Hi Mike, Hope you are well.. :-) Any chance that I can bribe you at LSF next week to to take a look at this..?
Many thanks for your most valuable of time, --nab On Fri, 2009-03-27 at 02:02 -0700, Nicholas A. Bellinger wrote: > Greetings Mike, Hannes and co: > > Here is the OOPs that I am seeing with upstream Open-iSCSI on kernel.org > v2.6.27.10 with the TASK_ABORTED status getting returned to outstanding > struct scsi_cmnd from lio-core.2.6.git provided fabric. Here is the > code from drivers/scsi/iscsi_tcp.c:iscsi_tcp_task_init(): > > BUG_ON(__kfifo_len(tcp_task->r2tqueue)); > > Is this something that has been fixed in recent Open-iSCSI code..? Any > ideas..? > > Many thanks for your most valuable of time, > > --nab > > > > > > > email message attachment, "Forwarded message - [PATCH] > [Target_Core_Mod/Persistent_Reservations]: Add support for > PREEMPT_AND_ABORT SA" > > -------- Forwarded Message -------- > > From: Nicholas A. Bellinger <n...@linux-iscsi.org> > > To: linux-scsi <linux-s...@vger.kernel.org>, LKML > > <linux-ker...@vger.kernel.org> > > Cc: James Bottomley <james.bottom...@hansenpartnership.com>, Mike > > Christie <micha...@cs.wisc.edu>, FUJITA Tomonori > > <fujita.tomon...@lab.ntt.co.jp>, Hannes Reinecke <h...@suse.de>, > > Martin K. Petersen <martin.peter...@oracle.com>, Alan Stern > > <st...@rowland.harvard.edu>, Douglas Gilbert > > <dgilb...@interlog.com>, Alasdair G Kergon <a...@redhat.com>, Philipp > > Reisner <philipp.reis...@linbit.com>, Ming Zhang > > <blackmagic02...@gmail.com> > > Subject: [PATCH] [Target_Core_Mod/Persistent_Reservations]: Add > > support for PREEMPT_AND_ABORT SA > > Date: Fri, 27 Mar 2009 01:46:36 -0700 > > > > Greetings all, > > > > This patch adds support for the PROUT PREEMPT_AND_ABORT service action to > > core_scsi3_emulate_pro_preempt() and core_tmr_lun_reset() using existing TAS > > (TASK_ABORTED status) emulation. The logic assigns the initiator port > > provided pre-registered reservation key to allocated SCSI Task and Task > > Management > > through logical unit ACLs in target_core_mod code. > > > > This patch uses struct list_head preempt_and_abort_list inside of > > core_scsi3_emulate_pro_preempt() to track PR registrations/reservation > > data structure t10_pr_registration_t once it has been removed from the > > se_device_t list, and before they get released back into struct kmem_cache > > t10_pr_reg_cache in core_scsi3_release_preempt_and_abort(). > > > > These patches are made against lio-core-2.6.git/master and tested on > > v2.6.29 x86 32-bit HVM using sg_persist and sg_request from sg3_utils. > > The lio-core-2.6.git tree can be found at: > > > > http://git.kernel.org/?p=linux/kernel/git/nab/lio-core-2.6.git;a=summary > > > > So far, I have been primarily testing the following scenario, which is what > > linux-cluster userspace in RHEL/CentOS (and everyone else) does with > > fence_scsi > > today for their WRITE Exclusive, Registrants Only persistent > > reservation setup. Here is test setup I am using: > > > > # The same /sys/kernel/config/target/core/$HBA/$DEV Linux LVM object mapped > > across > > # two different LIO-Target iSCSI target ports > > initiator# lsscsi --transport > > [3:0:0:0] disk > > iqn.2003-01.org.linux-iscsi.target.i686:sn.cff3eedbd2fd,t,0x1 /dev/sde > > [4:0:0:0] disk > > iqn.2003-01.org.linux-iscsi.target.i686:sn.e475ed6fcdd0,t,0x1 /dev/sdf > > > > *) Initiator side using Open/iSCSI: > > > > [ 185.682972] scsi3 : iSCSI Initiator over TCP/IP > > [ 185.998817] scsi 3:0:0:0: Direct-Access LIO-ORG IBLOCK > > 3.0 PQ: 0 ANSI: 5 > > [ 186.009172] sd 3:0:0:0: [sde] 128000 4096-byte hardware sectors (524 MB) > > [ 186.013274] sd 3:0:0:0: [sde] Write Protect is off > > [ 186.013286] sd 3:0:0:0: [sde] Mode Sense: 2f 00 00 00 > > [ 186.034372] sd 3:0:0:0: [sde] Write cache: disabled, read cache: > > enabled, doesn't support DPO or FUA > > [ 186.045854] sd 3:0:0:0: [sde] 128000 4096-byte hardware sectors (524 MB) > > [ 186.054955] sd 3:0:0:0: [sde] Write Protect is off > > [ 186.054967] sd 3:0:0:0: [sde] Mode Sense: 2f 00 00 00 > > [ 186.072648] sd 3:0:0:0: [sde] Write cache: disabled, read cache: > > enabled, doesn't support DPO or FUA > > [ 186.073401] sde: unknown partition table > > [ 186.084108] sd 3:0:0:0: [sde] Attached SCSI disk > > [ 186.085052] sd 3:0:0:0: Attached scsi generic sg4 type 0 > > [ 186.316470] alua: device handler registered > > [ 186.321957] sd 3:0:0:0: alua: supports implicit TPGS > > [ 186.326881] sd 3:0:0:0: alua: port group 00 rel port 02 > > [ 186.331445] sd 3:0:0:0: alua: port group 00 state A supports tousNA > > [ 186.372696] sd 3:0:0:0: alua: port group 00 state A supports tousNA > > [ 188.204172] scsi4 : iSCSI Initiator over TCP/IP > > [ 188.481410] scsi 4:0:0:0: Direct-Access LIO-ORG IBLOCK > > 3.0 PQ: 0 ANSI: 5 > > [ 188.489828] sd 4:0:0:0: [sdf] 128000 4096-byte hardware sectors (524 MB) > > [ 188.497081] sd 4:0:0:0: [sdf] Write Protect is off > > [ 188.497093] sd 4:0:0:0: [sdf] Mode Sense: 2f 00 00 00 > > [ 188.512344] sd 4:0:0:0: [sdf] Write cache: disabled, read cache: > > enabled, doesn't support DPO or FUA > > [ 188.525858] sd 4:0:0:0: [sdf] 128000 4096-byte hardware sectors (524 MB) > > [ 188.534314] sd 4:0:0:0: [sdf] Write Protect is off > > [ 188.534325] sd 4:0:0:0: [sdf] Mode Sense: 2f 00 00 00 > > [ 188.550966] sd 4:0:0:0: [sdf] Write cache: disabled, read cache: > > enabled, doesn't support DPO or FUA > > [ 188.557596] sdf: unknown partition table > > > > # Register both ports > > initiator# sg_persist --out --register --param-sark=0x1234abcd -Y -v > > /dev/sde > > initiator# sg_persist --out --register --param-sark=0x4567ffff -Y -v > > /dev/sdf > > # Create a write exclusive, registrants only persistent reservation > > initiator# sg_persist --out --reserve --param-rk=0x1234abcd --prout-type=5 > > -v /dev/sde > > > > ... Start running READ/WRITE I/O to /dev/sde ... > > > > # Preempt the reservation on /dev/sdf using /dev/sde's reservation key.. > > initiator# sg_persist --out --preempt-abort --param-rk=0x4567ffff > > --param-sark=0x1234abcd --prout-type 5 -v /dev/sdf > > > > [ 199.570148] sd 3:0:0:0: reservation conflict > > [ 205.461349] sd 3:0:0:0: reservation conflict > > [ 205.462076] sd 3:0:0:0: [sde] Result: hostbyte=DID_OK > > driverbyte=DRIVER_OK,SUGGEST_OK > > [ 205.462228] end_request: I/O error, dev sde, sector 384 > > [ 205.480997] sd 3:0:0:0: reservation conflict > > [ 205.481013] sd 3:0:0:0: [sde] Result: hostbyte=DID_OK > > driverbyte=DRIVER_OK,SUGGEST_OK > > > > # Re-Register on the port that has been preempted > > initiator# sg_persist --out --register --param-sark=0x1234abcd -Y -v > > /dev/sde > > > > ... Start running READ/WRITE I/O to /dev/sdf .. > > > > # Preempt the reservation on /dev/sde using /dev/sdf's reservation key.. > > initiator# sg_persist --out --preempt-abort --param-rk=0x1234abcd > > --param-sark=0x4567ffff --prout-type 5 -v /dev/sde > > > > [ 269.379004] sd 4:0:0:0: reservation conflict > > [ 269.379021] sd 4:0:0:0: [sdf] Result: hostbyte=DID_OK > > driverbyte=DRIVER_OK,SUGGEST_OK > > [ 269.379030] end_request: I/O error, dev sdf, sector 1280 > > [ 269.414193] sd 4:0:0:0: reservation conflict > > [ 269.414210] sd 4:0:0:0: [sdf] Result: hostbyte=DID_OK > > driverbyte=DRIVER_OK,SUGGEST_OK > > [ 269.414219] end_request: I/O error, dev sdf, sector 1024 > > > > and so on.. > > > > So far, things are looking good on the lio-core-2.6.git side, however I am > > able to trigger a BUG() from > > time to time in Open/iSCSI Initiator when returning > > include/scsi/scsi.h:SAM_STAT_TASK_ABORTED when TAS=1 in > > target_core_mod/ConfigFS, but other than that things are looking good with > > small amounts of outstanding CDBs > > being preempted and aborted. Sometimes the Open/iSCSI client side does a > > bus reset (restart the iSCSI session) > > instead of processing TASK_ABORTED status (which appear to be getting sent > > from target_core_mod), not sure if > > this is related to the BUG() that is triggered or not (will CC Open-iSCSI > > list). > > > > *) Target side using lio-core-2.6.git on v2.6.29: > > > > <SNIP> > > > > SPC-3 PR [iSCSI] Service Action: REGISTER Initiator Node: > > iqn.1993-08.org.debian:01:2dadf92d0ef > > SPC-3 PR [iSCSI] for ALL TCM Subsystem iblock Object Target Port(s) > > SPC-3 PR [iSCSI] SA Res Key: 0x000000001234abcd PRgeneration: 0x00000013 > > SPC-3 PR [iSCSI] Service Action: implict RELEASE cleared reservation holder > > TYPE: Write Exclusive Access, Registrants Only ALL_TG_PT: 1 > > SPC-3 PR [iSCSI] RELEASE Node: iqn.1993-08.org.debian:01:2dadf92d0ef > > SPC-3 PR [iSCSI] Service Action: UNREGISTER Initiator Node: > > iqn.1993-08.org.debian:01:2dadf92d0ef > > SPC-3 PR [iSCSI] for ALL TCM Subsystem iblock Object Target Port(s) > > SPC-3 PR [iSCSI] SA Res Key: 0x000000004567ffff PRgeneration: 0x00000011 > > [iSCSI]: Allocated UNIT ATTENTION, mapped LUN: 0, ASC: 0x2a, ASCQ: 0x03 > > SPC-3 PR [iSCSI] Service Action: PREEMPT_AND_ABORT created new reservation > > holder TYPE: Write Exclusive Access, Registrants Only ALL_TG_PT: 1 > > SPC-3 PR [iSCSI] PREEMPT_AND_ABORT from Node: > > iqn.1993-08.org.debian:01:2dadf92d0ef > > LUN_RESET: Preempt starting for [iblock], tas: 1 > > LUN_RESET: Preempt cmd: d3b5a300 task: d3193200 ITT/CmdSN: > > 0x2b000010/0x00000000, i_state: 1, t_state/def_t_state: 243/0 cdb: 0x2a > > LUN_RESET: ITT[0x2b000010] - pr_res_key: 0x000000004567ffff t_task_cdbs: 1 > > t_task_cdbs_left: 1 t_task_cdbs_sent: 0 -- t_transport_active: 0 > > t_transport_stop: 0 t_transport_sent: 0 > > LUN_RESET: Got t_transport_active = 0 for task: d3193200, t_fe_count: 1 > > dev: dec3f000 > > LUN_RESET: Preempt for [iblock] Complete > > [iSCSI]: Releasing UNIT ATTENTION condition with INTLCK_CTRL: 0, mapped > > LUN: 0, got CDB: 0x2a reported ASC: 0x2a, ASCQ: 0x03 > > Conflict for WRITE CDB: 0x2a to Write Exclusive Access, Registrants Only > > reservation > > Conflict for WRITE CDB: 0x2a to Write Exclusive Access, Registrants Only > > reservation > > Conflict for WRITE CDB: 0x2a to Write Exclusive Access, Registrants Only > > reservation > > > > > > > > Signed-off-by: Nicholas A. Bellinger <n...@linux-iscsi.org> > > > > --- > > drivers/lio-core/target_core_base.h | 4 + > > drivers/lio-core/target_core_device.c | 2 + > > drivers/lio-core/target_core_pr.c | 201 > > +++++++++++++++++++++--------- > > drivers/lio-core/target_core_pr.h | 2 + > > drivers/lio-core/target_core_tmr.c | 164 +++++++++++++++++------- > > drivers/lio-core/target_core_tmr.h | 3 +- > > drivers/lio-core/target_core_transport.c | 8 +- > > 7 files changed, 270 insertions(+), 114 deletions(-) > > > > diff --git a/drivers/lio-core/target_core_base.h > > b/drivers/lio-core/target_core_base.h > > index 5849a1f..5935d9b 100644 > > --- a/drivers/lio-core/target_core_base.h > > +++ b/drivers/lio-core/target_core_base.h > > @@ -294,6 +294,7 @@ typedef struct t10_pr_registration_s { > > struct se_dev_entry_s *pr_reg_deve; > > struct se_lun_s *pr_reg_tg_pt_lun; > > struct list_head pr_reg_list; > > + struct list_head pr_reg_abort_list; > > } t10_pr_registration_t; > > > > typedef struct t10_reservation_template_s { > > @@ -472,6 +473,8 @@ typedef struct se_cmd_s { > > u32 iov_data_count; > > /* Number of iovecs allocated for iscsi_cmd_t->iov_data */ > > u32 orig_iov_data_count; > > + /* Persistent Reservation key */ > > + u64 pr_res_key; > > atomic_t transport_sent; > > /* Used for sense data */ > > void *sense_buffer; > > @@ -604,6 +607,7 @@ typedef struct se_dev_entry_s { > > u32 last_byte_count; > > u32 total_cmds; > > u32 total_bytes; > > + u64 pr_res_key; > > #ifdef SNMP_SUPPORT > > u64 creation_time; > > u32 attach_count; > > diff --git a/drivers/lio-core/target_core_device.c > > b/drivers/lio-core/target_core_device.c > > index 95ab18d..a3db481 100644 > > --- a/drivers/lio-core/target_core_device.c > > +++ b/drivers/lio-core/target_core_device.c > > @@ -266,6 +266,7 @@ extern int __transport_get_lun_for_cmd( > > deve->deve_cmds++; > > > > se_lun = se_cmd->se_lun = deve->se_lun; > > + se_cmd->pr_res_key = deve->pr_res_key; > > se_cmd->orig_fe_lun = unpacked_lun; > > se_cmd->se_orig_obj_api = SE_LUN(se_cmd)->lun_obj_api; > > se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_type_ptr; > > @@ -346,6 +347,7 @@ extern int transport_get_lun_for_tmr( > > if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { > > se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun; > > dev = se_tmr->tmr_dev = se_lun->se_dev; > > + se_cmd->pr_res_key = deve->pr_res_key; > > se_cmd->orig_fe_lun = unpacked_lun; > > se_cmd->se_orig_obj_api = SE_LUN(se_cmd)->lun_obj_api; > > se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_type_ptr; > > diff --git a/drivers/lio-core/target_core_pr.c > > b/drivers/lio-core/target_core_pr.c > > index f55c59d..0f4772e 100644 > > --- a/drivers/lio-core/target_core_pr.c > > +++ b/drivers/lio-core/target_core_pr.c > > @@ -36,6 +36,7 @@ > > #include <target_core_base.h> > > #include <target_core_device.h> > > #include <target_core_hba.h> > > +#include <target_core_tmr.h> > > #include <target_core_transport.h> > > #include <target_core_pr.h> > > #include <target_core_ua.h> > > @@ -368,12 +369,14 @@ static int core_scsi3_pr_seq_non_holder( > > * as we expect registered non-reservation holding > > * nexuses to issue CDBs. > > */ > > +#if 0 > > if (!(registered_nexus)) { > > printk(KERN_INFO "Allowing implict CDB: 0x%02x" > > " for %s reservation on unregistered" > > " nexus\n", cdb[0], > > core_scsi3_pr_dump_type(pr_reg_type)); > > } > > +#endif > > return 0; > > } > > } else if (all_reg) { > > @@ -431,6 +434,7 @@ static int core_scsi3_pr_reservation_check( > > return 0; > > } > > *pr_reg_type = dev->dev_pr_res_holder->pr_res_type; > > + cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key; > > ret = (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) ? > > -1 : 0; > > spin_unlock(&dev->dev_reservation_lock); > > @@ -473,6 +477,7 @@ static int core_scsi3_alloc_registration( > > } > > > > INIT_LIST_HEAD(&pr_reg->pr_reg_list); > > + INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list); > > atomic_set(&pr_reg->pr_res_holders, 0); > > pr_reg->pr_reg_nacl = nacl; > > pr_reg->pr_reg_deve = deve; > > @@ -490,6 +495,7 @@ static int core_scsi3_alloc_registration( > > spin_lock(&pr_tmpl->registration_lock); > > list_add_tail(&pr_reg->pr_reg_list, &pr_tmpl->registration_list); > > deve->deve_flags |= DEF_PR_REGISTERED; > > + deve->pr_res_key = sa_res_key; > > > > printk(KERN_INFO "SPC-3 PR [%s] Service Action: REGISTER%s Initiator" > > " Node: %s\n", tfo->get_fabric_name(), (ignore_key) ? > > @@ -573,6 +579,7 @@ static int core_scsi3_check_implict_release( > > static void __core_scsi3_free_registration( > > se_device_t *dev, > > t10_pr_registration_t *pr_reg, > > + struct list_head *preempt_and_abort_list, > > int dec_holders) > > { > > struct target_core_fabric_ops *tfo = > > @@ -580,6 +587,7 @@ static void __core_scsi3_free_registration( > > t10_reservation_template_t *pr_tmpl = &SU_DEV(dev)->t10_reservation; > > > > pr_reg->pr_reg_deve->deve_flags &= ~DEF_PR_REGISTERED; > > + pr_reg->pr_reg_deve->pr_res_key = 0; > > list_del(&pr_reg->pr_reg_list); > > /* > > * Caller accessing *pr_reg using core_scsi3_locate_pr_reg(), > > @@ -612,9 +620,17 @@ static void __core_scsi3_free_registration( > > " 0x%08x\n", tfo->get_fabric_name(), pr_reg->pr_res_key, > > pr_reg->pr_res_generation); > > > > - pr_reg->pr_reg_deve = NULL; > > - pr_reg->pr_reg_nacl = NULL; > > - kmem_cache_free(t10_pr_reg_cache, pr_reg); > > + if (!(preempt_and_abort_list)) { > > + pr_reg->pr_reg_deve = NULL; > > + pr_reg->pr_reg_nacl = NULL; > > + kmem_cache_free(t10_pr_reg_cache, pr_reg); > > + return; > > + } > > + /* > > + * For PREEMPT_AND_ABORT, the list of *pr_reg in preempt_and_abort_list > > + * are released once the ABORT_TASK_SET has completed.. > > + */ > > + list_add_tail(&pr_reg->pr_reg_abort_list, preempt_and_abort_list); > > } > > > > void core_scsi3_free_pr_reg_from_nacl( > > @@ -643,7 +659,7 @@ void core_scsi3_free_pr_reg_from_nacl( > > if (pr_reg->pr_reg_nacl != nacl) > > continue; > > > > - __core_scsi3_free_registration(dev, pr_reg, 0); > > + __core_scsi3_free_registration(dev, pr_reg, NULL, 0); > > } > > spin_unlock(&pr_tmpl->registration_lock); > > } > > @@ -667,7 +683,7 @@ void core_scsi3_free_all_registrations( > > list_for_each_entry_safe(pr_reg, pr_reg_tmp, > > &pr_tmpl->registration_list, pr_reg_list) { > > > > - __core_scsi3_free_registration(dev, pr_reg, 0); > > + __core_scsi3_free_registration(dev, pr_reg, NULL, 0); > > } > > spin_unlock(&pr_tmpl->registration_lock); > > } > > @@ -785,7 +801,8 @@ static int core_scsi3_emulate_pro_register( > > /* > > * Release the calling I_T Nexus registration now.. > > */ > > - __core_scsi3_free_registration(SE_DEV(cmd), pr_reg, 1); > > + __core_scsi3_free_registration(SE_DEV(cmd), pr_reg, > > + NULL, 1); > > /* > > * From spc4r17, section 5.7.11.3 Unregistering > > * > > @@ -1285,7 +1302,8 @@ static int core_scsi3_emulate_pro_clear( > > calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; > > pr_reg_nacl = pr_reg->pr_reg_nacl; > > pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; > > - __core_scsi3_free_registration(dev, pr_reg, calling_it_nexus); > > + __core_scsi3_free_registration(dev, pr_reg, NULL, > > + calling_it_nexus); > > /* > > * e) Establish a unit attention condition for the initiator > > * port associated with every registered I_T nexus other > > @@ -1312,8 +1330,10 @@ static int core_scsi3_emulate_pro_clear( > > static void __core_scsi3_complete_pro_preempt( > > se_device_t *dev, > > t10_pr_registration_t *pr_reg, > > + struct list_head *preempt_and_abort_list, > > int type, > > - int scope) > > + int scope, > > + int abort) > > { > > se_node_acl_t *nacl = pr_reg->pr_reg_nacl; > > struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; > > @@ -1329,12 +1349,60 @@ static void __core_scsi3_complete_pro_preempt( > > pr_reg->pr_res_type = type; > > pr_reg->pr_res_scope = scope; > > > > - printk(KERN_INFO "SPC-3 PR [%s] Service Action: PREEMPT created new" > > + printk(KERN_INFO "SPC-3 PR [%s] Service Action: PREEMPT%s created new" > > " reservation holder TYPE: %s ALL_TG_PT: %d\n", > > - tfo->get_fabric_name(), core_scsi3_pr_dump_type(type), > > + tfo->get_fabric_name(), (abort) ? "_AND_ABORT" : "", > > + core_scsi3_pr_dump_type(type), > > (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); > > - printk(KERN_INFO "SPC-3 PR [%s] PREEMPT from Node: %s\n", > > - tfo->get_fabric_name(), nacl->initiatorname); > > + printk(KERN_INFO "SPC-3 PR [%s] PREEMPT%s from Node: %s\n", > > + tfo->get_fabric_name(), (abort) ? "_AND_ABORT" : "", > > + nacl->initiatorname); > > + /* > > + * For PREEMPT_AND_ABORT, add the preempting reservation's > > + * t10_pr_registration_t to the list that will be compared > > + * against received CDBs.. > > + */ > > + if (preempt_and_abort_list) > > + list_add_tail(&pr_reg->pr_reg_abort_list, > > + preempt_and_abort_list); > > +} > > + > > +static void core_scsi3_release_preempt_and_abort( > > + struct list_head *preempt_and_abort_list, > > + t10_pr_registration_t *pr_reg_holder) > > +{ > > + t10_pr_registration_t *pr_reg, *pr_reg_tmp; > > + > > + list_for_each_entry_safe(pr_reg, pr_reg_tmp, preempt_and_abort_list, > > + pr_reg_abort_list) { > > + > > + list_del(&pr_reg->pr_reg_abort_list); > > + if (pr_reg_holder == pr_reg) > > + continue; > > + if (pr_reg->pr_res_holder) { > > + printk(KERN_WARNING "pr_reg->pr_res_holder still > > set\n"); > > + continue; > > + } > > + > > + pr_reg->pr_reg_deve = NULL; > > + pr_reg->pr_reg_nacl = NULL; > > + kmem_cache_free(t10_pr_reg_cache, pr_reg); > > + } > > +} > > + > > +int core_scsi3_check_cdb_abort_and_preempt( > > + struct list_head *preempt_and_abort_list, > > + se_cmd_t *cmd) > > +{ > > + t10_pr_registration_t *pr_reg, *pr_reg_tmp; > > + > > + list_for_each_entry_safe(pr_reg, pr_reg_tmp, preempt_and_abort_list, > > + pr_reg_abort_list) { > > + if (pr_reg->pr_res_key == cmd->pr_res_key) > > + return 0; > > + } > > + > > + return 1; > > } > > > > static int core_scsi3_emulate_pro_preempt( > > @@ -1342,13 +1410,15 @@ static int core_scsi3_emulate_pro_preempt( > > int type, > > int scope, > > u64 res_key, > > - u64 sa_res_key) > > + u64 sa_res_key, > > + int abort) > > { > > se_device_t *dev = SE_DEV(cmd); > > se_dev_entry_t *se_deve; > > se_lun_t *se_lun = SE_LUN(cmd); > > se_node_acl_t *pr_reg_nacl; > > se_session_t *se_sess = SE_SESS(cmd); > > + struct list_head preempt_and_abort_list; > > t10_pr_registration_t *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; > > t10_reservation_template_t *pr_tmpl = &SU_DEV(dev)->t10_reservation; > > u32 pr_res_mapped_lun = 0; > > @@ -1365,7 +1435,8 @@ static int core_scsi3_emulate_pro_preempt( > > pr_reg_n = core_scsi3_locate_pr_reg(SE_DEV(cmd), se_sess->se_node_acl); > > if (!(pr_reg_n)) { > > printk(KERN_ERR "SPC-3 PR: Unable to locate" > > - " PR_REGISTERED *pr_reg for PREEMPT\n"); > > + " PR_REGISTERED *pr_reg for PREEMPT%s\n", > > + (abort) ? "_AND_ABORT" : ""); > > return PYX_TRANSPORT_RESERVATION_CONFLICT; > > } > > if (pr_reg_n->pr_res_key != res_key) { > > @@ -1377,6 +1448,7 @@ static int core_scsi3_emulate_pro_preempt( > > core_scsi3_put_pr_reg(pr_reg_n); > > return PYX_TRANSPORT_INVALID_PARAMETER_LIST; > > } > > + INIT_LIST_HEAD(&preempt_and_abort_list); > > > > spin_lock(&dev->dev_reservation_lock); > > pr_res_holder = dev->dev_pr_res_holder; > > @@ -1434,7 +1506,8 @@ static int core_scsi3_emulate_pro_preempt( > > pr_reg_nacl = pr_reg->pr_reg_nacl; > > pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; > > __core_scsi3_free_registration(dev, pr_reg, > > - calling_it_nexus); > > + (abort) ? &preempt_and_abort_list : > > + NULL, calling_it_nexus); > > released_regs++; > > } else { > > /* > > @@ -1460,7 +1533,9 @@ static int core_scsi3_emulate_pro_preempt( > > > > pr_reg_nacl = pr_reg->pr_reg_nacl; > > pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; > > - __core_scsi3_free_registration(dev, pr_reg, 0); > > + __core_scsi3_free_registration(dev, pr_reg, > > + (abort) ? &preempt_and_abort_list : > > + NULL, 0); > > released_regs++; > > } > > if (!(calling_it_nexus)) > > @@ -1486,9 +1561,15 @@ static int core_scsi3_emulate_pro_preempt( > > * with a zero SA rservation key, preempt the existing > > * reservation with the new PR type and scope. > > */ > > - if (pr_res_holder && all_reg && !(sa_res_key)) > > + if (pr_res_holder && all_reg && !(sa_res_key)) { > > __core_scsi3_complete_pro_preempt(dev, pr_reg_n, > > - type, scope); > > + (abort) ? &preempt_and_abort_list : NULL, > > + type, scope, abort); > > + > > + if (abort) > > + core_scsi3_release_preempt_and_abort( > > + &preempt_and_abort_list, pr_reg_n); > > + } > > spin_unlock(&dev->dev_reservation_lock); > > > > core_scsi3_put_pr_reg(pr_reg_n); > > @@ -1499,32 +1580,21 @@ static int core_scsi3_emulate_pro_preempt( > > * The PREEMPTing SA reservation key matches that of the > > * existing persistent reservation, first, we check if > > * we are preempting our own reservation. > > + * From spc4r17, section 5.7.11.4.3 Preempting > > + * persistent reservations and registration handling > > + * > > + * If an all registrants persistent reservation is not > > + * present, it is not an error for the persistent > > + * reservation holder to preempt itself (i.e., a > > + * PERSISTENT RESERVE OUT with a PREEMPT service action > > + * or a PREEMPT AND ABORT service action with the > > + * SERVICE ACTION RESERVATION KEY value equal to the > > + * persistent reservation holder's reservation key that > > + * is received from the persistent reservation holder). > > + * In that case, the device server shall establish the > > + * new persistent reservation and maintain the > > + * registration. > > */ > > - if (pr_reg_n == pr_res_holder) { > > - /* > > - * From spc4r17, section 5.7.11.4.3 Preempting > > - * persistent reservations and registration handling > > - * > > - * If an all registrants persistent reservation is not > > - * present, it is not an error for the persistent > > - * reservation holder to preempt itself (i.e., a > > - * PERSISTENT RESERVE OUT with a PREEMPT service action > > - * or a PREEMPT AND ABORT service action with the > > - * SERVICE ACTION RESERVATION KEY value equal to the > > - * persistent reservation holder's reservation key that > > - * is received from the persistent reservation holder). > > - * In that case, the device server shall establish the > > - * new persistent reservation and maintain the > > - * registration. > > - */ > > - __core_scsi3_complete_pro_preempt(dev, pr_reg_n, > > - type, scope); > > - spin_unlock(&dev->dev_reservation_lock); > > - > > - core_scsi3_put_pr_reg(pr_reg_n); > > - core_scsi3_pr_generation(SE_DEV(cmd)); > > - return 0; > > - } > > prh_type = pr_res_holder->pr_res_type; > > prh_scope = pr_res_holder->pr_res_scope; > > /* > > @@ -1536,7 +1606,9 @@ static int core_scsi3_emulate_pro_preempt( > > * a) Release the persistent reservation for the holder > > * identified by the SERVICE ACTION RESERVATION KEY field; > > */ > > - __core_scsi3_complete_pro_release(dev, pr_res_holder->pr_reg_nacl, > > + if (pr_reg_n != pr_res_holder) > > + __core_scsi3_complete_pro_release(dev, > > + pr_res_holder->pr_reg_nacl, > > dev->dev_pr_res_holder, 0); > > /* > > * b) Remove the registrations for all I_T nexuses identified > > @@ -1562,6 +1634,7 @@ static int core_scsi3_emulate_pro_preempt( > > pr_reg_nacl = pr_reg->pr_reg_nacl; > > pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; > > __core_scsi3_free_registration(dev, pr_reg, > > + (abort) ? &preempt_and_abort_list : NULL, > > calling_it_nexus); > > /* > > * e) Establish a unit attention condition for the initiator > > @@ -1577,7 +1650,9 @@ static int core_scsi3_emulate_pro_preempt( > > * c) Establish a persistent reservation for the preempting > > * I_T nexus using the contents of the SCOPE and TYPE fields; > > */ > > - __core_scsi3_complete_pro_preempt(dev, pr_reg_n, type, scope); > > + __core_scsi3_complete_pro_preempt(dev, pr_reg_n, > > + (abort) ? &preempt_and_abort_list : NULL, > > + type, scope, abort); > > /* > > * d) Process tasks as defined in 5.7.1; > > * e) See above.. > > @@ -1594,7 +1669,7 @@ static int core_scsi3_emulate_pro_preempt( > > if ((prh_type != type) || (prh_scope != scope)) { > > spin_lock(&pr_tmpl->registration_lock); > > list_for_each_entry_safe(pr_reg, pr_reg_tmp, > > - &pr_tmpl->registration_list, pr_reg_list) { > > + &pr_tmpl->registration_list, pr_reg_list) { > > > > calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0; > > if (calling_it_nexus) > > @@ -1607,23 +1682,27 @@ static int core_scsi3_emulate_pro_preempt( > > spin_unlock(&pr_tmpl->registration_lock); > > } > > spin_unlock(&dev->dev_reservation_lock); > > + /* > > + * Call LUN_RESET logic upon list of t10_pr_registration_t, > > + * All received CDBs for the matching existing reservation and > > + * registrations undergo ABORT_TASK logic. > > + * > > + * From there, core_scsi3_release_preempt_and_abort() will > > + * release every registration in the list (which have already > > + * been removed from the primary pr_reg list), except the > > + * new persistent reservation holder, the calling Initiator Port. > > + */ > > + if (abort) { > > + core_tmr_lun_reset(dev, NULL, &preempt_and_abort_list, cmd); > > + core_scsi3_release_preempt_and_abort(&preempt_and_abort_list, > > + pr_reg_n); > > + } > > > > core_scsi3_put_pr_reg(pr_reg_n); > > core_scsi3_pr_generation(SE_DEV(cmd)); > > return 0; > > } > > > > -static int core_scsi3_emulate_pro_preempt_and_abort( > > - se_cmd_t *cmd, > > - int type, > > - int scope, > > - u64 res_key, > > - u64 sa_res_key) > > -{ > > - core_scsi3_pr_generation(SE_DEV(cmd)); > > - return 0; > > -} > > - > > static int core_scsi3_emulate_pro_register_and_move( > > se_cmd_t *cmd, > > int type, > > @@ -1699,12 +1778,10 @@ static int core_scsi3_emulate_pr_out(se_cmd_t *cmd, > > unsigned char *cdb) > > return core_scsi3_emulate_pro_clear(cmd, res_key); > > case PRO_PREEMPT: > > return core_scsi3_emulate_pro_preempt(cmd, type, scope, > > - res_key, sa_res_key); > > -#if 0 > > + res_key, sa_res_key, 0); > > case PRO_PREEMPT_AND_ABORT: > > - return core_scsi3_emulate_pro_preempt_and_abort(cmd, > > - type, scope, res_key, sa_res_key); > > -#endif > > + return core_scsi3_emulate_pro_preempt(cmd, type, scope, > > + res_key, sa_res_key, 1); > > case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: > > return core_scsi3_emulate_pro_register(cmd, > > 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1); > > diff --git a/drivers/lio-core/target_core_pr.h > > b/drivers/lio-core/target_core_pr.h > > index 9003ebb..23d9e18 100644 > > --- a/drivers/lio-core/target_core_pr.h > > +++ b/drivers/lio-core/target_core_pr.h > > @@ -46,6 +46,8 @@ extern void core_scsi3_free_pr_reg_from_nacl(struct > > se_device_s *, > > struct se_node_acl_s *); > > extern void core_scsi3_free_all_registrations(struct se_device_s *); > > extern unsigned char *core_scsi3_pr_dump_type(int); > > +extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *, > > + struct se_cmd_s *); > > extern int core_scsi3_emulate_pr(struct se_cmd_s *); > > extern int core_setup_reservations(struct se_device_s *); > > > > diff --git a/drivers/lio-core/target_core_tmr.c > > b/drivers/lio-core/target_core_tmr.c > > index 531b135..577dc6a 100644 > > --- a/drivers/lio-core/target_core_tmr.c > > +++ b/drivers/lio-core/target_core_tmr.c > > @@ -29,12 +29,14 @@ > > #include <linux/version.h> > > #include <linux/slab.h> > > #include <linux/spinlock.h> > > +#include <linux/list.h> > > #include <scsi/scsi.h> > > #include <scsi/scsi_cmnd.h> > > > > #include <target_core_base.h> > > #include <target_core_device.h> > > #include <target_core_hba.h> > > +#include <target_core_pr.h> > > #include <target_core_seobj.h> > > #include <target_core_tmr.h> > > #include <target_core_transport.h> > > @@ -93,16 +95,21 @@ void core_tmr_release_req( > > spin_unlock(&dev->se_tmr_lock); > > } > > > > -int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t *tmr) > > +int core_tmr_lun_reset( > > + se_device_t *dev, > > + se_tmr_req_t *tmr, > > + struct list_head *preempt_and_abort_list, > > + se_cmd_t *prout_cmd) > > { > > se_cmd_t *cmd; > > - se_queue_req_t *qr; > > + se_queue_req_t *qr, *qr_tmp; > > se_node_acl_t *tmr_nacl = NULL; > > se_portal_group_t *tmr_tpg = NULL; > > + se_queue_obj_t *qobj = dev->dev_queue_obj; > > se_tmr_req_t *tmr_p, *tmr_pp; > > - se_task_t *task; > > + se_task_t *task, *task_tmp; > > unsigned long flags; > > - int state, tas; > > + int fe_count, state, tas; > > /* > > * TASK_ABORTED status bit, this is configurable via ConfigFS > > * se_device_t attributes. spc4r17 section 7.4.6 Control mode page > > @@ -119,7 +126,7 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > * Determine if this se_tmr is coming from a $FABRIC_MOD > > * or se_device_t passthrough.. > > */ > > - if (tmr->task_cmd && tmr->task_cmd->se_sess) { > > + if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) { > > tmr_nacl = tmr->task_cmd->se_sess->se_node_acl; > > tmr_tpg = tmr->task_cmd->se_sess->se_tpg; > > if (tmr_nacl && tmr_tpg) { > > @@ -129,8 +136,9 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > tmr_nacl->initiatorname); > > } > > } > > - DEBUG_LR("LUN_RESET: TMR: %p starting for [%s], tas: %d\n", tmr, > > - TRANSPORT(dev)->name, tas); > > + DEBUG_LR("LUN_RESET: %s starting for [%s], tas: %d\n", > > + (preempt_and_abort_list) ? "Preempt" : "TMR", > > + TRANSPORT(dev)->name, tas); > > /* > > * Release all pending and outgoing TMRs aside from the received > > * LUN_RESET tmr.. > > @@ -148,10 +156,20 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > printk(KERN_ERR "Unable to locate se_cmd_t for TMR\n"); > > continue; > > } > > + /* > > + * If this function was called with a valid pr_res_key > > + * parameter (eg: for PROUT PREEMPT_AND_ABORT service action > > + * skip non regisration key matching TMRs. > > + */ > > + if ((preempt_and_abort_list != NULL) && > > + (core_scsi3_check_cdb_abort_and_preempt( > > + preempt_and_abort_list, cmd) != 0)) > > + continue; > > spin_unlock(&dev->se_tmr_lock); > > > > - DEBUG_LR("LUN_RESET: Releasing TMR %p Function: 0x%02x," > > - " Response: 0x%02x, t_state: %d\n", tmr_p, > > + DEBUG_LR("LUN_RESET: %s releasing TMR %p Function: 0x%02x," > > + " Response: 0x%02x, t_state: %d\n", > > + (preempt_and_abort_list) ? "Preempt" : "", tmr_p, > > tmr_p->function, tmr_p->response, cmd->t_state); > > > > transport_cmd_finish_abort_tmr(cmd); > > @@ -180,7 +198,8 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > * in the Control Mode Page. > > */ > > spin_lock_irqsave(&dev->execute_task_lock, flags); > > - while ((task = transport_get_task_from_state_list(dev))) { > > + list_for_each_entry_safe(task, task_tmp, &dev->state_task_list, > > + t_state_list) { > > if (!(TASK_CMD(task))) { > > printk(KERN_ERR "TASK_CMD(task) is NULL!\n"); > > continue; > > @@ -193,19 +212,36 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > CMD_TFO(cmd)->get_task_tag(cmd)); > > continue; > > } > > + /* > > + * For PREEMPT_AND_ABORT usage, only process commands > > + * with a matching reservation key. > > + */ > > + if ((preempt_and_abort_list != NULL) && > > + (core_scsi3_check_cdb_abort_and_preempt( > > + preempt_and_abort_list, cmd) != 0)) > > + continue; > > + /* > > + * Not aborting PROUT PREEMPT_AND_ABORT CDB.. > > + */ > > + if (prout_cmd == cmd) > > + continue; > > + > > + list_del(&task->t_state_list); > > + atomic_set(&task->task_state_active, 0); > > spin_unlock_irqrestore(&dev->execute_task_lock, flags); > > > > spin_lock_irqsave(&T_TASK(cmd)->t_state_lock, flags); > > - DEBUG_LR("LUN_RESET: cmd: %p task: %p ITT/CmdSN: 0x%08x/0x%08x" > > - ", i_state: %d, t_state/def_t_state: %d/%d cdb:" > > - " 0x%02x\n", cmd, task, CMD_TFO(cmd)->get_task_tag(cmd), > > + DEBUG_LR("LUN_RESET: %s cmd: %p task: %p ITT/CmdSN: 0x%08x/" > > + "0x%08x, i_state: %d, t_state/def_t_state: %d/%d cdb:" > > + " 0x%02x\n", (preempt_and_abort_list) ? "Preempt" : "", > > + cmd, task, CMD_TFO(cmd)->get_task_tag(cmd), > > 0, CMD_TFO(cmd)->get_cmd_state(cmd), cmd->t_state, > > cmd->deferred_t_state, T_TASK(cmd)->t_task_cdb[0]); > > - DEBUG_LR("LUN_RESET: ITT[0x%08x] - t_task_cdbs: %d" > > - " t_task_cdbs_left: %d t_task_cdbs_sent: %d --" > > - " t_transport_active: %d t_transport_stop: %d" > > - " t_transport_sent: %d\n", > > - CMD_TFO(cmd)->get_task_tag(cmd), > > + DEBUG_LR("LUN_RESET: ITT[0x%08x] - pr_res_key: 0x%016Lx" > > + " t_task_cdbs: %d t_task_cdbs_left: %d" > > + " t_task_cdbs_sent: %d -- t_transport_active: %d" > > + " t_transport_stop: %d t_transport_sent: %d\n", > > + CMD_TFO(cmd)->get_task_tag(cmd), cmd->pr_res_key, > > T_TASK(cmd)->t_task_cdbs, > > atomic_read(&T_TASK(cmd)->t_task_cdbs_left), > > atomic_read(&T_TASK(cmd)->t_task_cdbs_sent), > > @@ -241,49 +277,44 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > spin_lock_irqsave(&dev->execute_task_lock, flags); > > continue; > > } > > + fe_count = atomic_read(&T_TASK(cmd)->t_fe_count); > > > > if (atomic_read(&T_TASK(cmd)->t_transport_active)) { > > DEBUG_LR("LUN_RESET: got t_transport_active = 1 for" > > - " task: %p, dev: %p\n", task, dev); > > - > > - if (atomic_read(&T_TASK(cmd)->t_fe_count)) { > > - spin_unlock_irqrestore( > > - &T_TASK(cmd)->t_state_lock, flags); > > + " task: %p, t_fe_count: %d dev: %p\n", task, > > + fe_count, dev); > > + spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, > > + flags); > > + if (fe_count) { > > /* > > * TASK ABORTED status (TAS) bit support > > */ > > - if ((tmr_nacl == cmd->se_sess->se_node_acl) || > > + if (((tmr_nacl != NULL) && > > + (tmr_nacl == cmd->se_sess->se_node_acl)) || > > tas) > > transport_send_task_abort(cmd); > > transport_cmd_finish_abort(cmd, 0); > > - } else { > > - spin_unlock_irqrestore( > > - &T_TASK(cmd)->t_state_lock, flags); > > - > > + } else > > transport_cmd_finish_abort(cmd, 1); > > - } > > > > spin_lock_irqsave(&dev->execute_task_lock, flags); > > continue; > > } > > DEBUG_LR("LUN_RESET: Got t_transport_active = 0 for task: %p," > > - " dev: %p\n", task, dev); > > + " t_fe_count: %d dev: %p\n", task, fe_count, dev); > > + spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags); > > > > - if (atomic_read(&T_TASK(cmd)->t_fe_count)) { > > - spin_unlock_irqrestore( > > - &T_TASK(cmd)->t_state_lock, flags); > > + if (fe_count) { > > /* > > * TASK ABORTED status (TAS) bit support > > */ > > - if ((tmr_nacl == cmd->se_sess->se_node_acl) || tas) > > + if (((tmr_nacl != NULL) && > > + (tmr_nacl == cmd->se_sess->se_node_acl)) || tas) > > transport_send_task_abort(cmd); > > transport_cmd_finish_abort(cmd, 0); > > - } else { > > - spin_unlock_irqrestore( > > - &T_TASK(cmd)->t_state_lock, flags); > > - > > + } else > > transport_cmd_finish_abort(cmd, 1); > > - } > > + > > spin_lock_irqsave(&dev->execute_task_lock, flags); > > } > > spin_unlock_irqrestore(&dev->execute_task_lock, flags); > > @@ -295,35 +326,70 @@ int core_tmr_lun_reset(se_device_t *dev, se_tmr_req_t > > *tmr) > > * TASK_ABORTED status, if there is an outstanding $FABRIC_MOD > > * reference, otherwise the se_cmd_t is released. > > */ > > - spin_lock_irqsave(&dev->dev_queue_obj->cmd_queue_lock, flags); > > - while ((qr = __transport_get_qr_from_queue(dev->dev_queue_obj))) { > > - spin_unlock_irqrestore( > > - &dev->dev_queue_obj->cmd_queue_lock, flags); > > + spin_lock_irqsave(&qobj->cmd_queue_lock, flags); > > + list_for_each_entry_safe(qr, qr_tmp, &qobj->qobj_list, qr_list) { > > cmd = (se_cmd_t *)qr->cmd; > > + if (!(cmd)) { > > + /* > > + * Skip these for non PREEMPT_AND_ABORT usage.. > > + */ > > + if (preempt_and_abort_list != NULL) > > + continue; > > + > > + atomic_dec(&qobj->queue_cnt); > > + list_del(&qr->qr_list); > > + kfree(qr); > > + continue; > > + } > > + /* > > + * For PREEMPT_AND_ABORT usage, only process commands > > + * with a matching reservation key. > > + */ > > + if ((preempt_and_abort_list != NULL) && > > + (core_scsi3_check_cdb_abort_and_preempt( > > + preempt_and_abort_list, cmd) != 0)) > > + continue; > > + /* > > + * Not aborting PROUT PREEMPT_AND_ABORT CDB.. > > + */ > > + if (prout_cmd == cmd) > > + continue; > > + > > + atomic_dec(&T_TASK(cmd)->t_transport_queue_active); > > + atomic_dec(&qobj->queue_cnt); > > + list_del(&qr->qr_list); > > + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); > > + > > state = qr->state; > > kfree(qr); > > > > - DEBUG_LR("LUN_RESET: From Device Queue: cmd: %p t_state: %d\n", > > - cmd, state); > > + DEBUG_LR("LUN_RESET: %s from Device Queue: cmd: %p t_state:" > > + " %d t_fe_count: %d\n", (preempt_and_abort_list) ? > > + "Preempt" : "", cmd, state, > > + atomic_read(&T_TASK(cmd)->t_fe_count)); > > > > if (atomic_read(&T_TASK(cmd)->t_fe_count)) { > > /* > > * TASK ABORTED status (TAS) bit support > > */ > > - if ((tmr_nacl == cmd->se_sess->se_node_acl) || tas) > > + if (((tmr_nacl != NULL) && > > + (tmr_nacl == cmd->se_sess->se_node_acl)) || > > + tas) > > transport_send_task_abort(cmd); > > transport_cmd_finish_abort(cmd, 0); > > } else > > transport_cmd_finish_abort(cmd, 1); > > > > - spin_lock_irqsave(&dev->dev_queue_obj->cmd_queue_lock, flags); > > + spin_lock_irqsave(&qobj->cmd_queue_lock, flags); > > } > > - spin_unlock_irqrestore(&dev->dev_queue_obj->cmd_queue_lock, flags); > > + spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); > > > > spin_lock(&dev->stats_lock); > > dev->num_resets++; > > spin_unlock(&dev->stats_lock); > > > > - DEBUG_LR("LUN_RESET: TMR for [%s] Complete\n", TRANSPORT(dev)->name); > > + DEBUG_LR("LUN_RESET: %s for [%s] Complete\n", > > + (preempt_and_abort_list) ? "Preempt" : "TMR", > > + TRANSPORT(dev)->name); > > return 0; > > } > > diff --git a/drivers/lio-core/target_core_tmr.h > > b/drivers/lio-core/target_core_tmr.h > > index 3786f1b..c649b92 100644 > > --- a/drivers/lio-core/target_core_tmr.h > > +++ b/drivers/lio-core/target_core_tmr.h > > @@ -37,6 +37,7 @@ extern struct kmem_cache *se_tmr_req_cache; > > > > extern struct se_tmr_req_s *core_tmr_alloc_req(struct se_cmd_s *, void *, > > u8); > > extern void core_tmr_release_req(struct se_tmr_req_s *); > > -extern int core_tmr_lun_reset(struct se_device_s *, struct se_tmr_req_s *); > > +extern int core_tmr_lun_reset(struct se_device_s *, struct se_tmr_req_s *, > > + struct list_head *, struct se_cmd_s *); > > > > #endif /* TARGET_CORE_TMR_H */ > > diff --git a/drivers/lio-core/target_core_transport.c > > b/drivers/lio-core/target_core_transport.c > > index 4c4a489..4132da1 100644 > > --- a/drivers/lio-core/target_core_transport.c > > +++ b/drivers/lio-core/target_core_transport.c > > @@ -7357,7 +7357,11 @@ > > EXPORT_SYMBOL(transport_send_check_condition_and_sense); > > void transport_send_task_abort(se_cmd_t *cmd) > > { > > cmd->scsi_status = SAM_STAT_TASK_ABORTED; > > - > > +#if 0 > > + printk(KERN_INFO "Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x," > > + " ITT: 0x%08x\n", T_TASK(cmd)->t_task_cdb[0], > > + CMD_TFO(cmd)->get_task_tag(cmd)); > > +#endif > > if (!(cmd->se_cmd_flags & SCF_CMD_PASSTHROUGH)) > > CMD_TFO(cmd)->queue_status(cmd); > > } > > @@ -7384,7 +7388,7 @@ int transport_generic_do_tmr(se_cmd_t *cmd) > > tmr->response = TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED; > > break; > > case LUN_RESET: > > - ret = core_tmr_lun_reset(dev, tmr); > > + ret = core_tmr_lun_reset(dev, tmr, NULL, NULL); > > tmr->response = (!ret) ? TMR_FUNCTION_COMPLETE : > > TMR_FUNCTION_REJECTED; > > break; --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "open-iscsi" group. To post to this group, send email to open-iscsi@googlegroups.com To unsubscribe from this group, send email to open-iscsi+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/open-iscsi -~----------~----~----~----~------~----~------~--~---