[PATCH 1/6] target: split core_scsi2_emulate_crh

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Split core_scsi2_emulate_crh into one routine each for the reserve and
release side.  The common code now is in a helper called by both
routines.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Index: lio-core/drivers/target/target_core_pr.c
===================================================================
--- lio-core.orig/drivers/target/target_core_pr.c	2011-11-02 17:19:40.037591448 +0100
+++ lio-core/drivers/target/target_core_pr.c	2011-11-03 14:13:09.848690378 +0100
@@ -116,14 +116,99 @@ static int core_scsi2_reservation_check(
 	return ret;
 }
 
-static int core_scsi2_reservation_release(struct se_cmd *cmd)
+static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
+					struct se_node_acl *, struct se_session *);
+static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
+
+static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
+{
+	struct se_session *se_sess = cmd->se_sess;
+	struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
+	struct t10_pr_registration *pr_reg;
+	struct t10_reservation *pr_tmpl = &su_dev->t10_pr;
+	int crh = (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
+	int conflict = 0;
+
+	if (!crh)
+		return false;
+
+	pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
+			se_sess);
+	if (pr_reg) {
+		/*
+		 * From spc4r17 5.7.3 Exceptions to SPC-2 RESERVE and RELEASE
+		 * behavior
+		 *
+		 * A RESERVE(6) or RESERVE(10) command shall complete with GOOD
+		 * status, but no reservation shall be established and the
+		 * persistent reservation shall not be changed, if the command
+		 * is received from a) and b) below.
+		 *
+		 * A RELEASE(6) or RELEASE(10) command shall complete with GOOD
+		 * status, but the persistent reservation shall not be released,
+		 * if the command is received from a) and b)
+		 *
+		 * a) An I_T nexus that is a persistent reservation holder; or
+		 * b) An I_T nexus that is registered if a registrants only or
+		 *    all registrants type persistent reservation is present.
+		 *
+		 * In all other cases, a RESERVE(6) command, RESERVE(10) command,
+		 * RELEASE(6) command, or RELEASE(10) command shall be processed
+		 * as defined in SPC-2.
+		 */
+		if (pr_reg->pr_res_holder) {
+			core_scsi3_put_pr_reg(pr_reg);
+			*ret = 0;
+			return false;
+		}
+		if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
+		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
+		    (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
+		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
+			core_scsi3_put_pr_reg(pr_reg);
+			*ret = 0;
+			return true;
+		}
+		core_scsi3_put_pr_reg(pr_reg);
+		conflict = 1;
+	} else {
+		/*
+		 * Following spc2r20 5.5.1 Reservations overview:
+		 *
+		 * If a logical unit has executed a PERSISTENT RESERVE OUT
+		 * command with the REGISTER or the REGISTER AND IGNORE
+		 * EXISTING KEY service action and is still registered by any
+		 * initiator, all RESERVE commands and all RELEASE commands
+		 * regardless of initiator shall conflict and shall terminate
+		 * with a RESERVATION CONFLICT status.
+		 */
+		spin_lock(&pr_tmpl->registration_lock);
+		conflict = (list_empty(&pr_tmpl->registration_list)) ? 0 : 1;
+		spin_unlock(&pr_tmpl->registration_lock);
+	}
+
+	if (conflict) {
+		pr_err("Received legacy SPC-2 RESERVE/RELEASE"
+			" while active SPC-3 registrations exist,"
+			" returning RESERVATION_CONFLICT\n");
+		*ret = PYX_TRANSPORT_RESERVATION_CONFLICT;
+		return true;
+	}
+
+	return false;
+}
+
+int target_scsi2_reservation_release(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
 	struct se_session *sess = cmd->se_sess;
 	struct se_portal_group *tpg = sess->se_tpg;
+	int ret;
 
 	if (!sess || !tpg)
 		return 0;
+	if (target_check_scsi2_reservation_conflict(cmd, &ret))
+		return ret;
 
 	spin_lock(&dev->dev_reservation_lock);
 	if (!dev->dev_reserved_node_acl || !sess) {
@@ -150,11 +235,12 @@ static int core_scsi2_reservation_releas
 	return 0;
 }
 
-static int core_scsi2_reservation_reserve(struct se_cmd *cmd)
+int target_scsi2_reservation_reserve(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
 	struct se_session *sess = cmd->se_sess;
 	struct se_portal_group *tpg = sess->se_tpg;
+	int ret;
 
 	if ((cmd->t_task_cdb[1] & 0x01) &&
 	    (cmd->t_task_cdb[1] & 0x02)) {
@@ -168,6 +254,8 @@ static int core_scsi2_reservation_reserv
 	 */
 	if (!sess || !tpg)
 		return 0;
+	if (target_check_scsi2_reservation_conflict(cmd, &ret))
+		return ret;
 
 	spin_lock(&dev->dev_reservation_lock);
 	if (dev->dev_reserved_node_acl &&
@@ -200,99 +288,6 @@ static int core_scsi2_reservation_reserv
 	return 0;
 }
 
-static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
-					struct se_node_acl *, struct se_session *);
-static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
-
-/*
- * Setup in target_core_transport.c:transport_generic_cmd_sequencer()
- * and called via struct se_cmd->transport_emulate_cdb() in TCM processing
- * thread context.
- */
-int core_scsi2_emulate_crh(struct se_cmd *cmd)
-{
-	struct se_session *se_sess = cmd->se_sess;
-	struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
-	struct t10_pr_registration *pr_reg;
-	struct t10_reservation *pr_tmpl = &su_dev->t10_pr;
-	unsigned char *cdb = &cmd->t_task_cdb[0];
-	int crh = (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
-	int conflict = 0;
-
-	if (!se_sess)
-		return 0;
-
-	if (!crh)
-		goto after_crh;
-
-	pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
-			se_sess);
-	if (pr_reg) {
-		/*
-		 * From spc4r17 5.7.3 Exceptions to SPC-2 RESERVE and RELEASE
-		 * behavior
-		 *
-		 * A RESERVE(6) or RESERVE(10) command shall complete with GOOD
-		 * status, but no reservation shall be established and the
-		 * persistent reservation shall not be changed, if the command
-		 * is received from a) and b) below.
-		 *
-		 * A RELEASE(6) or RELEASE(10) command shall complete with GOOD
-		 * status, but the persistent reservation shall not be released,
-		 * if the command is received from a) and b)
-		 *
-		 * a) An I_T nexus that is a persistent reservation holder; or
-		 * b) An I_T nexus that is registered if a registrants only or
-		 *    all registrants type persistent reservation is present.
-		 *
-		 * In all other cases, a RESERVE(6) command, RESERVE(10) command,
-		 * RELEASE(6) command, or RELEASE(10) command shall be processed
-		 * as defined in SPC-2.
-		 */
-		if (pr_reg->pr_res_holder) {
-			core_scsi3_put_pr_reg(pr_reg);
-			return 0;
-		}
-		if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
-		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
-		    (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
-		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
-			core_scsi3_put_pr_reg(pr_reg);
-			return 0;
-		}
-		core_scsi3_put_pr_reg(pr_reg);
-		conflict = 1;
-	} else {
-		/*
-		 * Following spc2r20 5.5.1 Reservations overview:
-		 *
-		 * If a logical unit has executed a PERSISTENT RESERVE OUT
-		 * command with the REGISTER or the REGISTER AND IGNORE
-		 * EXISTING KEY service action and is still registered by any
-		 * initiator, all RESERVE commands and all RELEASE commands
-		 * regardless of initiator shall conflict and shall terminate
-		 * with a RESERVATION CONFLICT status.
-		 */
-		spin_lock(&pr_tmpl->registration_lock);
-		conflict = (list_empty(&pr_tmpl->registration_list)) ? 0 : 1;
-		spin_unlock(&pr_tmpl->registration_lock);
-	}
-
-	if (conflict) {
-		pr_err("Received legacy SPC-2 RESERVE/RELEASE"
-			" while active SPC-3 registrations exist,"
-			" returning RESERVATION_CONFLICT\n");
-		return PYX_TRANSPORT_RESERVATION_CONFLICT;
-	}
-
-after_crh:
-	if ((cdb[0] == RESERVE) || (cdb[0] == RESERVE_10))
-		return core_scsi2_reservation_reserve(cmd);
-	else if ((cdb[0] == RELEASE) || (cdb[0] == RELEASE_10))
-		return core_scsi2_reservation_release(cmd);
-	else
-		return PYX_TRANSPORT_INVALID_CDB_FIELD;
-}
 
 /*
  * Begin SPC-3/SPC-4 Persistent Reservations emulation support
@@ -418,12 +413,12 @@ static int core_scsi3_pr_seq_non_holder(
 		break;
 	case RELEASE:
 	case RELEASE_10:
-		/* Handled by CRH=1 in core_scsi2_emulate_crh() */
+		/* Handled by CRH=1 in target_scsi2_reservation_release() */
 		ret = 0;
 		break;
 	case RESERVE:
 	case RESERVE_10:
-		/* Handled by CRH=1 in core_scsi2_emulate_crh() */
+		/* Handled by CRH=1 in target_scsi2_reservation_reserve() */
 		ret = 0;
 		break;
 	case TEST_UNIT_READY:
Index: lio-core/drivers/target/target_core_pr.h
===================================================================
--- lio-core.orig/drivers/target/target_core_pr.h	2011-11-02 17:19:40.049593145 +0100
+++ lio-core/drivers/target/target_core_pr.h	2011-11-03 14:13:09.860697116 +0100
@@ -47,7 +47,8 @@ extern struct kmem_cache *t10_pr_reg_cac
 
 extern int core_pr_dump_initiator_port(struct t10_pr_registration *,
 			char *, u32);
-extern int core_scsi2_emulate_crh(struct se_cmd *);
+extern int target_scsi2_reservation_release(struct se_cmd *cmd);
+extern int target_scsi2_reservation_reserve(struct se_cmd *cmd);
 extern int core_scsi3_alloc_aptpl_registration(
 			struct t10_reservation *, u64,
 			unsigned char *, unsigned char *, u32,
Index: lio-core/drivers/target/target_core_transport.c
===================================================================
--- lio-core.orig/drivers/target/target_core_transport.c	2011-11-02 17:19:46.313090566 +0100
+++ lio-core/drivers/target/target_core_transport.c	2011-11-03 14:13:09.876693687 +0100
@@ -2961,10 +2961,10 @@ static int transport_generic_cmd_sequenc
 		 * is running in SPC_PASSTHROUGH, and wants reservations
 		 * emulation disabled.
 		 */
-		cmd->transport_emulate_cdb =
-				(su_dev->t10_pr.res_type !=
-				 SPC_PASSTHROUGH) ?
-				core_scsi2_emulate_crh : NULL;
+		if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) {
+			cmd->transport_emulate_cdb =
+				target_scsi2_reservation_reserve;
+		}
 		cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
 		break;
 	case RELEASE:
@@ -2978,10 +2978,10 @@ static int transport_generic_cmd_sequenc
 		else
 			size = cmd->data_length;
 
-		cmd->transport_emulate_cdb =
-				(su_dev->t10_pr.res_type !=
-				 SPC_PASSTHROUGH) ?
-				core_scsi2_emulate_crh : NULL;
+		if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) {
+			cmd->transport_emulate_cdb =
+				target_scsi2_reservation_release;
+		}
 		cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
 		break;
 	case SYNCHRONIZE_CACHE:

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux