[PATCH 2/2] [Target_Core_Mod/Persistent_Reservations]: Add PROUTCLEAR service action
From: Nicholas A. Bellinger
Date: Thu Mar 19 2009 - 04:57:35 EST
>From 158217e58f9be1384fb06c4e296392101c7434f5 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
Date: Thu, 19 Mar 2009 00:50:25 -0700
Subject: [PATCH 2/2] [Target_Core_Mod/Persistent_Reservations]: Add PROUT CLEAR service action
This patch adds support for the PROUT CLEAR service action, which releases
any associated reservation and all registrations, as long as the calling
I_T nexus has a registration valid Reservation Key.
Support for unit-attention + RESERVATIONS PREEMPTED is listed as a FIXME
in the code, and is a WIP.
Here is what it looks like in action with the same SCSI target device
across multiple iSCSI Target Portal Groups (eg: relivate target port 0x1 and 0x2)):
In the example, the I_T Nexus NOT holding the reservation (/dev/sde) is able to
successfully call PROUT CLEAR on the target port, this is the expected
behaviour as defined by spc4r17, section 5.7.11.6
initiator# sg_persist --out --register --param-sark=0x1234abcd -Y -v /dev/sdf
inquiry cdb: 12 00 00 00 24 00
LIO-ORG IBLOCK 3.0
Peripheral device type: disk
Persistent Reservation Out cmd: 5f 00 00 00 00 00 00 00 18 00
PR out: command (Register) successful
initiator# sg_persist --out --register --param-sark=0x4567ffff -Y -v /dev/sde
inquiry cdb: 12 00 00 00 24 00
LIO-ORG IBLOCK 3.0
Peripheral device type: disk
Persistent Reservation Out cmd: 5f 00 00 00 00 00 00 00 18 00
PR out: command (Register) successful
iniiator# sg_persist --out --reserve --param-rk=0x1234abcd --prout-type=5 -v /dev/sdf
inquiry cdb: 12 00 00 00 24 00
LIO-ORG IBLOCK 3.0
Peripheral device type: disk
Persistent Reservation Out cmd: 5f 01 05 00 00 00 00 00 18 00
PR out: command (Reserve) successful
initiator# sg_persist --out --clear --param-rk=0x4567ffff -v /dev/sde
inquiry cdb: 12 00 00 00 24 00
LIO-ORG IBLOCK 3.0
Peripheral device type: disk
Persistent Reservation Out cmd: 5f 03 00 00 00 00 00 00 18 00
PR out: command (Clear) successful
*) dmesg from lio-core-2.6.git node
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: 0x00000000
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: 0x000000004567ffff PRgeneration: 0x00000001
SPC-3 PR [iSCSI] Service Action: RESERVE created new reservation holder TYPE: Write Exclusive Access, Registrants Only ALL_TG_PT: 1
SPC-3 PR [iSCSI] RESERVE Node: iqn.1993-08.org.debian:01:2dadf92d0ef
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: 0x000000001234abcd PRgeneration: 0x00000000
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: 0x00000001
SPC-3 PR [iSCSI] Service Action: CLEAR complete
Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
drivers/lio-core/target_core_pr.c | 63 +++++++++++++++++++++++++++++++++++-
1 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/drivers/lio-core/target_core_pr.c b/drivers/lio-core/target_core_pr.c
index cce50dc..d733bae 100644
--- a/drivers/lio-core/target_core_pr.c
+++ b/drivers/lio-core/target_core_pr.c
@@ -1149,7 +1149,66 @@ static int core_scsi3_emulate_pro_clear(
se_cmd_t *cmd,
u64 res_key)
{
- core_scsi3_pr_generation(SE_DEV(cmd));
+ se_device_t *dev = cmd->se_dev;
+ se_session_t *se_sess = SE_SESS(cmd);
+ t10_reservation_template_t *pr_tmpl = &SU_DEV(dev)->t10_reservation;
+ t10_pr_registration_t *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
+ /*
+ * Locate the existing *pr_reg via se_node_acl_t pointers
+ */
+ 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 CLEAR\n");
+ return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ }
+ /*
+ * From spc4r17 section 5.7.11.6, Clearing:
+ *
+ * Any application client may release the persistent reservation and
+ * remove all registrations from a device server by issuing a
+ * PERSISTENT RESERVE OUT command with CLEAR service action through a
+ * registered I_T nexus with the following parameter:
+ *
+ * a) RESERVATION KEY field set to the value of the reservation key
+ * that is registered with the logical unit for the I_T nexus.
+ */
+ if (res_key != pr_reg_n->pr_res_key) {
+ printk(KERN_ERR "SPC-3 PR REGISTER: Received"
+ " res_key: 0x%016Lx does not match"
+ " existing SA REGISTER res_key:"
+ " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
+ core_scsi3_put_pr_reg(pr_reg_n);
+ return PYX_TRANSPORT_RESERVATION_CONFLICT;
+ }
+ /*
+ * a) Release the persistent reservation, if any;
+ */
+ spin_lock(&dev->dev_reservation_lock);
+ pr_res_holder = dev->dev_pr_res_holder;
+ if (pr_res_holder) {
+ se_node_acl_t *pr_res_nacl = pr_res_holder->pr_reg_nacl;
+ __core_scsi3_complete_pro_release(dev, pr_res_nacl,
+ pr_res_holder, 0);
+ }
+ spin_unlock(&dev->dev_reservation_lock);
+ /*
+ * b) Remove all registration(s) (see spc4r17 5.7.7);
+ */
+ spin_lock(&pr_tmpl->registration_lock);
+ list_for_each_entry_safe(pr_reg, pr_reg_tmp,
+ &pr_tmpl->registration_list, pr_reg_list) {
+#warning FIXME: UA + RESERVATIONS PREEMPTED for all other registered I_T nexuses
+ __core_scsi3_free_registration(dev, pr_reg,
+ (pr_reg_n == pr_reg) ? 1 : 0);
+ }
+ spin_unlock(&pr_tmpl->registration_lock);
+
+ printk(KERN_INFO "SPC-3 PR [%s] Service Action: CLEAR complete\n",
+ CMD_TFO(cmd)->get_fabric_name());
+
+ core_scsi3_pr_generation(dev);
return 0;
}
@@ -1246,9 +1305,9 @@ static int core_scsi3_emulate_pr_out(se_cmd_t *cmd, unsigned char *cdb)
case PRO_RELEASE:
return core_scsi3_emulate_pro_release(cmd,
type, scope, res_key);
-#if 0
case PRO_CLEAR:
return core_scsi3_emulate_pro_clear(cmd, res_key);
+#if 0
case PRO_PREEMPT:
return core_scsi3_emulate_pro_preempt(cmd,
type, scope, res_key, sa_res_key);
--
1.5.4.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/