--- kernel/Makefile | 2 - kernel/config.c | 1 kernel/iscsi.h | 7 ++++ kernel/proc_reservation.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/volume.c | 5 +++ 5 files changed, 80 insertions(+), 1 deletion(-) Index: iscsitarget/trunk/kernel/config.c =================================================================== --- iscsitarget.orig/trunk/kernel/config.c +++ iscsitarget/trunk/kernel/config.c @@ -19,6 +19,7 @@ static struct proc_entries iet_proc_entr {"volume", &volume_seq_fops}, {"session", &session_seq_fops}, {"vpd", &vpd_seq_fops}, + {"reservation", &reservation_seq_fops}, }; static struct proc_dir_entry *proc_iet_dir; Index: iscsitarget/trunk/kernel/proc_reservation.c =================================================================== --- /dev/null +++ iscsitarget/trunk/kernel/proc_reservation.c @@ -0,0 +1,64 @@ +/* + * Reservation proc interface + * Copyright (C) 2006 Steffen Plotner swplotner@amherst.edu + * Released under the terms of the GNU GPL v2.0. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +#include +#include + +char *none = "none"; + +char *sid_2_name(struct iscsi_target *target, u64 sid) +{ + struct iscsi_session *session; + + list_for_each_entry(session, &target->session_list, list) { + if (session->sid == sid) + return session->initiator; + } + return none; +} + +static void iet_reservation_show(struct seq_file *seq, struct iscsi_target *target) +{ + struct iet_volume *volume; + + list_for_each_entry(volume, &target->volumes, list) { + seq_printf(seq, "\tlun:%u", + volume->lun); + if (volume->iotype->show) + volume->iotype->show(volume, seq); + else + seq_printf(seq, "\n"); + + seq_printf(seq, "\t\treserve:%llu release:%llu " + "reserved:%llu reserved_by:%s\n", + volume->count_reserve, + volume->count_release, + volume->count_reserved, + sid_2_name(target, volume->reserve_sid)); + } +} + +static int iet_reservations_info_show(struct seq_file *seq, void *v) +{ + return iet_info_show(seq, iet_reservation_show); +} + +static int iet_reservation_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, iet_reservations_info_show, NULL); +} + +struct file_operations reservation_seq_fops = { + .owner = THIS_MODULE, + .open = iet_reservation_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; Index: iscsitarget/trunk/kernel/iscsi.h =================================================================== --- iscsitarget.orig/trunk/kernel/iscsi.h +++ iscsitarget/trunk/kernel/iscsi.h @@ -145,6 +145,10 @@ struct iet_volume { u64 reserve_sid; spinlock_t reserve_lock; + u64 count_reserve; + u64 count_release; + u64 count_reserved; + unsigned long flags; struct iotype *iotype; @@ -368,6 +372,9 @@ extern void event_exit(void); /* proc_vpd.c */ extern struct file_operations vpd_seq_fops; +/* proc_reservation.c */ +extern struct file_operations reservation_seq_fops; + #define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu) Index: iscsitarget/trunk/kernel/Makefile =================================================================== --- iscsitarget.orig/trunk/kernel/Makefile +++ iscsitarget/trunk/kernel/Makefile @@ -13,5 +13,5 @@ obj-m += iscsi_trgt.o iscsi_trgt-objs := tio.o iscsi.o nthread.o wthread.o config.o digest.o \ conn.o session.o target.o volume.o iotype.o \ file-io.o null-io.o target_disk.o event.o param.o \ - block-io.o proc_vpd.o + block-io.o proc_vpd.o proc_reservation.o Index: iscsitarget/trunk/kernel/volume.c =================================================================== --- iscsitarget.orig/trunk/kernel/volume.c +++ iscsitarget/trunk/kernel/volume.c @@ -202,6 +202,7 @@ int volume_reserve(struct iet_volume *vo } volume->reserve_sid = sid; + volume->count_reserve++; spin_unlock(&volume->reserve_lock); return 0; @@ -212,13 +213,17 @@ int is_volume_reserved(struct iet_volume if (!volume || !volume->reserve_sid || volume->reserve_sid == sid) return 0; + volume->count_reserved++; return -EBUSY; } int volume_release(struct iet_volume *volume, u64 sid, int force) { if (force || volume->reserve_sid == sid) + { volume->reserve_sid = 0; + volume->count_release++; + } return 0; }