linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 00/18] ALUA update and Referrals support
@ 2013-11-19  8:07 Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit Hannes Reinecke
                   ` (18 more replies)
  0 siblings, 19 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Hi Nic,

here's the second version of my ALUA update & Referrals support patches.
As per request I've split up the supported states into individual
attributes, and while there I've also renamed the rather confusing
'alua_access_type' and 'alua_access_status' into 'alua_management_type'
and 'alua_status_modification', respectively.

The other features are:

- Make supported states configurable:
  We should make the list of supported ALUA states configurable,
  as some setups would possibly like to support a small subset
  of ALUA states only.
- Asynchronous transitioning: I've switched 'transitioning'
  handling to use a workqueue, that should allow us to simulate
  asynchronous transitioning modes. IE TCM should now be capable
  of handling requests while in transitioning, and properly terminate
  these with the correct sense code.
- Include target device descriptor in VPD page 83
  For the ALUA device handler we'd need to identify the target device
  where a given target port belongs to. So include the respective
  values in the VPD page.

And, of course, referrals support.

Hannes Reinecke (18):
  target core: rename (ex,im)plict -> (ex,im)plicit
  target_core_alua: spellcheck
  target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
  target_core_alua: Store supported ALUA states
  target_core_alua: Make supported states configurable
  target_core_configfs: split up ALUA supported states
  target_core_configfs: Verbose ALUA state display
  target_core_configfs: Split up ALUA access type
  target_core: Rename alua_access_type in alua_mgmt_type
  target_core: Rename alua_access_status to alua_status_modification
  target_core_alua: Validate ALUA state transition
  target_core_alua: Allocate ALUA metadata on demand
  target_core_alua: store old and pending ALUA state
  target_core_alua: Use workqueue for ALUA transitioning
  target_core: simplify scsi_name_len calculation
  target_core_spc: Include target device descriptor in VPD page 83
  target_core_alua: Referrals infrastructure
  target_core_alua: Referrals configfs integration

 drivers/target/target_core_alua.c      | 764 +++++++++++++++++++++++----------
 drivers/target/target_core_alua.h      |  55 ++-
 drivers/target/target_core_configfs.c  | 360 ++++++++++++++--
 drivers/target/target_core_device.c    |   9 +-
 drivers/target/target_core_file.c      |   2 +-
 drivers/target/target_core_pr.c        |  24 +-
 drivers/target/target_core_sbc.c       |   5 +-
 drivers/target/target_core_spc.c       |  84 +++-
 drivers/target/target_core_transport.c |  32 +-
 drivers/target/target_core_ua.h        |   2 +-
 include/scsi/scsi.h                    |   1 +
 include/target/target_core_base.h      |  34 +-
 12 files changed, 1050 insertions(+), 322 deletions(-)

-- 
1.7.12.4

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-20 19:29   ` Nicholas A. Bellinger
  2013-11-19  8:07 ` [PATCH 02/18] target_core_alua: spellcheck Hannes Reinecke
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c      | 110 ++++++++++++++++-----------------
 drivers/target/target_core_alua.h      |  20 +++---
 drivers/target/target_core_configfs.c  |  26 ++++----
 drivers/target/target_core_device.c    |   6 +-
 drivers/target/target_core_file.c      |   2 +-
 drivers/target/target_core_pr.c        |  24 +++----
 drivers/target/target_core_spc.c       |   6 +-
 drivers/target/target_core_transport.c |   4 +-
 drivers/target/target_core_ua.h        |   2 +-
 include/target/target_core_base.h      |   2 +-
 10 files changed, 101 insertions(+), 101 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 4724410..8297d37 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -44,7 +44,7 @@
 static sense_reason_t core_alua_check_transition(int state, int *primary);
 static int core_alua_set_tg_pt_secondary_state(
 		struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
-		struct se_port *port, int explict, int offline);
+		struct se_port *port, int explicit, int offline);
 
 static u16 alua_lu_gps_counter;
 static u32 alua_lu_gps_count;
@@ -175,7 +175,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
 	if (ext_hdr != 0) {
 		buf[4] = 0x10;
 		/*
-		 * Set the implict transition time (in seconds) for the application
+		 * Set the implicit transition time (in seconds) for the application
 		 * client to use as a base for it's transition timeout value.
 		 *
 		 * Use the current tg_pt_gp_mem -> tg_pt_gp membership from the LUN
@@ -188,7 +188,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
 			spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 			tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
 			if (tg_pt_gp)
-				buf[5] = tg_pt_gp->tg_pt_gp_implict_trans_secs;
+				buf[5] = tg_pt_gp->tg_pt_gp_implicit_trans_secs;
 			spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 		}
 	}
@@ -199,7 +199,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
 }
 
 /*
- * SET_TARGET_PORT_GROUPS for explict ALUA operation.
+ * SET_TARGET_PORT_GROUPS for explicit ALUA operation.
  *
  * See spc4r17 section 6.35
  */
@@ -232,7 +232,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
 	/*
-	 * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed
+	 * Determine if explicit ALUA via SET_TARGET_PORT_GROUPS is allowed
 	 * for the local tg_pt_gp.
 	 */
 	l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem;
@@ -251,9 +251,9 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 	}
 	spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
 
-	if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA)) {
+	if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA)) {
 		pr_debug("Unable to process SET_TARGET_PORT_GROUPS"
-				" while TPGS_EXPLICT_ALUA is disabled\n");
+				" while TPGS_EXPLICIT_ALUA is disabled\n");
 		rc = TCM_UNSUPPORTED_SCSI_OPCODE;
 		goto out;
 	}
@@ -620,7 +620,7 @@ out:
 }
 
 /*
- * Check implict and explict ALUA state change request.
+ * Check implicit and explicit ALUA state change request.
  */
 static sense_reason_t
 core_alua_check_transition(int state, int *primary)
@@ -676,10 +676,10 @@ char *core_alua_dump_status(int status)
 	switch (status) {
 	case ALUA_STATUS_NONE:
 		return "None";
-	case ALUA_STATUS_ALTERED_BY_EXPLICT_STPG:
-		return "Altered by Explict STPG";
-	case ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA:
-		return "Altered by Implict ALUA";
+	case ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG:
+		return "Altered by Explicit STPG";
+	case ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA:
+		return "Altered by Implicit ALUA";
 	default:
 		return "Unknown";
 	}
@@ -770,7 +770,7 @@ static int core_alua_do_transition_tg_pt(
 	struct se_node_acl *nacl,
 	unsigned char *md_buf,
 	int new_state,
-	int explict)
+	int explicit)
 {
 	struct se_dev_entry *se_deve;
 	struct se_lun_acl *lacl;
@@ -784,9 +784,9 @@ static int core_alua_do_transition_tg_pt(
 	old_state = atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 			ALUA_ACCESS_STATE_TRANSITION);
-	tg_pt_gp->tg_pt_gp_alua_access_status = (explict) ?
-				ALUA_STATUS_ALTERED_BY_EXPLICT_STPG :
-				ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA;
+	tg_pt_gp->tg_pt_gp_alua_access_status = (explicit) ?
+				ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
+				ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
 	/*
 	 * Check for the optional ALUA primary state transition delay
 	 */
@@ -821,12 +821,12 @@ static int core_alua_do_transition_tg_pt(
 			lacl = se_deve->se_lun_acl;
 			/*
 			 * se_deve->se_lun_acl pointer may be NULL for a
-			 * entry created without explict Node+MappedLUN ACLs
+			 * entry created without explicit Node+MappedLUN ACLs
 			 */
 			if (!lacl)
 				continue;
 
-			if (explict &&
+			if (explicit &&
 			   (nacl != NULL) && (nacl == lacl->se_lun_nacl) &&
 			   (l_port != NULL) && (l_port == port))
 				continue;
@@ -866,8 +866,8 @@ static int core_alua_do_transition_tg_pt(
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, new_state);
 
 	pr_debug("Successful %s ALUA transition TG PT Group: %s ID: %hu"
-		" from primary access state %s to %s\n", (explict) ? "explict" :
-		"implict", config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item),
+		" from primary access state %s to %s\n", (explicit) ? "explicit" :
+		"implicit", config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item),
 		tg_pt_gp->tg_pt_gp_id, core_alua_dump_state(old_state),
 		core_alua_dump_state(new_state));
 
@@ -880,7 +880,7 @@ int core_alua_do_port_transition(
 	struct se_port *l_port,
 	struct se_node_acl *l_nacl,
 	int new_state,
-	int explict)
+	int explicit)
 {
 	struct se_device *dev;
 	struct se_port *port;
@@ -917,7 +917,7 @@ int core_alua_do_port_transition(
 		 * success.
 		 */
 		core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl,
-					md_buf, new_state, explict);
+					md_buf, new_state, explicit);
 		atomic_dec(&lu_gp->lu_gp_ref_cnt);
 		smp_mb__after_atomic_dec();
 		kfree(md_buf);
@@ -970,7 +970,7 @@ int core_alua_do_port_transition(
 			 * success.
 			 */
 			core_alua_do_transition_tg_pt(tg_pt_gp, port,
-					nacl, md_buf, new_state, explict);
+					nacl, md_buf, new_state, explicit);
 
 			spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 			atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
@@ -987,7 +987,7 @@ int core_alua_do_port_transition(
 	pr_debug("Successfully processed LU Group: %s all ALUA TG PT"
 		" Group IDs: %hu %s transition to primary state: %s\n",
 		config_item_name(&lu_gp->lu_gp_group.cg_item),
-		l_tg_pt_gp->tg_pt_gp_id, (explict) ? "explict" : "implict",
+		l_tg_pt_gp->tg_pt_gp_id, (explicit) ? "explicit" : "implicit",
 		core_alua_dump_state(new_state));
 
 	atomic_dec(&lu_gp->lu_gp_ref_cnt);
@@ -1034,7 +1034,7 @@ static int core_alua_update_tpg_secondary_metadata(
 static int core_alua_set_tg_pt_secondary_state(
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
 	struct se_port *port,
-	int explict,
+	int explicit,
 	int offline)
 {
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
@@ -1061,13 +1061,13 @@ static int core_alua_set_tg_pt_secondary_state(
 		atomic_set(&port->sep_tg_pt_secondary_offline, 0);
 
 	md_buf_len = tg_pt_gp->tg_pt_gp_md_buf_len;
-	port->sep_tg_pt_secondary_stat = (explict) ?
-			ALUA_STATUS_ALTERED_BY_EXPLICT_STPG :
-			ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA;
+	port->sep_tg_pt_secondary_stat = (explicit) ?
+			ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
+			ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
 
 	pr_debug("Successful %s ALUA transition TG PT Group: %s ID: %hu"
-		" to secondary access state: %s\n", (explict) ? "explict" :
-		"implict", config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item),
+		" to secondary access state: %s\n", (explicit) ? "explicit" :
+		"implicit", config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item),
 		tg_pt_gp->tg_pt_gp_id, (offline) ? "OFFLINE" : "ONLINE");
 
 	spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -1356,16 +1356,16 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 		ALUA_ACCESS_STATE_ACTIVE_OPTMIZED);
 	/*
-	 * Enable both explict and implict ALUA support by default
+	 * Enable both explicit and implicit ALUA support by default
 	 */
 	tg_pt_gp->tg_pt_gp_alua_access_type =
-			TPGS_EXPLICT_ALUA | TPGS_IMPLICT_ALUA;
+			TPGS_EXPLICIT_ALUA | TPGS_IMPLICIT_ALUA;
 	/*
 	 * Set the default Active/NonOptimized Delay in milliseconds
 	 */
 	tg_pt_gp->tg_pt_gp_nonop_delay_msecs = ALUA_DEFAULT_NONOP_DELAY_MSECS;
 	tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
-	tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS;
+	tg_pt_gp->tg_pt_gp_implicit_trans_secs = ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
 
 	if (def_group) {
 		spin_lock(&dev->t10_alua.tg_pt_gps_lock);
@@ -1465,7 +1465,7 @@ void core_alua_free_tg_pt_gp(
 	 * been called from target_core_alua_drop_tg_pt_gp().
 	 *
 	 * Here we remove *tg_pt_gp from the global list so that
-	 * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS
+	 * no assications *OR* explicit ALUA via SET_TARGET_PORT_GROUPS
 	 * can be made while we are releasing struct t10_alua_tg_pt_gp.
 	 */
 	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
@@ -1740,13 +1740,13 @@ ssize_t core_alua_show_access_type(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	char *page)
 {
-	if ((tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA) &&
-	    (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICT_ALUA))
-		return sprintf(page, "Implict and Explict\n");
-	else if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICT_ALUA)
-		return sprintf(page, "Implict\n");
-	else if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA)
-		return sprintf(page, "Explict\n");
+	if ((tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA) &&
+	    (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA))
+		return sprintf(page, "Implicit and Explicit\n");
+	else if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA)
+		return sprintf(page, "Implicit\n");
+	else if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA)
+		return sprintf(page, "Explicit\n");
 	else
 		return sprintf(page, "None\n");
 }
@@ -1771,11 +1771,11 @@ ssize_t core_alua_store_access_type(
 	}
 	if (tmp == 3)
 		tg_pt_gp->tg_pt_gp_alua_access_type =
-			TPGS_IMPLICT_ALUA | TPGS_EXPLICT_ALUA;
+			TPGS_IMPLICIT_ALUA | TPGS_EXPLICIT_ALUA;
 	else if (tmp == 2)
-		tg_pt_gp->tg_pt_gp_alua_access_type = TPGS_EXPLICT_ALUA;
+		tg_pt_gp->tg_pt_gp_alua_access_type = TPGS_EXPLICIT_ALUA;
 	else if (tmp == 1)
-		tg_pt_gp->tg_pt_gp_alua_access_type = TPGS_IMPLICT_ALUA;
+		tg_pt_gp->tg_pt_gp_alua_access_type = TPGS_IMPLICIT_ALUA;
 	else
 		tg_pt_gp->tg_pt_gp_alua_access_type = 0;
 
@@ -1844,14 +1844,14 @@ ssize_t core_alua_store_trans_delay_msecs(
 	return count;
 }
 
-ssize_t core_alua_show_implict_trans_secs(
+ssize_t core_alua_show_implicit_trans_secs(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	char *page)
 {
-	return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_implict_trans_secs);
+	return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_implicit_trans_secs);
 }
 
-ssize_t core_alua_store_implict_trans_secs(
+ssize_t core_alua_store_implicit_trans_secs(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	const char *page,
 	size_t count)
@@ -1861,16 +1861,16 @@ ssize_t core_alua_store_implict_trans_secs(
 
 	ret = kstrtoul(page, 0, &tmp);
 	if (ret < 0) {
-		pr_err("Unable to extract implict_trans_secs\n");
+		pr_err("Unable to extract implicit_trans_secs\n");
 		return ret;
 	}
-	if (tmp > ALUA_MAX_IMPLICT_TRANS_SECS) {
-		pr_err("Passed implict_trans_secs: %lu, exceeds"
-			" ALUA_MAX_IMPLICT_TRANS_SECS: %d\n", tmp,
-			ALUA_MAX_IMPLICT_TRANS_SECS);
+	if (tmp > ALUA_MAX_IMPLICIT_TRANS_SECS) {
+		pr_err("Passed implicit_trans_secs: %lu, exceeds"
+			" ALUA_MAX_IMPLICIT_TRANS_SECS: %d\n", tmp,
+			ALUA_MAX_IMPLICIT_TRANS_SECS);
 		return  -EINVAL;
 	}
-	tg_pt_gp->tg_pt_gp_implict_trans_secs = (int)tmp;
+	tg_pt_gp->tg_pt_gp_implicit_trans_secs = (int)tmp;
 
 	return count;
 }
@@ -1970,8 +1970,8 @@ ssize_t core_alua_store_secondary_status(
 		return ret;
 	}
 	if ((tmp != ALUA_STATUS_NONE) &&
-	    (tmp != ALUA_STATUS_ALTERED_BY_EXPLICT_STPG) &&
-	    (tmp != ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA)) {
+	    (tmp != ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG) &&
+	    (tmp != ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA)) {
 		pr_err("Illegal value for alua_tg_pt_status: %lu\n",
 				tmp);
 		return -EINVAL;
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index e539c3e..74cf0c0 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -7,8 +7,8 @@
  * from spc4r17 section 6.4.2 Table 135
  */
 #define TPGS_NO_ALUA				0x00
-#define TPGS_IMPLICT_ALUA			0x10
-#define TPGS_EXPLICT_ALUA			0x20
+#define TPGS_IMPLICIT_ALUA			0x10
+#define TPGS_EXPLICIT_ALUA			0x20
 
 /*
  * ASYMMETRIC ACCESS STATE field
@@ -28,8 +28,8 @@
  * from spc4r17 section 6.27 Table 246
  */
 #define ALUA_STATUS_NONE				0x00
-#define ALUA_STATUS_ALTERED_BY_EXPLICT_STPG		0x01
-#define ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA		0x02
+#define ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG		0x01
+#define ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA		0x02
 
 /*
  * From spc4r17, Table D.1: ASC and ASCQ Assignement
@@ -46,17 +46,17 @@
 #define ALUA_DEFAULT_NONOP_DELAY_MSECS			100
 #define ALUA_MAX_NONOP_DELAY_MSECS			10000 /* 10 seconds */
 /*
- * Used for implict and explict ALUA transitional delay, that is disabled
+ * Used for implicit and explicit ALUA transitional delay, that is disabled
  * by default, and is intended to be used for debugging client side ALUA code.
  */
 #define ALUA_DEFAULT_TRANS_DELAY_MSECS			0
 #define ALUA_MAX_TRANS_DELAY_MSECS			30000 /* 30 seconds */
 /*
- * Used for the recommended application client implict transition timeout
+ * Used for the recommended application client implicit transition timeout
  * in seconds, returned by the REPORT_TARGET_PORT_GROUPS w/ extended header.
  */
-#define ALUA_DEFAULT_IMPLICT_TRANS_SECS			0
-#define ALUA_MAX_IMPLICT_TRANS_SECS			255
+#define ALUA_DEFAULT_IMPLICIT_TRANS_SECS			0
+#define ALUA_MAX_IMPLICIT_TRANS_SECS			255
 /*
  * Used by core_alua_update_tpg_primary_metadata() and
  * core_alua_update_tpg_secondary_metadata()
@@ -113,9 +113,9 @@ extern ssize_t core_alua_show_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
 					char *);
 extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
 					const char *, size_t);
-extern ssize_t core_alua_show_implict_trans_secs(struct t10_alua_tg_pt_gp *,
+extern ssize_t core_alua_show_implicit_trans_secs(struct t10_alua_tg_pt_gp *,
 					char *);
-extern ssize_t core_alua_store_implict_trans_secs(struct t10_alua_tg_pt_gp *,
+extern ssize_t core_alua_store_implicit_trans_secs(struct t10_alua_tg_pt_gp *,
 					const char *, size_t);
 extern ssize_t core_alua_show_preferred_bit(struct t10_alua_tg_pt_gp *,
 					char *);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index b04edc1..3a964fb 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2036,7 +2036,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 	int new_state, ret;
 
 	if (!tg_pt_gp->tg_pt_gp_valid_id) {
-		pr_err("Unable to do implict ALUA on non valid"
+		pr_err("Unable to do implicit ALUA on non valid"
 			" tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id);
 		return -EINVAL;
 	}
@@ -2049,9 +2049,9 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 	}
 	new_state = (int)tmp;
 
-	if (!(tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICT_ALUA)) {
-		pr_err("Unable to process implict configfs ALUA"
-			" transition while TPGS_IMPLICT_ALUA is disabled\n");
+	if (!(tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA)) {
+		pr_err("Unable to process implicit configfs ALUA"
+			" transition while TPGS_IMPLICIT_ALUA is disabled\n");
 		return -EINVAL;
 	}
 
@@ -2097,8 +2097,8 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
 	new_status = (int)tmp;
 
 	if ((new_status != ALUA_STATUS_NONE) &&
-	    (new_status != ALUA_STATUS_ALTERED_BY_EXPLICT_STPG) &&
-	    (new_status != ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA)) {
+	    (new_status != ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG) &&
+	    (new_status != ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA)) {
 		pr_err("Illegal ALUA access status: 0x%02x\n",
 				new_status);
 		return -EINVAL;
@@ -2210,24 +2210,24 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_trans_delay_msecs(
 SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR);
 
 /*
- * implict_trans_secs
+ * implicit_trans_secs
  */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_implict_trans_secs(
+static ssize_t target_core_alua_tg_pt_gp_show_attr_implicit_trans_secs(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	char *page)
 {
-	return core_alua_show_implict_trans_secs(tg_pt_gp, page);
+	return core_alua_show_implicit_trans_secs(tg_pt_gp, page);
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_implict_trans_secs(
+static ssize_t target_core_alua_tg_pt_gp_store_attr_implicit_trans_secs(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	const char *page,
 	size_t count)
 {
-	return core_alua_store_implict_trans_secs(tg_pt_gp, page, count);
+	return core_alua_store_implicit_trans_secs(tg_pt_gp, page, count);
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(implict_trans_secs, S_IRUGO | S_IWUSR);
+SE_DEV_ALUA_TG_PT_ATTR(implicit_trans_secs, S_IRUGO | S_IWUSR);
 
 /*
  * preferred
@@ -2353,7 +2353,7 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
 	&target_core_alua_tg_pt_gp_alua_write_metadata.attr,
 	&target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
 	&target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
-	&target_core_alua_tg_pt_gp_implict_trans_secs.attr,
+	&target_core_alua_tg_pt_gp_implicit_trans_secs.attr,
 	&target_core_alua_tg_pt_gp_preferred.attr,
 	&target_core_alua_tg_pt_gp_tg_pt_gp_id.attr,
 	&target_core_alua_tg_pt_gp_members.attr,
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 986afd2..207b340 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -313,14 +313,14 @@ int core_enable_device_list_for_node(
 	deve = nacl->device_list[mapped_lun];
 
 	/*
-	 * Check if the call is handling demo mode -> explict LUN ACL
+	 * Check if the call is handling demo mode -> explicit LUN ACL
 	 * transition.  This transition must be for the same struct se_lun
 	 * + mapped_lun that was setup in demo mode..
 	 */
 	if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
 		if (deve->se_lun_acl != NULL) {
 			pr_err("struct se_dev_entry->se_lun_acl"
-			       " already set for demo mode -> explict"
+			       " already set for demo mode -> explicit"
 			       " LUN ACL transition\n");
 			spin_unlock_irq(&nacl->device_list_lock);
 			return -EINVAL;
@@ -328,7 +328,7 @@ int core_enable_device_list_for_node(
 		if (deve->se_lun != lun) {
 			pr_err("struct se_dev_entry->se_lun does"
 			       " match passed struct se_lun for demo mode"
-			       " -> explict LUN ACL transition\n");
+			       " -> explicit LUN ACL transition\n");
 			spin_unlock_irq(&nacl->device_list_lock);
 			return -EINVAL;
 		}
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index b662f89..0e34cda 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -562,7 +562,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
 	} else {
 		ret = fd_do_rw(cmd, sgl, sgl_nents, 1);
 		/*
-		 * Perform implict vfs_fsync_range() for fd_do_writev() ops
+		 * Perform implicit vfs_fsync_range() for fd_do_writev() ops
 		 * for SCSI WRITEs with Forced Unit Access (FUA) set.
 		 * Allow this to happen independent of WCE=0 setting.
 		 */
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index d1ae4c5..2f5d779 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -474,7 +474,7 @@ static int core_scsi3_pr_seq_non_holder(
 	 * statement.
 	 */
 	if (!ret && !other_cdb) {
-		pr_debug("Allowing explict CDB: 0x%02x for %s"
+		pr_debug("Allowing explicit CDB: 0x%02x for %s"
 			" reservation holder\n", cdb[0],
 			core_scsi3_pr_dump_type(pr_reg_type));
 
@@ -507,7 +507,7 @@ static int core_scsi3_pr_seq_non_holder(
 			 */
 
 			if (!registered_nexus) {
-				pr_debug("Allowing implict CDB: 0x%02x"
+				pr_debug("Allowing implicit CDB: 0x%02x"
 					" for %s reservation on unregistered"
 					" nexus\n", cdb[0],
 					core_scsi3_pr_dump_type(pr_reg_type));
@@ -522,7 +522,7 @@ static int core_scsi3_pr_seq_non_holder(
 			 * allow commands from registered nexuses.
 			 */
 
-			pr_debug("Allowing implict CDB: 0x%02x for %s"
+			pr_debug("Allowing implicit CDB: 0x%02x for %s"
 				" reservation\n", cdb[0],
 				core_scsi3_pr_dump_type(pr_reg_type));
 
@@ -683,7 +683,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 					alua_port_list) {
 			/*
 			 * This pointer will be NULL for demo mode MappedLUNs
-			 * that have not been make explict via a ConfigFS
+			 * that have not been make explicit via a ConfigFS
 			 * MappedLUN group for the SCSI Initiator Node ACL.
 			 */
 			if (!deve_tmp->se_lun_acl)
@@ -1158,7 +1158,7 @@ static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg)
 	smp_mb__after_atomic_dec();
 }
 
-static int core_scsi3_check_implict_release(
+static int core_scsi3_check_implicit_release(
 	struct se_device *dev,
 	struct t10_pr_registration *pr_reg)
 {
@@ -1174,7 +1174,7 @@ static int core_scsi3_check_implict_release(
 	}
 	if (pr_res_holder == pr_reg) {
 		/*
-		 * Perform an implict RELEASE if the registration that
+		 * Perform an implicit RELEASE if the registration that
 		 * is being released is holding the reservation.
 		 *
 		 * From spc4r17, section 5.7.11.1:
@@ -1192,7 +1192,7 @@ static int core_scsi3_check_implict_release(
 		 * For 'All Registrants' reservation types, all existing
 		 * registrations are still processed as reservation holders
 		 * in core_scsi3_pr_seq_non_holder() after the initial
-		 * reservation holder is implictly released here.
+		 * reservation holder is implicitly released here.
 		 */
 	} else if (pr_reg->pr_reg_all_tg_pt &&
 		  (!strcmp(pr_res_holder->pr_reg_nacl->initiatorname,
@@ -2125,7 +2125,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
 		/*
 		 * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus.
 		 */
-		pr_holder = core_scsi3_check_implict_release(
+		pr_holder = core_scsi3_check_implicit_release(
 				cmd->se_dev, pr_reg);
 		if (pr_holder < 0) {
 			ret = TCM_RESERVATION_CONFLICT;
@@ -2402,7 +2402,7 @@ static void __core_scsi3_complete_pro_release(
 	struct se_device *dev,
 	struct se_node_acl *se_nacl,
 	struct t10_pr_registration *pr_reg,
-	int explict)
+	int explicit)
 {
 	struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo;
 	char i_buf[PR_REG_ISID_ID_LEN];
@@ -2416,7 +2416,7 @@ static void __core_scsi3_complete_pro_release(
 
 	pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared"
 		" reservation holder TYPE: %s ALL_TG_PT: %d\n",
-		tfo->get_fabric_name(), (explict) ? "explict" : "implict",
+		tfo->get_fabric_name(), (explicit) ? "explicit" : "implicit",
 		core_scsi3_pr_dump_type(pr_reg->pr_res_type),
 		(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
 	pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n",
@@ -2692,7 +2692,7 @@ static void __core_scsi3_complete_pro_preempt(
 	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
 	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);
 	/*
-	 * Do an implict RELEASE of the existing reservation.
+	 * Do an implicit RELEASE of the existing reservation.
 	 */
 	if (dev->dev_pr_res_holder)
 		__core_scsi3_complete_pro_release(dev, nacl,
@@ -2845,7 +2845,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 				 * 5.7.11.4 Preempting, Table 52 and Figure 7.
 				 *
 				 * For a ZERO SA Reservation key, release
-				 * all other registrations and do an implict
+				 * all other registrations and do an implicit
 				 * release of active persistent reservation.
 				 *
 				 * For a non-ZERO SA Reservation key, only
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index f89a86f..021c3f4 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -48,7 +48,7 @@ static void spc_fill_alua_data(struct se_port *port, unsigned char *buf)
 	buf[5]	= 0x80;
 
 	/*
-	 * Set TPGS field for explict and/or implict ALUA access type
+	 * Set TPGS field for explicit and/or implicit ALUA access type
 	 * and opteration.
 	 *
 	 * See spc4r17 section 6.4.2 Table 135
@@ -1257,7 +1257,7 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 		*size = (cdb[3] << 8) + cdb[4];
 
 		/*
-		 * Do implict HEAD_OF_QUEUE processing for INQUIRY.
+		 * Do implicit HEAD_OF_QUEUE processing for INQUIRY.
 		 * See spc4r17 section 5.3
 		 */
 		cmd->sam_task_attr = MSG_HEAD_TAG;
@@ -1291,7 +1291,7 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 		cmd->execute_cmd = spc_emulate_report_luns;
 		*size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
 		/*
-		 * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS
+		 * Do implicit HEAD_OF_QUEUE processing for REPORT_LUNS
 		 * See spc4r17 section 5.3
 		 */
 		cmd->sam_task_attr = MSG_HEAD_TAG;
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 46d8229..269a798 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -462,7 +462,7 @@ void transport_deregister_session(struct se_session *se_sess)
 	pr_debug("TARGET_CORE[%s]: Deregistered fabric_sess\n",
 		se_tpg->se_tpg_tfo->get_fabric_name());
 	/*
-	 * If last kref is dropping now for an explict NodeACL, awake sleeping
+	 * If last kref is dropping now for an explicit NodeACL, awake sleeping
 	 * ->acl_free_comp caller to wakeup configfs se_node_acl->acl_group
 	 * removal context.
 	 */
@@ -636,7 +636,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
 		cmd->transport_state |= CMD_T_FAILED;
 
 	/*
-	 * Check for case where an explict ABORT_TASK has been received
+	 * Check for case where an explicit ABORT_TASK has been received
 	 * and transport_wait_for_tasks() will be waiting for completion..
 	 */
 	if (cmd->transport_state & CMD_T_ABORTED &&
diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h
index 0204952..be912b3 100644
--- a/drivers/target/target_core_ua.h
+++ b/drivers/target/target_core_ua.h
@@ -19,7 +19,7 @@
 #define ASCQ_2AH_RESERVATIONS_RELEASED				0x04
 #define ASCQ_2AH_REGISTRATIONS_PREEMPTED			0x05
 #define ASCQ_2AH_ASYMMETRIC_ACCESS_STATE_CHANGED		0x06
-#define ASCQ_2AH_IMPLICT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED 0x07
+#define ASCQ_2AH_IMPLICIT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED 0x07
 #define ASCQ_2AH_PRIORITY_CHANGED				0x08
 
 #define ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS		0x09
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 499e85d..658b356 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -287,7 +287,7 @@ struct t10_alua_tg_pt_gp {
 	int	tg_pt_gp_alua_access_type;
 	int	tg_pt_gp_nonop_delay_msecs;
 	int	tg_pt_gp_trans_delay_msecs;
-	int	tg_pt_gp_implict_trans_secs;
+	int	tg_pt_gp_implicit_trans_secs;
 	int	tg_pt_gp_pref;
 	int	tg_pt_gp_write_metadata;
 	/* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/18] target_core_alua: spellcheck
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-20 19:30   ` Nicholas A. Bellinger
  2013-11-19  8:07 ` [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED Hannes Reinecke
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 8297d37..1994353 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -330,7 +330,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 			spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 		} else {
 			/*
-			 * Extact the RELATIVE TARGET PORT IDENTIFIER to identify
+			 * Extract the RELATIVE TARGET PORT IDENTIFIER to identify
 			 * the Target Port in question for the the incoming
 			 * SET_TARGET_PORT_GROUPS op.
 			 */
@@ -487,7 +487,7 @@ static inline int core_alua_state_transition(
 	u8 *alua_ascq)
 {
 	/*
-	 * Allowed CDBs for ALUA_ACCESS_STATE_TRANSITIO as defined by
+	 * Allowed CDBs for ALUA_ACCESS_STATE_TRANSITION as defined by
 	 * spc4r17 section 5.9.2.5
 	 */
 	switch (cdb[0]) {
@@ -515,9 +515,9 @@ static inline int core_alua_state_transition(
 }
 
 /*
- * return 1: Is used to signal LUN not accecsable, and check condition/not ready
+ * return 1: Is used to signal LUN not accessible, and check condition/not ready
  * return 0: Used to signal success
- * reutrn -1: Used to signal failure, and invalid cdb field
+ * return -1: Used to signal failure, and invalid cdb field
  */
 sense_reason_t
 target_alua_state_check(struct se_cmd *cmd)
@@ -802,7 +802,7 @@ static int core_alua_do_transition_tg_pt(
 		 * change, a device server shall establish a unit attention
 		 * condition for the initiator port associated with every I_T
 		 * nexus with the additional sense code set to ASYMMETRIC
-		 * ACCESS STATE CHAGED.
+		 * ACCESS STATE CHANGED.
 		 *
 		 * After an explicit target port asymmetric access state
 		 * change, a device server shall establish a unit attention
@@ -946,7 +946,7 @@ int core_alua_do_port_transition(
 				continue;
 			/*
 			 * If the target behavior port asymmetric access state
-			 * is changed for any target port group accessiable via
+			 * is changed for any target port group accessible via
 			 * a logical unit within a LU group, the target port
 			 * behavior group asymmetric access states for the same
 			 * target port group accessible via other logical units
@@ -1232,7 +1232,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp)
 		 * struct se_device is released via core_alua_free_lu_gp_mem().
 		 *
 		 * If the passed lu_gp does NOT match the default_lu_gp, assume
-		 * we want to re-assocate a given lu_gp_mem with default_lu_gp.
+		 * we want to re-associate a given lu_gp_mem with default_lu_gp.
 		 */
 		spin_lock(&lu_gp_mem->lu_gp_mem_lock);
 		if (lu_gp != default_lu_gp)
@@ -1465,7 +1465,7 @@ void core_alua_free_tg_pt_gp(
 	 * been called from target_core_alua_drop_tg_pt_gp().
 	 *
 	 * Here we remove *tg_pt_gp from the global list so that
-	 * no assications *OR* explicit ALUA via SET_TARGET_PORT_GROUPS
+	 * no associations *OR* explicit ALUA via SET_TARGET_PORT_GROUPS
 	 * can be made while we are releasing struct t10_alua_tg_pt_gp.
 	 */
 	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
@@ -1501,7 +1501,7 @@ void core_alua_free_tg_pt_gp(
 		 * core_alua_free_tg_pt_gp_mem().
 		 *
 		 * If the passed tg_pt_gp does NOT match the default_tg_pt_gp,
-		 * assume we want to re-assocate a given tg_pt_gp_mem with
+		 * assume we want to re-associate a given tg_pt_gp_mem with
 		 * default_tg_pt_gp.
 		 */
 		spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 02/18] target_core_alua: spellcheck Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-20 19:30   ` Nicholas A. Bellinger
  2013-11-19  8:07 ` [PATCH 04/18] target_core_alua: Store supported ALUA states Hannes Reinecke
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Rename ALUA_ACCESS_STATE_OPTMIZED to
ALUA_ACCESS_STATE_OPTIMIZED.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 10 +++++-----
 drivers/target/target_core_alua.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 1994353..08e41e3 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -566,12 +566,12 @@ target_alua_state_check(struct se_cmd *cmd)
 	nonop_delay_msecs = tg_pt_gp->tg_pt_gp_nonop_delay_msecs;
 	spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 	/*
-	 * Process ALUA_ACCESS_STATE_ACTIVE_OPTMIZED in a separate conditional
+	 * Process ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED in a separate conditional
 	 * statement so the compiler knows explicitly to check this case first.
 	 * For the Optimized ALUA access state case, we want to process the
 	 * incoming fabric cmd ASAP..
 	 */
-	if (out_alua_state == ALUA_ACCESS_STATE_ACTIVE_OPTMIZED)
+	if (out_alua_state == ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED)
 		return 0;
 
 	switch (out_alua_state) {
@@ -626,7 +626,7 @@ static sense_reason_t
 core_alua_check_transition(int state, int *primary)
 {
 	switch (state) {
-	case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED:
+	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
 	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
 	case ALUA_ACCESS_STATE_STANDBY:
 	case ALUA_ACCESS_STATE_UNAVAILABLE:
@@ -654,7 +654,7 @@ core_alua_check_transition(int state, int *primary)
 static char *core_alua_dump_state(int state)
 {
 	switch (state) {
-	case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED:
+	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
 		return "Active/Optimized";
 	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
 		return "Active/NonOptimized";
@@ -1354,7 +1354,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
 	tg_pt_gp->tg_pt_gp_dev = dev;
 	tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN;
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
-		ALUA_ACCESS_STATE_ACTIVE_OPTMIZED);
+		ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED);
 	/*
 	 * Enable both explicit and implicit ALUA support by default
 	 */
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index 74cf0c0..d6db78b 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -15,7 +15,7 @@
  *
  * from spc4r17 section 6.27 Table 245
  */
-#define ALUA_ACCESS_STATE_ACTIVE_OPTMIZED	0x0
+#define ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED	0x0
 #define ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED	0x1
 #define ALUA_ACCESS_STATE_STANDBY		0x2
 #define ALUA_ACCESS_STATE_UNAVAILABLE		0x3
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/18] target_core_alua: Store supported ALUA states
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (2 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-20 19:31   ` Nicholas A. Bellinger
  2013-11-19  8:07 ` [PATCH 05/18] target_core_alua: Make supported states configurable Hannes Reinecke
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

The supported ALUA states might be different for individual
devices, so store it in a separate field.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 14 ++++++++------
 drivers/target/target_core_alua.h | 11 +++++++++++
 include/target/target_core_base.h |  1 +
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 08e41e3..a16115e 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -117,12 +117,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
 		/*
 		 * Set supported ASYMMETRIC ACCESS State bits
 		 */
-		buf[off] = 0x80; /* T_SUP */
-		buf[off] |= 0x40; /* O_SUP */
-		buf[off] |= 0x8; /* U_SUP */
-		buf[off] |= 0x4; /* S_SUP */
-		buf[off] |= 0x2; /* AN_SUP */
-		buf[off++] |= 0x1; /* AO_SUP */
+		buf[off++] |= tg_pt_gp->tg_pt_gp_alua_supported_states;
 		/*
 		 * TARGET PORT GROUP
 		 */
@@ -1367,6 +1362,13 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
 	tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
 	tg_pt_gp->tg_pt_gp_implicit_trans_secs = ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
 
+	/*
+	 * Enable all supported states
+	 */
+	tg_pt_gp->tg_pt_gp_alua_supported_states =
+	    ALUA_T_SUP | ALUA_O_SUP | \
+	    ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
+
 	if (def_group) {
 		spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 		tg_pt_gp->tg_pt_gp_id =
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index d6db78b..88e2e83 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -23,6 +23,17 @@
 #define ALUA_ACCESS_STATE_TRANSITION		0xf
 
 /*
+ * from spc4r36j section 6.37 Table 306
+ */
+#define ALUA_T_SUP		0x80
+#define ALUA_O_SUP		0x40
+#define ALUA_LBD_SUP		0x10
+#define ALUA_U_SUP		0x08
+#define ALUA_S_SUP		0x04
+#define ALUA_AN_SUP		0x02
+#define ALUA_AO_SUP		0x01
+
+/*
  * REPORT_TARGET_PORT_GROUP STATUS CODE
  *
  * from spc4r17 section 6.27 Table 246
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 658b356..a23785f 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -283,6 +283,7 @@ struct t10_alua_lu_gp_member {
 struct t10_alua_tg_pt_gp {
 	u16	tg_pt_gp_id;
 	int	tg_pt_gp_valid_id;
+	int	tg_pt_gp_alua_supported_states;
 	int	tg_pt_gp_alua_access_status;
 	int	tg_pt_gp_alua_access_type;
 	int	tg_pt_gp_nonop_delay_msecs;
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/18] target_core_alua: Make supported states configurable
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (3 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 04/18] target_core_alua: Store supported ALUA states Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-20 19:36   ` Nicholas A. Bellinger
  2013-11-19  8:07 ` [PATCH 06/18] target_core_configfs: split up ALUA supported states Hannes Reinecke
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_configfs.c | 50 +++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 3a964fb..1e4ea28 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2131,6 +2131,55 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type(
 SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
 
 /*
+ * alua_supported_states
+ */
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_supported_states(
+	struct t10_alua_tg_pt_gp *tg_pt_gp,
+	char *page)
+{
+	return sprintf(page, "%02x\n",
+		tg_pt_gp->tg_pt_gp_alua_supported_states);
+}
+
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_supported_states(
+	struct t10_alua_tg_pt_gp *tg_pt_gp,
+	const char *page,
+	size_t count)
+{
+	unsigned long tmp;
+	int new_states, valid_states, ret;
+
+	if (!tg_pt_gp->tg_pt_gp_valid_id) {
+		pr_err("Unable to do set supported ALUA states on non"
+			" valid tg_pt_gp ID: %hu\n",
+			tg_pt_gp->tg_pt_gp_valid_id);
+		return -EINVAL;
+	}
+
+	ret = strict_strtoul(page, 0, &tmp);
+	if (ret < 0) {
+		pr_err("Unable to extract new supported ALUA states"
+				" from %s\n", page);
+		return -EINVAL;
+	}
+	new_states = (int)tmp;
+	valid_states = ALUA_T_SUP | ALUA_O_SUP | ALUA_LBD_SUP | \
+	    ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
+
+
+	if (new_states & ~valid_states) {
+		pr_err("Illegal supported ALUA states: 0x%02x\n",
+				new_states);
+		return -EINVAL;
+	}
+
+	tg_pt_gp->tg_pt_gp_alua_supported_states = new_states;
+	return count;
+}
+
+SE_DEV_ALUA_TG_PT_ATTR(alua_supported_states, S_IRUGO | S_IWUSR);
+
+/*
  * alua_write_metadata
  */
 static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_write_metadata(
@@ -2350,6 +2399,7 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
 	&target_core_alua_tg_pt_gp_alua_access_state.attr,
 	&target_core_alua_tg_pt_gp_alua_access_status.attr,
 	&target_core_alua_tg_pt_gp_alua_access_type.attr,
+	&target_core_alua_tg_pt_gp_alua_supported_states.attr,
 	&target_core_alua_tg_pt_gp_alua_write_metadata.attr,
 	&target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
 	&target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/18] target_core_configfs: split up ALUA supported states
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (4 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 05/18] target_core_alua: Make supported states configurable Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-20 19:39   ` Nicholas A. Bellinger
  2013-11-19  8:07 ` [PATCH 07/18] target_core_configfs: Verbose ALUA state display Hannes Reinecke
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Split up the various ALUA states into individual attributes to
make parsing easier and adhere to the one value per attribute
sysfs principle.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_configfs.c | 127 ++++++++++++++++++++++------------
 1 file changed, 84 insertions(+), 43 deletions(-)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 1e4ea28..8476f48 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2133,51 +2133,86 @@ SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
 /*
  * alua_supported_states
  */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_supported_states(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	char *page)
-{
-	return sprintf(page, "%02x\n",
-		tg_pt_gp->tg_pt_gp_alua_supported_states);
-}
-
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_supported_states(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	const char *page,
-	size_t count)
-{
-	unsigned long tmp;
-	int new_states, valid_states, ret;
 
-	if (!tg_pt_gp->tg_pt_gp_valid_id) {
-		pr_err("Unable to do set supported ALUA states on non"
-			" valid tg_pt_gp ID: %hu\n",
-			tg_pt_gp->tg_pt_gp_valid_id);
-		return -EINVAL;
-	}
-
-	ret = strict_strtoul(page, 0, &tmp);
-	if (ret < 0) {
-		pr_err("Unable to extract new supported ALUA states"
-				" from %s\n", page);
-		return -EINVAL;
-	}
-	new_states = (int)tmp;
-	valid_states = ALUA_T_SUP | ALUA_O_SUP | ALUA_LBD_SUP | \
-	    ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
-
-
-	if (new_states & ~valid_states) {
-		pr_err("Illegal supported ALUA states: 0x%02x\n",
-				new_states);
-		return -EINVAL;
-	}
-
-	tg_pt_gp->tg_pt_gp_alua_supported_states = new_states;
-	return count;
+#define SE_DEV_ALUA_SUPPORT_STATE_SHOW(_name, _var, _bit)		\
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_support_##_name( \
+	struct t10_alua_tg_pt_gp *t, char *p)				\
+{									\
+	return sprintf(p, "%d\n", !!(t->_var & _bit));			\
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(alua_supported_states, S_IRUGO | S_IWUSR);
+#define SE_DEV_ALUA_SUPPORT_STATE_STORE(_name, _var, _bit)		\
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
+	struct t10_alua_tg_pt_gp *t, const char *p, size_t c)		\
+{									\
+	unsigned long tmp;						\
+	int ret;							\
+									\
+	if (!t->tg_pt_gp_valid_id) {					\
+		pr_err("Unable to do set ##_name ALUA state on non"	\
+		       " valid tg_pt_gp ID: %hu\n",			\
+		       t->tg_pt_gp_valid_id);				\
+		return -EINVAL;						\
+	}								\
+									\
+	ret = strict_strtoul(p, 0, &tmp);				\
+	if (ret < 0) {							\
+		pr_err("Invalid value '%s', must be '0' or '1'\n", p);	\
+		return -EINVAL;						\
+	}								\
+	if (tmp > 1) {							\
+		pr_err("Invalid value '%ld', must be '0' or '1'\n", tmp); \
+		return -EINVAL;						\
+	}								\
+	if (!tmp)							\
+		t->_var |= _bit;					\
+	else								\
+		t->_var &= ~_bit;					\
+									\
+	return c;							\
+}
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(transitioning,
+			       tg_pt_gp_alua_supported_states, ALUA_T_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(transitioning,
+				tg_pt_gp_alua_supported_states, ALUA_T_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_transitioning, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(offline,
+			       tg_pt_gp_alua_supported_states, ALUA_O_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(offline,
+				tg_pt_gp_alua_supported_states, ALUA_O_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_offline, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(lba_dependent,
+			       tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(lba_dependent,
+				tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(unavailable,
+			       tg_pt_gp_alua_supported_states, ALUA_U_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(unavailable,
+				tg_pt_gp_alua_supported_states, ALUA_U_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_unavailable, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(standby,
+			       tg_pt_gp_alua_supported_states, ALUA_S_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(standby,
+				tg_pt_gp_alua_supported_states, ALUA_S_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_standby, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(active_optimized,
+			       tg_pt_gp_alua_supported_states, ALUA_AO_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(active_optimized,
+				tg_pt_gp_alua_supported_states, ALUA_AO_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_active_optimized, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(active_nonoptimized,
+			       tg_pt_gp_alua_supported_states, ALUA_AN_SUP);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(active_nonoptimized,
+				tg_pt_gp_alua_supported_states, ALUA_AN_SUP);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_active_nonoptimized, S_IRUGO | S_IWUSR);
 
 /*
  * alua_write_metadata
@@ -2399,7 +2434,13 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
 	&target_core_alua_tg_pt_gp_alua_access_state.attr,
 	&target_core_alua_tg_pt_gp_alua_access_status.attr,
 	&target_core_alua_tg_pt_gp_alua_access_type.attr,
-	&target_core_alua_tg_pt_gp_alua_supported_states.attr,
+	&target_core_alua_tg_pt_gp_alua_support_transitioning.attr,
+	&target_core_alua_tg_pt_gp_alua_support_offline.attr,
+	&target_core_alua_tg_pt_gp_alua_support_lba_dependent.attr,
+	&target_core_alua_tg_pt_gp_alua_support_unavailable.attr,
+	&target_core_alua_tg_pt_gp_alua_support_standby.attr,
+	&target_core_alua_tg_pt_gp_alua_support_active_nonoptimized.attr,
+	&target_core_alua_tg_pt_gp_alua_support_active_optimized.attr,
 	&target_core_alua_tg_pt_gp_alua_write_metadata.attr,
 	&target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
 	&target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/18] target_core_configfs: Verbose ALUA state display
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (5 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 06/18] target_core_configfs: split up ALUA supported states Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 08/18] target_core_configfs: Split up ALUA access type Hannes Reinecke
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Instead of printing out the ALUA state number we should be using
proper strings; this helps administration and reduces confusion.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c     | 18 +++++++++++++++++-
 drivers/target/target_core_alua.h     |  2 ++
 drivers/target/target_core_configfs.c | 24 ++++++++++++++----------
 3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index a16115e..26e3c6d 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -646,7 +646,7 @@ core_alua_check_transition(int state, int *primary)
 	return 0;
 }
 
-static char *core_alua_dump_state(int state)
+char *core_alua_dump_state(int state)
 {
 	switch (state) {
 	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
@@ -666,6 +666,22 @@ static char *core_alua_dump_state(int state)
 	return NULL;
 }
 
+int core_alua_parse_state(const char *state)
+{
+	if (!strncasecmp(state, "Active/Optimized", 16))
+		return ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED;
+	if (!strncasecmp(state, "Active/NonOptimized", 19))
+		return ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED;
+	if (!strncasecmp(state, "Standby", 7))
+		return ALUA_ACCESS_STATE_STANDBY;
+	if (!strncasecmp(state, "Unavailable", 11))
+		return ALUA_ACCESS_STATE_UNAVAILABLE;
+	if (!strncasecmp(state, "Offline", 7))
+		return ALUA_ACCESS_STATE_OFFLINE;
+
+	return -1;
+}
+
 char *core_alua_dump_status(int status)
 {
 	switch (status) {
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index 88e2e83..24ddf85 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -89,6 +89,8 @@ extern int core_alua_check_nonop_delay(struct se_cmd *);
 extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
 				struct se_device *, struct se_port *,
 				struct se_node_acl *, int, int);
+extern char *core_alua_dump_state(int);
+extern int core_alua_parse_state(const char *);
 extern char *core_alua_dump_status(int);
 extern struct t10_alua_lu_gp *core_alua_allocate_lu_gp(const char *, int);
 extern int core_alua_set_lu_gp_id(struct t10_alua_lu_gp *, u16);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 8476f48..dcceecf 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2022,10 +2022,12 @@ static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_state(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	char *page)
 {
-	return sprintf(page, "%d\n",
-		atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state));
+	int state = atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
+
+	return sprintf(page, "%s\n", core_alua_dump_state(state));
 }
 
+
 static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	const char *page,
@@ -2041,20 +2043,22 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 		return -EINVAL;
 	}
 
-	ret = kstrtoul(page, 0, &tmp);
-	if (ret < 0) {
-		pr_err("Unable to extract new ALUA access state from"
-				" %s\n", page);
-		return ret;
-	}
-	new_state = (int)tmp;
-
 	if (!(tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA)) {
 		pr_err("Unable to process implicit configfs ALUA"
 			" transition while TPGS_IMPLICIT_ALUA is disabled\n");
 		return -EINVAL;
 	}
 
+	new_state = core_alua_parse_state(page);
+	if (new_state < 0) {
+		ret = kstrtoul(page, 0, &tmp);
+		if (ret < 0) {
+			pr_err("Unable to extract new ALUA access state from"
+			       " %s\n", page);
+			return ret;
+		}
+		new_state = (int)tmp;
+	}
 	ret = core_alua_do_port_transition(tg_pt_gp, dev,
 					NULL, NULL, new_state, 0);
 	return (!ret) ? count : -EINVAL;
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/18] target_core_configfs: Split up ALUA access type
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (6 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 07/18] target_core_configfs: Verbose ALUA state display Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 09/18] target_core: Rename alua_access_type in alua_mgmt_type Hannes Reinecke
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Instead of lumping two independent values into one attribute
we should be using on attribute per value.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c     | 46 --------------------
 drivers/target/target_core_alua.h     |  3 --
 drivers/target/target_core_configfs.c | 79 +++++++++++++++++------------------
 3 files changed, 38 insertions(+), 90 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 26e3c6d..c4d73a4 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -1754,52 +1754,6 @@ ssize_t core_alua_store_tg_pt_gp_info(
 	return count;
 }
 
-ssize_t core_alua_show_access_type(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	char *page)
-{
-	if ((tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA) &&
-	    (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA))
-		return sprintf(page, "Implicit and Explicit\n");
-	else if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA)
-		return sprintf(page, "Implicit\n");
-	else if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA)
-		return sprintf(page, "Explicit\n");
-	else
-		return sprintf(page, "None\n");
-}
-
-ssize_t core_alua_store_access_type(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	const char *page,
-	size_t count)
-{
-	unsigned long tmp;
-	int ret;
-
-	ret = kstrtoul(page, 0, &tmp);
-	if (ret < 0) {
-		pr_err("Unable to extract alua_access_type\n");
-		return ret;
-	}
-	if ((tmp != 0) && (tmp != 1) && (tmp != 2) && (tmp != 3)) {
-		pr_err("Illegal value for alua_access_type:"
-				" %lu\n", tmp);
-		return -EINVAL;
-	}
-	if (tmp == 3)
-		tg_pt_gp->tg_pt_gp_alua_access_type =
-			TPGS_IMPLICIT_ALUA | TPGS_EXPLICIT_ALUA;
-	else if (tmp == 2)
-		tg_pt_gp->tg_pt_gp_alua_access_type = TPGS_EXPLICIT_ALUA;
-	else if (tmp == 1)
-		tg_pt_gp->tg_pt_gp_alua_access_type = TPGS_IMPLICIT_ALUA;
-	else
-		tg_pt_gp->tg_pt_gp_alua_access_type = 0;
-
-	return count;
-}
-
 ssize_t core_alua_show_nonop_delay_msecs(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	char *page)
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index 24ddf85..03955a9 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -115,9 +115,6 @@ extern void __core_alua_attach_tg_pt_gp_mem(struct t10_alua_tg_pt_gp_member *,
 extern ssize_t core_alua_show_tg_pt_gp_info(struct se_port *, char *);
 extern ssize_t core_alua_store_tg_pt_gp_info(struct se_port *, const char *,
 						size_t);
-extern ssize_t core_alua_show_access_type(struct t10_alua_tg_pt_gp *, char *);
-extern ssize_t core_alua_store_access_type(struct t10_alua_tg_pt_gp *,
-					const char *, size_t);
 extern ssize_t core_alua_show_nonop_delay_msecs(struct t10_alua_tg_pt_gp *,
 						char *);
 extern ssize_t core_alua_store_nonop_delay_msecs(struct t10_alua_tg_pt_gp *,
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index dcceecf..6f01a1e 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2114,39 +2114,15 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
 
 SE_DEV_ALUA_TG_PT_ATTR(alua_access_status, S_IRUGO | S_IWUSR);
 
-/*
- * alua_access_type
- */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_type(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	char *page)
-{
-	return core_alua_show_access_type(tg_pt_gp, page);
-}
-
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	const char *page,
-	size_t count)
-{
-	return core_alua_store_access_type(tg_pt_gp, page, count);
-}
-
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
-
-/*
- * alua_supported_states
- */
-
 #define SE_DEV_ALUA_SUPPORT_STATE_SHOW(_name, _var, _bit)		\
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_support_##_name( \
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_##_name(	\
 	struct t10_alua_tg_pt_gp *t, char *p)				\
 {									\
 	return sprintf(p, "%d\n", !!(t->_var & _bit));			\
 }
 
 #define SE_DEV_ALUA_SUPPORT_STATE_STORE(_name, _var, _bit)		\
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_##_name(	\
 	struct t10_alua_tg_pt_gp *t, const char *p, size_t c)		\
 {									\
 	unsigned long tmp;						\
@@ -2176,45 +2152,65 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
 	return c;							\
 }
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(transitioning,
+/*
+ * alua_access_type
+ */
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(access_implicit,
+			       tg_pt_gp_alua_access_type, TPGS_IMPLICIT_ALUA);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(access_implicit,
+				tg_pt_gp_alua_access_type, TPGS_IMPLICIT_ALUA);
+SE_DEV_ALUA_TG_PT_ATTR(alua_access_implicit, S_IRUGO | S_IWUSR);
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(access_explicit,
+			       tg_pt_gp_alua_access_type, TPGS_EXPLICIT_ALUA);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(access_explicit,
+				tg_pt_gp_alua_access_type, TPGS_EXPLICIT_ALUA);
+SE_DEV_ALUA_TG_PT_ATTR(alua_access_explicit, S_IRUGO | S_IWUSR);
+
+
+/*
+ * alua_supported_states
+ */
+
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_transitioning,
 			       tg_pt_gp_alua_supported_states, ALUA_T_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(transitioning,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_transitioning,
 				tg_pt_gp_alua_supported_states, ALUA_T_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_transitioning, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(offline,
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_offline,
 			       tg_pt_gp_alua_supported_states, ALUA_O_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(offline,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_offline,
 				tg_pt_gp_alua_supported_states, ALUA_O_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_offline, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(lba_dependent,
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_lba_dependent,
 			       tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(lba_dependent,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_lba_dependent,
 				tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(unavailable,
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_unavailable,
 			       tg_pt_gp_alua_supported_states, ALUA_U_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(unavailable,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_unavailable,
 				tg_pt_gp_alua_supported_states, ALUA_U_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_unavailable, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(standby,
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_standby,
 			       tg_pt_gp_alua_supported_states, ALUA_S_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(standby,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_standby,
 				tg_pt_gp_alua_supported_states, ALUA_S_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_standby, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(active_optimized,
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_active_optimized,
 			       tg_pt_gp_alua_supported_states, ALUA_AO_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(active_optimized,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_active_optimized,
 				tg_pt_gp_alua_supported_states, ALUA_AO_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_active_optimized, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(active_nonoptimized,
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_active_nonoptimized,
 			       tg_pt_gp_alua_supported_states, ALUA_AN_SUP);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(active_nonoptimized,
+SE_DEV_ALUA_SUPPORT_STATE_STORE(support_active_nonoptimized,
 				tg_pt_gp_alua_supported_states, ALUA_AN_SUP);
 SE_DEV_ALUA_TG_PT_ATTR(alua_support_active_nonoptimized, S_IRUGO | S_IWUSR);
 
@@ -2437,7 +2433,8 @@ CONFIGFS_EATTR_OPS(target_core_alua_tg_pt_gp, t10_alua_tg_pt_gp,
 static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
 	&target_core_alua_tg_pt_gp_alua_access_state.attr,
 	&target_core_alua_tg_pt_gp_alua_access_status.attr,
-	&target_core_alua_tg_pt_gp_alua_access_type.attr,
+	&target_core_alua_tg_pt_gp_alua_access_implicit.attr,
+	&target_core_alua_tg_pt_gp_alua_access_explicit.attr,
 	&target_core_alua_tg_pt_gp_alua_support_transitioning.attr,
 	&target_core_alua_tg_pt_gp_alua_support_offline.attr,
 	&target_core_alua_tg_pt_gp_alua_support_lba_dependent.attr,
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/18] target_core: Rename alua_access_type in alua_mgmt_type
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (7 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 08/18] target_core_configfs: Split up ALUA access type Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 10/18] target_core: Rename alua_access_status to alua_status_modification Hannes Reinecke
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

'alua_access_type' is not very descriptive and leads to confusion,
so rename it to 'alua_mgmt_type'.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c     | 10 +++++-----
 drivers/target/target_core_alua.h     |  6 +++---
 drivers/target/target_core_configfs.c | 32 ++++++++++++++++----------------
 drivers/target/target_core_spc.c      |  2 +-
 include/target/target_core_base.h     |  2 +-
 5 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index c4d73a4..5540aae 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -246,9 +246,9 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 	}
 	spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
 
-	if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA)) {
-		pr_debug("Unable to process SET_TARGET_PORT_GROUPS"
-				" while TPGS_EXPLICIT_ALUA is disabled\n");
+	if (!(l_tg_pt_gp->tg_pt_gp_alua_mgmt_type & ALUA_MGMT_EXPLICIT)) {
+		pr_debug("Unable to process SET_TARGET_PORT_GROUPS while"
+				" explicit ALUA management is disabled\n");
 		rc = TCM_UNSUPPORTED_SCSI_OPCODE;
 		goto out;
 	}
@@ -1369,8 +1369,8 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
 	/*
 	 * Enable both explicit and implicit ALUA support by default
 	 */
-	tg_pt_gp->tg_pt_gp_alua_access_type =
-			TPGS_EXPLICIT_ALUA | TPGS_IMPLICIT_ALUA;
+	tg_pt_gp->tg_pt_gp_alua_mgmt_type =
+			ALUA_MGMT_EXPLICIT | ALUA_MGMT_IMPLICIT;
 	/*
 	 * Set the default Active/NonOptimized Delay in milliseconds
 	 */
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index 03955a9..299dc33 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -6,9 +6,9 @@
  *
  * from spc4r17 section 6.4.2 Table 135
  */
-#define TPGS_NO_ALUA				0x00
-#define TPGS_IMPLICIT_ALUA			0x10
-#define TPGS_EXPLICIT_ALUA			0x20
+#define ALUA_MGMT_NONE				0x00
+#define ALUA_MGMT_IMPLICIT			0x10
+#define ALUA_MGMT_EXPLICIT			0x20
 
 /*
  * ASYMMETRIC ACCESS STATE field
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 6f01a1e..c16eb87 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2043,9 +2043,9 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 		return -EINVAL;
 	}
 
-	if (!(tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICIT_ALUA)) {
-		pr_err("Unable to process implicit configfs ALUA"
-			" transition while TPGS_IMPLICIT_ALUA is disabled\n");
+	if (!(tg_pt_gp->tg_pt_gp_alua_mgmt_type & ALUA_MGMT_IMPLICIT)) {
+		pr_err("Unable to process implicit configfs ALUA transition"
+			" while implicit ALUA management is disabled\n");
 		return -EINVAL;
 	}
 
@@ -2153,19 +2153,19 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_##_name(	\
 }
 
 /*
- * alua_access_type
+ * alua_mgmt_type
  */
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(access_implicit,
-			       tg_pt_gp_alua_access_type, TPGS_IMPLICIT_ALUA);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(access_implicit,
-				tg_pt_gp_alua_access_type, TPGS_IMPLICIT_ALUA);
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_implicit, S_IRUGO | S_IWUSR);
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(management_implicit,
+			       tg_pt_gp_alua_mgmt_type, ALUA_MGMT_IMPLICIT);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(management_implicit,
+				tg_pt_gp_alua_mgmt_type, ALUA_MGMT_IMPLICIT);
+SE_DEV_ALUA_TG_PT_ATTR(alua_management_implicit, S_IRUGO | S_IWUSR);
 
-SE_DEV_ALUA_SUPPORT_STATE_SHOW(access_explicit,
-			       tg_pt_gp_alua_access_type, TPGS_EXPLICIT_ALUA);
-SE_DEV_ALUA_SUPPORT_STATE_STORE(access_explicit,
-				tg_pt_gp_alua_access_type, TPGS_EXPLICIT_ALUA);
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_explicit, S_IRUGO | S_IWUSR);
+SE_DEV_ALUA_SUPPORT_STATE_SHOW(management_explicit,
+			       tg_pt_gp_alua_mgmt_type, ALUA_MGMT_EXPLICIT);
+SE_DEV_ALUA_SUPPORT_STATE_STORE(management_explicit,
+				tg_pt_gp_alua_mgmt_type, ALUA_MGMT_EXPLICIT);
+SE_DEV_ALUA_TG_PT_ATTR(alua_management_explicit, S_IRUGO | S_IWUSR);
 
 
 /*
@@ -2433,8 +2433,8 @@ CONFIGFS_EATTR_OPS(target_core_alua_tg_pt_gp, t10_alua_tg_pt_gp,
 static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
 	&target_core_alua_tg_pt_gp_alua_access_state.attr,
 	&target_core_alua_tg_pt_gp_alua_access_status.attr,
-	&target_core_alua_tg_pt_gp_alua_access_implicit.attr,
-	&target_core_alua_tg_pt_gp_alua_access_explicit.attr,
+	&target_core_alua_tg_pt_gp_alua_management_implicit.attr,
+	&target_core_alua_tg_pt_gp_alua_management_explicit.attr,
 	&target_core_alua_tg_pt_gp_alua_support_transitioning.attr,
 	&target_core_alua_tg_pt_gp_alua_support_offline.attr,
 	&target_core_alua_tg_pt_gp_alua_support_lba_dependent.attr,
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 021c3f4..49947f3 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -62,7 +62,7 @@ static void spc_fill_alua_data(struct se_port *port, unsigned char *buf)
 	spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 	tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
 	if (tg_pt_gp)
-		buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
+		buf[5] |= tg_pt_gp->tg_pt_gp_alua_mgmt_type;
 	spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 }
 
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index a23785f..e3e334d 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -285,7 +285,7 @@ struct t10_alua_tg_pt_gp {
 	int	tg_pt_gp_valid_id;
 	int	tg_pt_gp_alua_supported_states;
 	int	tg_pt_gp_alua_access_status;
-	int	tg_pt_gp_alua_access_type;
+	int	tg_pt_gp_alua_mgmt_type;
 	int	tg_pt_gp_nonop_delay_msecs;
 	int	tg_pt_gp_trans_delay_msecs;
 	int	tg_pt_gp_implicit_trans_secs;
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/18] target_core: Rename alua_access_status to alua_status_modification
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (8 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 09/18] target_core: Rename alua_access_type in alua_mgmt_type Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 11/18] target_core_alua: Validate ALUA state transition Hannes Reinecke
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

It is utterly confusing to have an attribute 'alua_access_state'
and another one 'alua_access_status'. So rename the latter to
'alua_status_modification' to avoid the confusion and better
reflect that actual usage.

Signed-off-by: Hannes Reiencke <hare@suse.de>
---
 drivers/target/target_core_alua.c     | 10 +++++-----
 drivers/target/target_core_configfs.c | 14 +++++++-------
 include/target/target_core_base.h     |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 5540aae..661ee1b 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -128,7 +128,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
 		/*
 		 * STATUS CODE
 		 */
-		buf[off++] = (tg_pt_gp->tg_pt_gp_alua_access_status & 0xff);
+		buf[off++] = (tg_pt_gp->tg_pt_gp_alua_status_modification & 0xff);
 		/*
 		 * Vendor Specific field
 		 */
@@ -764,9 +764,9 @@ static int core_alua_update_tpg_primary_metadata(
 	len = snprintf(md_buf, tg_pt_gp->tg_pt_gp_md_buf_len,
 			"tg_pt_gp_id=%hu\n"
 			"alua_access_state=0x%02x\n"
-			"alua_access_status=0x%02x\n",
+			"alua_status_modification=0x%02x\n",
 			tg_pt_gp->tg_pt_gp_id, primary_state,
-			tg_pt_gp->tg_pt_gp_alua_access_status);
+			tg_pt_gp->tg_pt_gp_alua_status_modification);
 
 	snprintf(path, ALUA_METADATA_PATH_LEN,
 		"/var/target/alua/tpgs_%s/%s", &wwn->unit_serial[0],
@@ -795,7 +795,7 @@ static int core_alua_do_transition_tg_pt(
 	old_state = atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 			ALUA_ACCESS_STATE_TRANSITION);
-	tg_pt_gp->tg_pt_gp_alua_access_status = (explicit) ?
+	tg_pt_gp->tg_pt_gp_alua_status_modification = (explicit) ?
 				ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
 				ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
 	/*
@@ -1653,7 +1653,7 @@ ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page)
 			core_alua_dump_state(atomic_read(
 					&tg_pt_gp->tg_pt_gp_alua_access_state)),
 			core_alua_dump_status(
-				tg_pt_gp->tg_pt_gp_alua_access_status),
+				tg_pt_gp->tg_pt_gp_alua_status_modification),
 			(atomic_read(&port->sep_tg_pt_secondary_offline)) ?
 			"Offline" : "None",
 			core_alua_dump_status(port->sep_tg_pt_secondary_stat));
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index c16eb87..9ba6828 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2067,17 +2067,17 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 SE_DEV_ALUA_TG_PT_ATTR(alua_access_state, S_IRUGO | S_IWUSR);
 
 /*
- * alua_access_status
+ * alua_status_modification
  */
-static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_status(
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_status_modification(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	char *page)
 {
 	return sprintf(page, "%s\n",
-		core_alua_dump_status(tg_pt_gp->tg_pt_gp_alua_access_status));
+		core_alua_dump_status(tg_pt_gp->tg_pt_gp_alua_status_modification));
 }
 
-static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_status_modification(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	const char *page,
 	size_t count)
@@ -2108,11 +2108,11 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
 		return -EINVAL;
 	}
 
-	tg_pt_gp->tg_pt_gp_alua_access_status = new_status;
+	tg_pt_gp->tg_pt_gp_alua_status_modification = new_status;
 	return count;
 }
 
-SE_DEV_ALUA_TG_PT_ATTR(alua_access_status, S_IRUGO | S_IWUSR);
+SE_DEV_ALUA_TG_PT_ATTR(alua_status_modification, S_IRUGO | S_IWUSR);
 
 #define SE_DEV_ALUA_SUPPORT_STATE_SHOW(_name, _var, _bit)		\
 static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_##_name(	\
@@ -2432,7 +2432,7 @@ CONFIGFS_EATTR_OPS(target_core_alua_tg_pt_gp, t10_alua_tg_pt_gp,
 
 static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
 	&target_core_alua_tg_pt_gp_alua_access_state.attr,
-	&target_core_alua_tg_pt_gp_alua_access_status.attr,
+	&target_core_alua_tg_pt_gp_alua_status_modification.attr,
 	&target_core_alua_tg_pt_gp_alua_management_implicit.attr,
 	&target_core_alua_tg_pt_gp_alua_management_explicit.attr,
 	&target_core_alua_tg_pt_gp_alua_support_transitioning.attr,
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index e3e334d..6944c75 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -284,7 +284,7 @@ struct t10_alua_tg_pt_gp {
 	u16	tg_pt_gp_id;
 	int	tg_pt_gp_valid_id;
 	int	tg_pt_gp_alua_supported_states;
-	int	tg_pt_gp_alua_access_status;
+	int	tg_pt_gp_alua_status_modification;
 	int	tg_pt_gp_alua_mgmt_type;
 	int	tg_pt_gp_nonop_delay_msecs;
 	int	tg_pt_gp_trans_delay_msecs;
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/18] target_core_alua: Validate ALUA state transition
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (9 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 10/18] target_core: Rename alua_access_status to alua_status_modification Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 12/18] target_core_alua: Allocate ALUA metadata on demand Hannes Reinecke
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

As we now can modify the list of supported states we need to
validate the requested ALUA state when doing a state transition.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 117 +++++++++++++++++++++++---------------
 1 file changed, 72 insertions(+), 45 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 661ee1b..2e7110a 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -41,7 +41,8 @@
 #include "target_core_alua.h"
 #include "target_core_ua.h"
 
-static sense_reason_t core_alua_check_transition(int state, int *primary);
+static sense_reason_t core_alua_check_transition(int state, int valid,
+						 int *primary);
 static int core_alua_set_tg_pt_secondary_state(
 		struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
 		struct se_port *port, int explicit, int offline);
@@ -210,7 +211,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 	unsigned char *ptr;
 	sense_reason_t rc = TCM_NO_SENSE;
 	u32 len = 4; /* Skip over RESERVED area in header */
-	int alua_access_state, primary = 0;
+	int alua_access_state, primary = 0, valid_states;
 	u16 tg_pt_id, rtpi;
 
 	if (!l_port)
@@ -252,6 +253,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 		rc = TCM_UNSUPPORTED_SCSI_OPCODE;
 		goto out;
 	}
+	valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states;
 
 	ptr = &buf[4]; /* Skip over RESERVED area in header */
 
@@ -263,7 +265,8 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 		 * the state is a primary or secondary target port asymmetric
 		 * access state.
 		 */
-		rc = core_alua_check_transition(alua_access_state, &primary);
+		rc = core_alua_check_transition(alua_access_state,
+						valid_states, &primary);
 		if (rc) {
 			/*
 			 * If the SET TARGET PORT GROUPS attempts to establish
@@ -614,36 +617,20 @@ out:
 	return 0;
 }
 
-/*
- * Check implicit and explicit ALUA state change request.
- */
-static sense_reason_t
-core_alua_check_transition(int state, int *primary)
+int core_alua_parse_state(const char *state)
 {
-	switch (state) {
-	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
-	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
-	case ALUA_ACCESS_STATE_STANDBY:
-	case ALUA_ACCESS_STATE_UNAVAILABLE:
-		/*
-		 * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
-		 * defined as primary target port asymmetric access states.
-		 */
-		*primary = 1;
-		break;
-	case ALUA_ACCESS_STATE_OFFLINE:
-		/*
-		 * OFFLINE state is defined as a secondary target port
-		 * asymmetric access state.
-		 */
-		*primary = 0;
-		break;
-	default:
-		pr_err("Unknown ALUA access state: 0x%02x\n", state);
-		return TCM_INVALID_PARAMETER_LIST;
-	}
+	if (!strncasecmp(state, "Active/Optimized", 16))
+		return ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED;
+	if (!strncasecmp(state, "Active/NonOptimized", 19))
+		return ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED;
+	if (!strncasecmp(state, "Standby", 7))
+		return ALUA_ACCESS_STATE_STANDBY;
+	if (!strncasecmp(state, "Unavailable", 11))
+		return ALUA_ACCESS_STATE_UNAVAILABLE;
+	if (!strncasecmp(state, "Offline", 7))
+		return ALUA_ACCESS_STATE_OFFLINE;
 
-	return 0;
+	return -1;
 }
 
 char *core_alua_dump_state(int state)
@@ -659,6 +646,8 @@ char *core_alua_dump_state(int state)
 		return "Unavailable";
 	case ALUA_ACCESS_STATE_OFFLINE:
 		return "Offline";
+	case ALUA_ACCESS_STATE_TRANSITION:
+		return "Transitioning";
 	default:
 		return "Unknown";
 	}
@@ -666,20 +655,57 @@ char *core_alua_dump_state(int state)
 	return NULL;
 }
 
-int core_alua_parse_state(const char *state)
+/*
+ * Check implicit and explicit ALUA state change request.
+ */
+static sense_reason_t
+core_alua_check_transition(int state, int valid, int *primary)
 {
-	if (!strncasecmp(state, "Active/Optimized", 16))
-		return ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED;
-	if (!strncasecmp(state, "Active/NonOptimized", 19))
-		return ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED;
-	if (!strncasecmp(state, "Standby", 7))
-		return ALUA_ACCESS_STATE_STANDBY;
-	if (!strncasecmp(state, "Unavailable", 11))
-		return ALUA_ACCESS_STATE_UNAVAILABLE;
-	if (!strncasecmp(state, "Offline", 7))
-		return ALUA_ACCESS_STATE_OFFLINE;
+	/*
+	 * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
+	 * defined as primary target port asymmetric access states.
+	 */
+	switch (state) {
+	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
+		if (!(valid & ALUA_AO_SUP))
+			goto not_supported;
+		*primary = 1;
+		break;
+	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
+		if (!(valid & ALUA_AN_SUP))
+			goto not_supported;
+		*primary = 1;
+		break;
+	case ALUA_ACCESS_STATE_STANDBY:
+		if (!(valid & ALUA_S_SUP))
+			goto not_supported;
+		*primary = 1;
+		break;
+	case ALUA_ACCESS_STATE_UNAVAILABLE:
+		if (!(valid & ALUA_U_SUP))
+			goto not_supported;
+		*primary = 1;
+		break;
+	case ALUA_ACCESS_STATE_OFFLINE:
+		/*
+		 * OFFLINE state is defined as a secondary target port
+		 * asymmetric access state.
+		 */
+		if (!(valid & ALUA_O_SUP))
+			goto not_supported;
+		*primary = 0;
+		break;
+	default:
+		pr_err("Unknown ALUA access state: 0x%02x\n", state);
+		return TCM_INVALID_PARAMETER_LIST;
+	}
 
-	return -1;
+	return 0;
+
+not_supported:
+	pr_err("ALUA access state %s not supported",
+	       core_alua_dump_state(state));
+	return TCM_INVALID_PARAMETER_LIST;
 }
 
 char *core_alua_dump_status(int status)
@@ -900,9 +926,10 @@ int core_alua_do_port_transition(
 	struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	unsigned char *md_buf;
-	int primary;
+	int primary, valid_states;
 
-	if (core_alua_check_transition(new_state, &primary) != 0)
+	valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states;
+	if (core_alua_check_transition(new_state, valid_states, &primary) != 0)
 		return -EINVAL;
 
 	md_buf = kzalloc(l_tg_pt_gp->tg_pt_gp_md_buf_len, GFP_KERNEL);
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/18] target_core_alua: Allocate ALUA metadata on demand
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (10 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 11/18] target_core_alua: Validate ALUA state transition Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 13/18] target_core_alua: store old and pending ALUA state Hannes Reinecke
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

We should only allocate ALUA metadata if we're actually going
to write them.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 70 +++++++++++++++++----------------------
 drivers/target/target_core_alua.h |  3 ++
 include/target/target_core_base.h |  3 --
 3 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 2e7110a..3fa535c 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -778,16 +778,22 @@ static int core_alua_write_tpg_metadata(
  */
 static int core_alua_update_tpg_primary_metadata(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	int primary_state,
-	unsigned char *md_buf)
+	int primary_state)
 {
+	unsigned char *md_buf;
 	struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn;
 	char path[ALUA_METADATA_PATH_LEN];
-	int len;
+	int len, rc;
+
+	md_buf = kzalloc(ALUA_MD_BUF_LEN, GFP_KERNEL);
+	if (!md_buf) {
+		pr_err("Unable to allocate buf for ALUA metadata\n");
+		return -ENOMEM;
+	}
 
 	memset(path, 0, ALUA_METADATA_PATH_LEN);
 
-	len = snprintf(md_buf, tg_pt_gp->tg_pt_gp_md_buf_len,
+	len = snprintf(md_buf, ALUA_MD_BUF_LEN,
 			"tg_pt_gp_id=%hu\n"
 			"alua_access_state=0x%02x\n"
 			"alua_status_modification=0x%02x\n",
@@ -798,14 +804,15 @@ static int core_alua_update_tpg_primary_metadata(
 		"/var/target/alua/tpgs_%s/%s", &wwn->unit_serial[0],
 		config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item));
 
-	return core_alua_write_tpg_metadata(path, md_buf, len);
+	rc = core_alua_write_tpg_metadata(path, md_buf, len);
+	kfree(md_buf);
+	return rc;
 }
 
 static int core_alua_do_transition_tg_pt(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	struct se_port *l_port,
 	struct se_node_acl *nacl,
-	unsigned char *md_buf,
 	int new_state,
 	int explicit)
 {
@@ -893,8 +900,7 @@ static int core_alua_do_transition_tg_pt(
 	 */
 	if (tg_pt_gp->tg_pt_gp_write_metadata) {
 		mutex_lock(&tg_pt_gp->tg_pt_gp_md_mutex);
-		core_alua_update_tpg_primary_metadata(tg_pt_gp,
-					new_state, md_buf);
+		core_alua_update_tpg_primary_metadata(tg_pt_gp, new_state);
 		mutex_unlock(&tg_pt_gp->tg_pt_gp_md_mutex);
 	}
 	/*
@@ -925,19 +931,12 @@ int core_alua_do_port_transition(
 	struct t10_alua_lu_gp *lu_gp;
 	struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
-	unsigned char *md_buf;
 	int primary, valid_states;
 
 	valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states;
 	if (core_alua_check_transition(new_state, valid_states, &primary) != 0)
 		return -EINVAL;
 
-	md_buf = kzalloc(l_tg_pt_gp->tg_pt_gp_md_buf_len, GFP_KERNEL);
-	if (!md_buf) {
-		pr_err("Unable to allocate buf for ALUA metadata\n");
-		return -ENOMEM;
-	}
-
 	local_lu_gp_mem = l_dev->dev_alua_lu_gp_mem;
 	spin_lock(&local_lu_gp_mem->lu_gp_mem_lock);
 	lu_gp = local_lu_gp_mem->lu_gp;
@@ -955,10 +954,9 @@ int core_alua_do_port_transition(
 		 * success.
 		 */
 		core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl,
-					md_buf, new_state, explicit);
+					new_state, explicit);
 		atomic_dec(&lu_gp->lu_gp_ref_cnt);
 		smp_mb__after_atomic_dec();
-		kfree(md_buf);
 		return 0;
 	}
 	/*
@@ -1008,7 +1006,7 @@ int core_alua_do_port_transition(
 			 * success.
 			 */
 			core_alua_do_transition_tg_pt(tg_pt_gp, port,
-					nacl, md_buf, new_state, explicit);
+					nacl, new_state, explicit);
 
 			spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 			atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
@@ -1030,7 +1028,6 @@ int core_alua_do_port_transition(
 
 	atomic_dec(&lu_gp->lu_gp_ref_cnt);
 	smp_mb__after_atomic_dec();
-	kfree(md_buf);
 	return 0;
 }
 
@@ -1039,13 +1036,18 @@ int core_alua_do_port_transition(
  */
 static int core_alua_update_tpg_secondary_metadata(
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
-	struct se_port *port,
-	unsigned char *md_buf,
-	u32 md_buf_len)
+	struct se_port *port)
 {
+	unsigned char *md_buf;
 	struct se_portal_group *se_tpg = port->sep_tpg;
 	char path[ALUA_METADATA_PATH_LEN], wwn[ALUA_SECONDARY_METADATA_WWN_LEN];
-	int len;
+	int len, rc;
+
+	md_buf = kzalloc(ALUA_MD_BUF_LEN, GFP_KERNEL);
+	if (!md_buf) {
+		pr_err("Unable to allocate buf for ALUA metadata\n");
+		return -ENOMEM;
+	}
 
 	memset(path, 0, ALUA_METADATA_PATH_LEN);
 	memset(wwn, 0, ALUA_SECONDARY_METADATA_WWN_LEN);
@@ -1057,7 +1059,7 @@ static int core_alua_update_tpg_secondary_metadata(
 		snprintf(wwn+len, ALUA_SECONDARY_METADATA_WWN_LEN-len, "+%hu",
 				se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg));
 
-	len = snprintf(md_buf, md_buf_len, "alua_tg_pt_offline=%d\n"
+	len = snprintf(md_buf, ALUA_MD_BUF_LEN, "alua_tg_pt_offline=%d\n"
 			"alua_tg_pt_status=0x%02x\n",
 			atomic_read(&port->sep_tg_pt_secondary_offline),
 			port->sep_tg_pt_secondary_stat);
@@ -1066,7 +1068,10 @@ static int core_alua_update_tpg_secondary_metadata(
 			se_tpg->se_tpg_tfo->get_fabric_name(), wwn,
 			port->sep_lun->unpacked_lun);
 
-	return core_alua_write_tpg_metadata(path, md_buf, len);
+	rc = core_alua_write_tpg_metadata(path, md_buf, len);
+	kfree(md_buf);
+
+	return rc;
 }
 
 static int core_alua_set_tg_pt_secondary_state(
@@ -1076,8 +1081,6 @@ static int core_alua_set_tg_pt_secondary_state(
 	int offline)
 {
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
-	unsigned char *md_buf;
-	u32 md_buf_len;
 	int trans_delay_msecs;
 
 	spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -1098,7 +1101,6 @@ static int core_alua_set_tg_pt_secondary_state(
 	else
 		atomic_set(&port->sep_tg_pt_secondary_offline, 0);
 
-	md_buf_len = tg_pt_gp->tg_pt_gp_md_buf_len;
 	port->sep_tg_pt_secondary_stat = (explicit) ?
 			ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
 			ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
@@ -1120,18 +1122,9 @@ static int core_alua_set_tg_pt_secondary_state(
 	 * secondary state and status
 	 */
 	if (port->sep_tg_pt_secondary_write_md) {
-		md_buf = kzalloc(md_buf_len, GFP_KERNEL);
-		if (!md_buf) {
-			pr_err("Unable to allocate md_buf for"
-				" secondary ALUA access metadata\n");
-			return -ENOMEM;
-		}
 		mutex_lock(&port->sep_tg_pt_md_mutex);
-		core_alua_update_tpg_secondary_metadata(tg_pt_gp_mem, port,
-				md_buf, md_buf_len);
+		core_alua_update_tpg_secondary_metadata(tg_pt_gp_mem, port);
 		mutex_unlock(&port->sep_tg_pt_md_mutex);
-
-		kfree(md_buf);
 	}
 
 	return 0;
@@ -1390,7 +1383,6 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
 	spin_lock_init(&tg_pt_gp->tg_pt_gp_lock);
 	atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0);
 	tg_pt_gp->tg_pt_gp_dev = dev;
-	tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN;
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 		ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED);
 	/*
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index 299dc33..f2c1ef3 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -78,6 +78,9 @@
  */
 #define ALUA_SECONDARY_METADATA_WWN_LEN			256
 
+/* Used by core_alua_update_tpg_(primary,secondary)_metadata */
+#define ALUA_MD_BUF_LEN					1024
+
 extern struct kmem_cache *t10_alua_lu_gp_cache;
 extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
 extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 6944c75..faf7de0 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -291,9 +291,6 @@ struct t10_alua_tg_pt_gp {
 	int	tg_pt_gp_implicit_trans_secs;
 	int	tg_pt_gp_pref;
 	int	tg_pt_gp_write_metadata;
-	/* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */
-#define ALUA_MD_BUF_LEN				1024
-	u32	tg_pt_gp_md_buf_len;
 	u32	tg_pt_gp_members;
 	atomic_t tg_pt_gp_alua_access_state;
 	atomic_t tg_pt_gp_ref_cnt;
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/18] target_core_alua: store old and pending ALUA state
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (11 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 12/18] target_core_alua: Allocate ALUA metadata on demand Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:07 ` [PATCH 14/18] target_core_alua: Use workqueue for ALUA transitioning Hannes Reinecke
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

During state transition we should be storing both the original
and the pending state.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 15 ++++++++++-----
 include/target/target_core_base.h |  6 ++++--
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 3fa535c..5de2ea1 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -820,12 +820,15 @@ static int core_alua_do_transition_tg_pt(
 	struct se_lun_acl *lacl;
 	struct se_port *port;
 	struct t10_alua_tg_pt_gp_member *mem;
-	int old_state = 0;
+
 	/*
 	 * Save the old primary ALUA access state, and set the current state
 	 * to ALUA_ACCESS_STATE_TRANSITION.
 	 */
-	old_state = atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
+	tg_pt_gp->tg_pt_gp_alua_previous_state =
+		atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
+	tg_pt_gp->tg_pt_gp_alua_pending_state = new_state;
+
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 			ALUA_ACCESS_STATE_TRANSITION);
 	tg_pt_gp->tg_pt_gp_alua_status_modification = (explicit) ?
@@ -906,13 +909,15 @@ static int core_alua_do_transition_tg_pt(
 	/*
 	 * Set the current primary ALUA access state to the requested new state
 	 */
-	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, new_state);
+	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
+		   tg_pt_gp->tg_pt_gp_alua_pending_state);
 
 	pr_debug("Successful %s ALUA transition TG PT Group: %s ID: %hu"
 		" from primary access state %s to %s\n", (explicit) ? "explicit" :
 		"implicit", config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item),
-		tg_pt_gp->tg_pt_gp_id, core_alua_dump_state(old_state),
-		core_alua_dump_state(new_state));
+		tg_pt_gp->tg_pt_gp_id,
+		core_alua_dump_state(tg_pt_gp->tg_pt_gp_alua_previous_state),
+		core_alua_dump_state(tg_pt_gp->tg_pt_gp_alua_pending_state));
 
 	return 0;
 }
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index faf7de0..b8b7ec8 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -283,8 +283,10 @@ struct t10_alua_lu_gp_member {
 struct t10_alua_tg_pt_gp {
 	u16	tg_pt_gp_id;
 	int	tg_pt_gp_valid_id;
-	int	tg_pt_gp_alua_supported_states;
-	int	tg_pt_gp_alua_status_modification;
+	u8	tg_pt_gp_alua_pending_state;
+	u8	tg_pt_gp_alua_previous_state;
+	u8	tg_pt_gp_alua_supported_states;
+	u8	tg_pt_gp_alua_status_modification;
 	int	tg_pt_gp_alua_mgmt_type;
 	int	tg_pt_gp_nonop_delay_msecs;
 	int	tg_pt_gp_trans_delay_msecs;
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 14/18] target_core_alua: Use workqueue for ALUA transitioning
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (12 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 13/18] target_core_alua: store old and pending ALUA state Hannes Reinecke
@ 2013-11-19  8:07 ` Hannes Reinecke
  2013-11-19  8:08 ` [PATCH 15/18] target_core: simplify scsi_name_len calculation Hannes Reinecke
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:07 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Use a workqueue for processing ALUA state transitions; this allows
us to process implicit delay properly.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c | 174 +++++++++++++++++++++++++++-----------
 include/target/target_core_base.h |   4 +
 2 files changed, 128 insertions(+), 50 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 5de2ea1..19179cf 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -777,8 +777,7 @@ static int core_alua_write_tpg_metadata(
  * Called with tg_pt_gp->tg_pt_gp_md_mutex held
  */
 static int core_alua_update_tpg_primary_metadata(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	int primary_state)
+	struct t10_alua_tg_pt_gp *tg_pt_gp)
 {
 	unsigned char *md_buf;
 	struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn;
@@ -797,7 +796,8 @@ static int core_alua_update_tpg_primary_metadata(
 			"tg_pt_gp_id=%hu\n"
 			"alua_access_state=0x%02x\n"
 			"alua_status_modification=0x%02x\n",
-			tg_pt_gp->tg_pt_gp_id, primary_state,
+			tg_pt_gp->tg_pt_gp_id,
+			tg_pt_gp->tg_pt_gp_alua_pending_state,
 			tg_pt_gp->tg_pt_gp_alua_status_modification);
 
 	snprintf(path, ALUA_METADATA_PATH_LEN,
@@ -809,36 +809,17 @@ static int core_alua_update_tpg_primary_metadata(
 	return rc;
 }
 
-static int core_alua_do_transition_tg_pt(
-	struct t10_alua_tg_pt_gp *tg_pt_gp,
-	struct se_port *l_port,
-	struct se_node_acl *nacl,
-	int new_state,
-	int explicit)
+static void core_alua_do_transition_tg_pt_work(struct work_struct *work)
 {
+	struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(work,
+		struct t10_alua_tg_pt_gp, tg_pt_gp_transition_work.work);
+	struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
 	struct se_dev_entry *se_deve;
 	struct se_lun_acl *lacl;
 	struct se_port *port;
 	struct t10_alua_tg_pt_gp_member *mem;
-
-	/*
-	 * Save the old primary ALUA access state, and set the current state
-	 * to ALUA_ACCESS_STATE_TRANSITION.
-	 */
-	tg_pt_gp->tg_pt_gp_alua_previous_state =
-		atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
-	tg_pt_gp->tg_pt_gp_alua_pending_state = new_state;
-
-	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
-			ALUA_ACCESS_STATE_TRANSITION);
-	tg_pt_gp->tg_pt_gp_alua_status_modification = (explicit) ?
-				ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
-				ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
-	/*
-	 * Check for the optional ALUA primary state transition delay
-	 */
-	if (tg_pt_gp->tg_pt_gp_trans_delay_msecs != 0)
-		msleep_interruptible(tg_pt_gp->tg_pt_gp_trans_delay_msecs);
+	bool explicit = (tg_pt_gp->tg_pt_gp_alua_status_modification ==
+			 ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG);
 
 	spin_lock(&tg_pt_gp->tg_pt_gp_lock);
 	list_for_each_entry(mem, &tg_pt_gp->tg_pt_gp_mem_list,
@@ -873,9 +854,12 @@ static int core_alua_do_transition_tg_pt(
 			if (!lacl)
 				continue;
 
-			if (explicit &&
-			   (nacl != NULL) && (nacl == lacl->se_lun_nacl) &&
-			   (l_port != NULL) && (l_port == port))
+			if ((tg_pt_gp->tg_pt_gp_alua_status_modification ==
+			     ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG) &&
+			   (tg_pt_gp->tg_pt_gp_alua_nacl != NULL) &&
+			    (tg_pt_gp->tg_pt_gp_alua_nacl == lacl->se_lun_nacl) &&
+			   (tg_pt_gp->tg_pt_gp_alua_port != NULL) &&
+			    (tg_pt_gp->tg_pt_gp_alua_port == port))
 				continue;
 
 			core_scsi3_ua_allocate(lacl->se_lun_nacl,
@@ -903,7 +887,7 @@ static int core_alua_do_transition_tg_pt(
 	 */
 	if (tg_pt_gp->tg_pt_gp_write_metadata) {
 		mutex_lock(&tg_pt_gp->tg_pt_gp_md_mutex);
-		core_alua_update_tpg_primary_metadata(tg_pt_gp, new_state);
+		core_alua_update_tpg_primary_metadata(tg_pt_gp);
 		mutex_unlock(&tg_pt_gp->tg_pt_gp_md_mutex);
 	}
 	/*
@@ -918,6 +902,87 @@ static int core_alua_do_transition_tg_pt(
 		tg_pt_gp->tg_pt_gp_id,
 		core_alua_dump_state(tg_pt_gp->tg_pt_gp_alua_previous_state),
 		core_alua_dump_state(tg_pt_gp->tg_pt_gp_alua_pending_state));
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+	atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
+	smp_mb__after_atomic_dec();
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
+
+	if (tg_pt_gp->tg_pt_gp_transition_complete)
+		complete(tg_pt_gp->tg_pt_gp_transition_complete);
+}
+
+static int core_alua_do_transition_tg_pt(
+	struct t10_alua_tg_pt_gp *tg_pt_gp,
+	int new_state,
+	int explicit)
+{
+	struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
+	DECLARE_COMPLETION_ONSTACK(wait);
+
+	/* Nothing to be done here */
+	if (atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) == new_state)
+		return 0;
+
+	if (new_state == ALUA_ACCESS_STATE_TRANSITION)
+		return -EAGAIN;
+
+	/*
+	 * Flush any pending transitions
+	 */
+	if (!explicit && tg_pt_gp->tg_pt_gp_implicit_trans_secs &&
+	    atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) ==
+	    ALUA_ACCESS_STATE_TRANSITION) {
+		/* Just in case */
+		tg_pt_gp->tg_pt_gp_alua_pending_state = new_state;
+		tg_pt_gp->tg_pt_gp_transition_complete = &wait;
+		flush_delayed_work(&tg_pt_gp->tg_pt_gp_transition_work);
+		wait_for_completion(&wait);
+		tg_pt_gp->tg_pt_gp_transition_complete = NULL;
+		return 0;
+	}
+
+	/*
+	 * Save the old primary ALUA access state, and set the current state
+	 * to ALUA_ACCESS_STATE_TRANSITION.
+	 */
+	tg_pt_gp->tg_pt_gp_alua_previous_state =
+		atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state);
+	tg_pt_gp->tg_pt_gp_alua_pending_state = new_state;
+
+	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
+			ALUA_ACCESS_STATE_TRANSITION);
+	tg_pt_gp->tg_pt_gp_alua_status_modification = (explicit) ?
+				ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
+				ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
+
+	/*
+	 * Check for the optional ALUA primary state transition delay
+	 */
+	if (tg_pt_gp->tg_pt_gp_trans_delay_msecs != 0)
+		msleep_interruptible(tg_pt_gp->tg_pt_gp_trans_delay_msecs);
+
+	/*
+	 * Take a reference for workqueue item
+	 */
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+	atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
+	smp_mb__after_atomic_inc();
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
+
+	if (!explicit && tg_pt_gp->tg_pt_gp_implicit_trans_secs) {
+		unsigned long transition_tmo;
+
+		transition_tmo = tg_pt_gp->tg_pt_gp_implicit_trans_secs * HZ;
+		queue_delayed_work(tg_pt_gp->tg_pt_gp_dev->tmr_wq,
+				   &tg_pt_gp->tg_pt_gp_transition_work,
+				   transition_tmo);
+	} else {
+		tg_pt_gp->tg_pt_gp_transition_complete = &wait;
+		queue_delayed_work(tg_pt_gp->tg_pt_gp_dev->tmr_wq,
+				   &tg_pt_gp->tg_pt_gp_transition_work, 0);
+		wait_for_completion(&wait);
+		tg_pt_gp->tg_pt_gp_transition_complete = NULL;
+	}
 
 	return 0;
 }
@@ -931,12 +996,10 @@ int core_alua_do_port_transition(
 	int explicit)
 {
 	struct se_device *dev;
-	struct se_port *port;
-	struct se_node_acl *nacl;
 	struct t10_alua_lu_gp *lu_gp;
 	struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
-	int primary, valid_states;
+	int primary, valid_states, rc = 0;
 
 	valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states;
 	if (core_alua_check_transition(new_state, valid_states, &primary) != 0)
@@ -958,11 +1021,13 @@ int core_alua_do_port_transition(
 		 * core_alua_do_transition_tg_pt() will always return
 		 * success.
 		 */
-		core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl,
-					new_state, explicit);
+		l_tg_pt_gp->tg_pt_gp_alua_port = l_port;
+		l_tg_pt_gp->tg_pt_gp_alua_nacl = l_nacl;
+		rc = core_alua_do_transition_tg_pt(l_tg_pt_gp,
+						   new_state, explicit);
 		atomic_dec(&lu_gp->lu_gp_ref_cnt);
 		smp_mb__after_atomic_dec();
-		return 0;
+		return rc;
 	}
 	/*
 	 * For all other LU groups aside from 'default_lu_gp', walk all of
@@ -997,11 +1062,11 @@ int core_alua_do_port_transition(
 				continue;
 
 			if (l_tg_pt_gp == tg_pt_gp) {
-				port = l_port;
-				nacl = l_nacl;
+				tg_pt_gp->tg_pt_gp_alua_port = l_port;
+				tg_pt_gp->tg_pt_gp_alua_nacl = l_nacl;
 			} else {
-				port = NULL;
-				nacl = NULL;
+				tg_pt_gp->tg_pt_gp_alua_port = NULL;
+				tg_pt_gp->tg_pt_gp_alua_nacl = NULL;
 			}
 			atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
 			smp_mb__after_atomic_inc();
@@ -1010,12 +1075,14 @@ int core_alua_do_port_transition(
 			 * core_alua_do_transition_tg_pt() will always return
 			 * success.
 			 */
-			core_alua_do_transition_tg_pt(tg_pt_gp, port,
-					nacl, new_state, explicit);
+			rc = core_alua_do_transition_tg_pt(tg_pt_gp,
+					new_state, explicit);
 
 			spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 			atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
 			smp_mb__after_atomic_dec();
+			if (rc)
+				break;
 		}
 		spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
@@ -1025,15 +1092,18 @@ int core_alua_do_port_transition(
 	}
 	spin_unlock(&lu_gp->lu_gp_lock);
 
-	pr_debug("Successfully processed LU Group: %s all ALUA TG PT"
-		" Group IDs: %hu %s transition to primary state: %s\n",
-		config_item_name(&lu_gp->lu_gp_group.cg_item),
-		l_tg_pt_gp->tg_pt_gp_id, (explicit) ? "explicit" : "implicit",
-		core_alua_dump_state(new_state));
+	if (!rc) {
+		pr_debug("Successfully processed LU Group: %s all ALUA TG PT"
+			 " Group IDs: %hu %s transition to primary state: %s\n",
+			 config_item_name(&lu_gp->lu_gp_group.cg_item),
+			 l_tg_pt_gp->tg_pt_gp_id,
+			 (explicit) ? "explicit" : "implicit",
+			 core_alua_dump_state(new_state));
+	}
 
 	atomic_dec(&lu_gp->lu_gp_ref_cnt);
 	smp_mb__after_atomic_dec();
-	return 0;
+	return rc;
 }
 
 /*
@@ -1387,6 +1457,8 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
 	mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex);
 	spin_lock_init(&tg_pt_gp->tg_pt_gp_lock);
 	atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0);
+	INIT_DELAYED_WORK(&tg_pt_gp->tg_pt_gp_transition_work,
+			  core_alua_do_transition_tg_pt_work);
 	tg_pt_gp->tg_pt_gp_dev = dev;
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 		ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED);
@@ -1515,6 +1587,8 @@ void core_alua_free_tg_pt_gp(
 	dev->t10_alua.alua_tg_pt_gps_counter--;
 	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
+	flush_delayed_work(&tg_pt_gp->tg_pt_gp_transition_work);
+
 	/*
 	 * Allow a struct t10_alua_tg_pt_gp_member * referenced by
 	 * core_alua_get_tg_pt_gp_by_name() in
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index b8b7ec8..b95c1f1 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -302,6 +302,10 @@ struct t10_alua_tg_pt_gp {
 	struct config_group tg_pt_gp_group;
 	struct list_head tg_pt_gp_list;
 	struct list_head tg_pt_gp_mem_list;
+	struct se_port *tg_pt_gp_alua_port;
+	struct se_node_acl *tg_pt_gp_alua_nacl;
+	struct delayed_work tg_pt_gp_transition_work;
+	struct completion *tg_pt_gp_transition_complete;
 };
 
 struct t10_alua_tg_pt_gp_member {
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 15/18] target_core: simplify scsi_name_len calculation
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (13 preceding siblings ...)
  2013-11-19  8:07 ` [PATCH 14/18] target_core_alua: Use workqueue for ALUA transitioning Hannes Reinecke
@ 2013-11-19  8:08 ` Hannes Reinecke
  2013-11-19  8:08 ` [PATCH 16/18] target_core_spc: Include target device descriptor in VPD page 83 Hannes Reinecke
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:08 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

scsi_name_len in spc_emulate_evpd_83 is calculated twice, with
the results of the first calculation discarded. So remove it.
And check for the maximum allowed length, too.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_spc.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 49947f3..0fde086 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -365,16 +365,6 @@ check_lu_gp:
 		 * section 7.5.1 Table 362
 		 */
 check_scsi_name:
-		scsi_name_len = strlen(tpg->se_tpg_tfo->tpg_get_wwn(tpg));
-		/* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */
-		scsi_name_len += 10;
-		/* Check for 4-byte padding */
-		padding = ((-scsi_name_len) & 3);
-		if (padding != 0)
-			scsi_name_len += padding;
-		/* Header size + Designation descriptor */
-		scsi_name_len += 4;
-
 		buf[off] =
 			(tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4);
 		buf[off++] |= 0x3; /* CODE SET == UTF-8 */
@@ -402,8 +392,11 @@ check_scsi_name:
 		 * shall be no larger than 256 and shall be a multiple
 		 * of four.
 		 */
+		padding = ((-scsi_name_len) & 3);
 		if (padding)
 			scsi_name_len += padding;
+		if (scsi_name_len > 256)
+			scsi_name_len = 256;
 
 		buf[off-1] = scsi_name_len;
 		off += scsi_name_len;
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 16/18] target_core_spc: Include target device descriptor in VPD page 83
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (14 preceding siblings ...)
  2013-11-19  8:08 ` [PATCH 15/18] target_core: simplify scsi_name_len calculation Hannes Reinecke
@ 2013-11-19  8:08 ` Hannes Reinecke
  2013-11-19  8:08 ` [PATCH 17/18] target_core_alua: Referrals infrastructure Hannes Reinecke
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:08 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

We should be including a descriptor referring to the target device
to allow identification of different TCM instances.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_spc.c | 43 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 0fde086..44e8d69 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -267,7 +267,7 @@ check_t10_vend_desc:
 	port = lun->lun_sep;
 	if (port) {
 		struct t10_alua_lu_gp *lu_gp;
-		u32 padding, scsi_name_len;
+		u32 padding, scsi_name_len, scsi_target_len;
 		u16 lu_gp_id = 0;
 		u16 tg_pt_gp_id = 0;
 		u16 tpgt;
@@ -402,6 +402,47 @@ check_scsi_name:
 		off += scsi_name_len;
 		/* Header size + Designation descriptor */
 		len += (scsi_name_len + 4);
+
+		/*
+		 * Target device designator
+		 */
+		buf[off] =
+			(tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4);
+		buf[off++] |= 0x3; /* CODE SET == UTF-8 */
+		buf[off] = 0x80; /* Set PIV=1 */
+		/* Set ASSOCIATION == target device: 10b */
+		buf[off] |= 0x20;
+		/* DESIGNATOR TYPE == SCSI name string */
+		buf[off++] |= 0x8;
+		off += 2; /* Skip over Reserved and length */
+		/*
+		 * SCSI name string identifer containing, $FABRIC_MOD
+		 * dependent information.  For LIO-Target and iSCSI
+		 * Target Port, this means "<iSCSI name>" in
+		 * UTF-8 encoding.
+		 */
+		scsi_target_len = sprintf(&buf[off], "%s",
+					  tpg->se_tpg_tfo->tpg_get_wwn(tpg));
+		scsi_target_len += 1 /* Include  NULL terminator */;
+		/*
+		 * The null-terminated, null-padded (see 4.4.2) SCSI
+		 * NAME STRING field contains a UTF-8 format string.
+		 * The number of bytes in the SCSI NAME STRING field
+		 * (i.e., the value in the DESIGNATOR LENGTH field)
+		 * shall be no larger than 256 and shall be a multiple
+		 * of four.
+		 */
+		padding = ((-scsi_target_len) & 3);
+		if (padding)
+			scsi_target_len += padding;
+		if (scsi_name_len > 256)
+			scsi_name_len = 256;
+
+		buf[off-1] = scsi_target_len;
+		off += scsi_target_len;
+
+		/* Header size + Designation descriptor */
+		len += (scsi_target_len + 4);
 	}
 	buf[2] = ((len >> 8) & 0xff);
 	buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 17/18] target_core_alua: Referrals infrastructure
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (15 preceding siblings ...)
  2013-11-19  8:08 ` [PATCH 16/18] target_core_spc: Include target device descriptor in VPD page 83 Hannes Reinecke
@ 2013-11-19  8:08 ` Hannes Reinecke
  2013-11-19  8:08 ` [PATCH 18/18] target_core_alua: Referrals configfs integration Hannes Reinecke
  2013-11-19 23:42 ` [PATCHv2 00/18] ALUA update and Referrals support Nicholas A. Bellinger
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:08 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Add infrastructure for referrals.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c     | 155 ++++++++++++++++++++++++++++++++++
 drivers/target/target_core_alua.h     |   4 +-
 drivers/target/target_core_configfs.c |   9 +-
 drivers/target/target_core_device.c   |   2 +
 drivers/target/target_core_sbc.c      |   5 +-
 drivers/target/target_core_spc.c      |  20 +++++
 include/scsi/scsi.h                   |   1 +
 include/target/target_core_base.h     |  18 ++++
 8 files changed, 211 insertions(+), 3 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 19179cf..5b11908 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -56,6 +56,75 @@ static LIST_HEAD(lu_gps_list);
 struct t10_alua_lu_gp *default_lu_gp;
 
 /*
+ * REPORT REFERRALS
+ *
+ * See sbc3r35 section 5.23
+ */
+sense_reason_t
+target_emulate_report_referrals(struct se_cmd *cmd)
+{
+	struct se_device *dev = cmd->se_dev;
+	struct t10_alua_lba_map *map;
+	struct t10_alua_lba_map_member *map_mem;
+	unsigned char *buf;
+	u32 rd_len = 0, off;
+
+	if (cmd->data_length < 4) {
+		pr_warn("REPORT REFERRALS allocation length %u too"
+			" small\n", cmd->data_length);
+		return TCM_INVALID_CDB_FIELD;
+	}
+
+	buf = transport_kmap_data_sg(cmd);
+	if (!buf)
+		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+	off = 4;
+	spin_lock(&dev->t10_alua.lba_map_lock);
+	if (list_empty(&dev->t10_alua.lba_map_list)) {
+		spin_unlock(&dev->t10_alua.lba_map_lock);
+		transport_kunmap_data_sg(cmd);
+
+		return TCM_UNSUPPORTED_SCSI_OPCODE;
+	}
+
+	list_for_each_entry(map, &dev->t10_alua.lba_map_list,
+			    lba_map_list) {
+		int desc_num = off + 3;
+		int pg_num;
+
+		off += 4;
+		put_unaligned_be64(map->lba_map_first_lba, &buf[off]);
+		off += 8;
+		put_unaligned_be64(map->lba_map_last_lba, &buf[off]);
+		off += 8;
+		rd_len += 20;
+		pg_num = 0;
+		list_for_each_entry(map_mem, &map->lba_map_mem_list,
+				    lba_map_mem_list) {
+			buf[off++] = map_mem->lba_map_mem_alua_state & 0x0f;
+			off++;
+			buf[off++] = (map_mem->lba_map_mem_alua_pg_id >> 8) & 0xff;
+			buf[off++] = (map_mem->lba_map_mem_alua_pg_id & 0xff);
+			rd_len += 4;
+			pg_num++;
+		}
+		buf[desc_num] = pg_num;
+	}
+	spin_unlock(&dev->t10_alua.lba_map_lock);
+
+	/*
+	 * Set the RETURN DATA LENGTH set in the header of the DataIN Payload
+	 */
+	put_unaligned_be16(rd_len, &buf[2]);
+
+	transport_kunmap_data_sg(cmd);
+
+	target_complete_cmd(cmd, GOOD);
+	return 0;
+}
+
+/*
  * REPORT_TARGET_PORT_GROUPS
  *
  * See spc4r17 section 6.27
@@ -389,6 +458,80 @@ static inline int core_alua_state_nonoptimized(
 	return 0;
 }
 
+static inline int core_alua_state_lba_dependent(
+	struct se_cmd *cmd,
+	struct t10_alua_tg_pt_gp *tg_pt_gp,
+	u8 *alua_ascq)
+{
+	struct se_device *dev = cmd->se_dev;
+	u32 segment_size, segment_mult, sectors;
+	u64 lba;
+
+	/* Only need to check for cdb actually containing LBAs */
+	if (!cmd->se_cmd_flags & SCF_SCSI_DATA_CDB)
+		return 0;
+
+	spin_lock(&dev->t10_alua.lba_map_lock);
+	segment_size = dev->t10_alua.lba_map_segment_size;
+	segment_mult = dev->t10_alua.lba_map_segment_multiplier;
+	sectors = cmd->data_length / dev->dev_attrib.block_size;
+
+	lba = cmd->t_task_lba;
+	while (lba < cmd->t_task_lba + sectors) {
+		struct t10_alua_lba_map *cur_map = NULL, *map;
+		struct t10_alua_lba_map_member *map_mem;
+
+		list_for_each_entry(map, &dev->t10_alua.lba_map_list,
+				    lba_map_list) {
+			u64 start_lba, last_lba;
+			u64 first_lba = map->lba_map_first_lba;
+
+			if (segment_mult) {
+				start_lba = lba % (segment_size * segment_mult);
+				last_lba = first_lba + segment_size - 1;
+				if (start_lba >= first_lba &&
+				    start_lba <= last_lba) {
+					lba += segment_size;
+					cur_map = map;
+					break;
+				}
+			} else {
+				last_lba = map->lba_map_last_lba;
+				if (lba >= first_lba && lba <= last_lba) {
+					lba = last_lba + 1;
+					cur_map = map;
+					break;
+				}
+			}
+		}
+		if (!cur_map) {
+			spin_unlock(&dev->t10_alua.lba_map_lock);
+			*alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
+			return 1;
+		}
+		list_for_each_entry(map_mem, &cur_map->lba_map_mem_list,
+				    lba_map_mem_list) {
+			if (map_mem->lba_map_mem_alua_pg_id !=
+			    tg_pt_gp->tg_pt_gp_id)
+				continue;
+			switch(map_mem->lba_map_mem_alua_state) {
+			case ALUA_ACCESS_STATE_STANDBY:
+				spin_unlock(&dev->t10_alua.lba_map_lock);
+				*alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
+				return 1;
+			case ALUA_ACCESS_STATE_UNAVAILABLE:
+				spin_unlock(&dev->t10_alua.lba_map_lock);
+				*alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
+				return 1;
+			default:
+				break;
+			}
+		}
+	}
+	spin_unlock(&dev->t10_alua.lba_map_lock);
+	return 0;
+}
+
 static inline int core_alua_state_standby(
 	struct se_cmd *cmd,
 	unsigned char *cdb,
@@ -586,6 +729,9 @@ target_alua_state_check(struct se_cmd *cmd)
 	case ALUA_ACCESS_STATE_TRANSITION:
 		ret = core_alua_state_transition(cmd, cdb, &alua_ascq);
 		break;
+	case ALUA_ACCESS_STATE_LBA_DEPENDENT:
+		ret = core_alua_state_lba_dependent(cmd, tg_pt_gp, &alua_ascq);
+		break;
 	/*
 	 * OFFLINE is a secondary ALUA target port group access state, that is
 	 * handled above with struct se_port->sep_tg_pt_secondary_offline=1
@@ -623,6 +769,8 @@ int core_alua_parse_state(const char *state)
 		return ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED;
 	if (!strncasecmp(state, "Active/NonOptimized", 19))
 		return ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED;
+	if (!strncasecmp(state, "LBA Dependent", 19))
+		return ALUA_ACCESS_STATE_LBA_DEPENDENT;
 	if (!strncasecmp(state, "Standby", 7))
 		return ALUA_ACCESS_STATE_STANDBY;
 	if (!strncasecmp(state, "Unavailable", 11))
@@ -640,6 +788,8 @@ char *core_alua_dump_state(int state)
 		return "Active/Optimized";
 	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
 		return "Active/NonOptimized";
+	case ALUA_ACCESS_STATE_LBA_DEPENDENT:
+		return "LBA Dependent";
 	case ALUA_ACCESS_STATE_STANDBY:
 		return "Standby";
 	case ALUA_ACCESS_STATE_UNAVAILABLE:
@@ -686,6 +836,11 @@ core_alua_check_transition(int state, int valid, int *primary)
 			goto not_supported;
 		*primary = 1;
 		break;
+	case ALUA_ACCESS_STATE_LBA_DEPENDENT:
+		if (!(valid & ALUA_LBD_SUP))
+			goto not_supported;
+		*primary = 1;
+		break;
 	case ALUA_ACCESS_STATE_OFFLINE:
 		/*
 		 * OFFLINE state is defined as a secondary target port
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index f2c1ef3..e4ba452 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -13,12 +13,13 @@
 /*
  * ASYMMETRIC ACCESS STATE field
  *
- * from spc4r17 section 6.27 Table 245
+ * from spc4r36j section 6.37 Table 307
  */
 #define ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED	0x0
 #define ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED	0x1
 #define ALUA_ACCESS_STATE_STANDBY		0x2
 #define ALUA_ACCESS_STATE_UNAVAILABLE		0x3
+#define ALUA_ACCESS_STATE_LBA_DEPENDENT		0x4
 #define ALUA_ACCESS_STATE_OFFLINE		0xe
 #define ALUA_ACCESS_STATE_TRANSITION		0xf
 
@@ -88,6 +89,7 @@ extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
 
 extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *);
 extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *);
+extern sense_reason_t target_emulate_report_referrals(struct se_cmd *);
 extern int core_alua_check_nonop_delay(struct se_cmd *);
 extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
 				struct se_device *, struct se_port *,
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 9ba6828..50f058c 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2059,6 +2059,13 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 		}
 		new_state = (int)tmp;
 	}
+	if (tg_pt_gp->tg_pt_gp_alua_mgmt_type & ALUA_MGMT_EXPLICIT &&
+	    new_state == ALUA_ACCESS_STATE_LBA_DEPENDENT) {
+		/* LBA DEPENDENT is only allowed with implicit ALUA */
+		pr_err("Unable to process implicit configfs ALUA transition"
+		       " while explicit ALUA management is enabled\n");
+		return -EINVAL;
+	}
 	ret = core_alua_do_port_transition(tg_pt_gp, dev,
 					NULL, NULL, new_state, 0);
 	return (!ret) ? count : -EINVAL;
@@ -2188,7 +2195,7 @@ SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_lba_dependent,
 			       tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
 SE_DEV_ALUA_SUPPORT_STATE_STORE(support_lba_dependent,
 				tg_pt_gp_alua_supported_states, ALUA_LBD_SUP);
-SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO | S_IWUSR);
+SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO);
 
 SE_DEV_ALUA_SUPPORT_STATE_SHOW(support_unavailable,
 			       tg_pt_gp_alua_supported_states, ALUA_U_SUP);
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 207b340..3c08f99 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1439,6 +1439,8 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
 	spin_lock_init(&dev->t10_pr.aptpl_reg_lock);
 	INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list);
 	spin_lock_init(&dev->t10_alua.tg_pt_gps_lock);
+	INIT_LIST_HEAD(&dev->t10_alua.lba_map_list);
+	spin_lock_init(&dev->t10_alua.lba_map_lock);
 
 	dev->t10_wwn.t10_dev = dev;
 	dev->t10_alua.t10_dev = dev;
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 61a30f0..daaddc7 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -33,7 +33,7 @@
 
 #include "target_core_internal.h"
 #include "target_core_ua.h"
-
+#include "target_core_alua.h"
 
 static sense_reason_t
 sbc_emulate_readcapacity(struct se_cmd *cmd)
@@ -702,6 +702,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
 		case SAI_READ_CAPACITY_16:
 			cmd->execute_cmd = sbc_emulate_readcapacity_16;
 			break;
+		case SAI_REPORT_REFERRALS:
+			cmd->execute_cmd = target_emulate_report_referrals;
+			break;
 		default:
 			pr_err("Unsupported SA: 0x%02x\n",
 				cmd->t_task_cdb[1] & 0x1f);
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 44e8d69..5d86813 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -476,6 +476,11 @@ spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
 	/* If WriteCache emulation is enabled, set V_SUP */
 	if (spc_check_dev_wce(dev))
 		buf[6] = 0x01;
+	/* If an LBA map is present set R_SUP */
+	spin_lock(&cmd->se_dev->t10_alua.lba_map_lock);
+	if (!list_empty(&dev->t10_alua.lba_map_list))
+		buf[8] = 0x10;
+	spin_unlock(&cmd->se_dev->t10_alua.lba_map_lock);
 	return 0;
 }
 
@@ -634,6 +639,20 @@ spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
 	return 0;
 }
 
+/* Referrals VPD page */
+static sense_reason_t
+spc_emulate_evpd_b3(struct se_cmd *cmd, unsigned char *buf)
+{
+	struct se_device *dev = cmd->se_dev;
+
+	buf[0] = dev->transport->get_device_type(dev);
+	buf[3] = 0x0c;
+	put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[8]);
+	put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[12]);
+
+	return 0;
+}
+
 static sense_reason_t
 spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf);
 
@@ -648,6 +667,7 @@ static struct {
 	{ .page = 0xb0, .emulate = spc_emulate_evpd_b0 },
 	{ .page = 0xb1, .emulate = spc_emulate_evpd_b1 },
 	{ .page = 0xb2, .emulate = spc_emulate_evpd_b2 },
+	{ .page = 0xb3, .emulate = spc_emulate_evpd_b3 },
 };
 
 /* supported vital product data pages */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 66d42ed..0a4edfe 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -155,6 +155,7 @@ enum scsi_timeouts {
 /* values for service action in */
 #define	SAI_READ_CAPACITY_16  0x10
 #define SAI_GET_LBA_STATUS    0x12
+#define SAI_REPORT_REFERRALS  0x13
 /* values for VARIABLE_LENGTH_CMD service action codes
  * see spc4r17 Section D.3.5, table D.7 and D.8 */
 #define VLC_SA_RECEIVE_CREDENTIAL 0x1800
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index b95c1f1..ab66b87 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -247,10 +247,28 @@ typedef enum {
 
 struct se_cmd;
 
+struct t10_alua_lba_map_member {
+	struct list_head lba_map_mem_list;
+	int lba_map_mem_alua_state;
+	int lba_map_mem_alua_pg_id;
+};
+
+struct t10_alua_lba_map {
+	u64 lba_map_first_lba;
+	u64 lba_map_last_lba;
+	struct list_head lba_map_list;
+	struct list_head lba_map_mem_list;
+};
+
 struct t10_alua {
 	/* ALUA Target Port Group ID */
 	u16	alua_tg_pt_gps_counter;
 	u32	alua_tg_pt_gps_count;
+	/* Referrals support */
+	spinlock_t lba_map_lock;
+	u32     lba_map_segment_size;
+	u32     lba_map_segment_multiplier;
+	struct list_head lba_map_list;
 	spinlock_t tg_pt_gps_lock;
 	struct se_device *t10_dev;
 	/* Used for default ALUA Target Port Group */
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 18/18] target_core_alua: Referrals configfs integration
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (16 preceding siblings ...)
  2013-11-19  8:08 ` [PATCH 17/18] target_core_alua: Referrals infrastructure Hannes Reinecke
@ 2013-11-19  8:08 ` Hannes Reinecke
  2013-11-19 23:42 ` [PATCHv2 00/18] ALUA update and Referrals support Nicholas A. Bellinger
  18 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-19  8:08 UTC (permalink / raw)
  To: Nic Bellinger; +Cc: target-devel, linux-scsi, Hannes Reinecke

Referrals need an LBA map, which needs to be kept
consistent across all target port groups. So
instead of tying the map to the target port groups
I've implemented a single attribute containing the
entire map.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/target/target_core_alua.c      | 101 +++++++++++++++++++
 drivers/target/target_core_alua.h      |   8 ++
 drivers/target/target_core_configfs.c  | 171 +++++++++++++++++++++++++++++++++
 drivers/target/target_core_device.c    |   1 +
 drivers/target/target_core_transport.c |  28 +++++-
 5 files changed, 308 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 5b11908..b1c33e8 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -1360,6 +1360,107 @@ static int core_alua_set_tg_pt_secondary_state(
 	return 0;
 }
 
+struct t10_alua_lba_map *
+core_alua_allocate_lba_map(struct list_head *list,
+			   u64 first_lba, u64 last_lba)
+{
+	struct t10_alua_lba_map *lba_map;
+
+	lba_map = kmem_cache_zalloc(t10_alua_lba_map_cache, GFP_KERNEL);
+	if (!lba_map) {
+		pr_err("Unable to allocate struct t10_alua_lba_map\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	INIT_LIST_HEAD(&lba_map->lba_map_mem_list);
+	lba_map->lba_map_first_lba = first_lba;
+	lba_map->lba_map_last_lba = last_lba;
+
+	list_add_tail(&lba_map->lba_map_list, list);
+	return lba_map;
+}
+
+int
+core_alua_allocate_lba_map_mem(struct t10_alua_lba_map *lba_map,
+			       int pg_id, int state)
+{
+	struct t10_alua_lba_map_member *lba_map_mem;
+
+	list_for_each_entry(lba_map_mem, &lba_map->lba_map_mem_list,
+			    lba_map_mem_list) {
+		if (lba_map_mem->lba_map_mem_alua_pg_id == pg_id) {
+			pr_err("Duplicate pg_id %d in lba_map\n", pg_id);
+			return -EINVAL;
+		}
+	}
+
+	lba_map_mem = kmem_cache_zalloc(t10_alua_lba_map_mem_cache, GFP_KERNEL);
+	if (!lba_map_mem) {
+		pr_err("Unable to allocate struct t10_alua_lba_map_mem\n");
+		return -ENOMEM;
+	}
+	lba_map_mem->lba_map_mem_alua_state = state;
+	lba_map_mem->lba_map_mem_alua_pg_id = pg_id;
+
+	list_add_tail(&lba_map_mem->lba_map_mem_list,
+		      &lba_map->lba_map_mem_list);
+	return 0;
+}
+
+void
+core_alua_free_lba_map(struct list_head *lba_list)
+{
+	struct t10_alua_lba_map *lba_map, *lba_map_tmp;
+	struct t10_alua_lba_map_member *lba_map_mem, *lba_map_mem_tmp;
+
+	list_for_each_entry_safe(lba_map, lba_map_tmp, lba_list,
+				 lba_map_list) {
+		list_for_each_entry_safe(lba_map_mem, lba_map_mem_tmp,
+					 &lba_map->lba_map_mem_list,
+					 lba_map_mem_list) {
+			list_del(&lba_map_mem->lba_map_mem_list);
+			kmem_cache_free(t10_alua_lba_map_mem_cache,
+					lba_map_mem);
+		}
+		list_del(&lba_map->lba_map_list);
+		kmem_cache_free(t10_alua_lba_map_cache, lba_map);
+	}
+}
+
+void
+core_alua_set_lba_map(struct se_device *dev, struct list_head *lba_map_list,
+		      int segment_size, int segment_mult)
+{
+	struct list_head old_lba_map_list;
+	struct t10_alua_tg_pt_gp *tg_pt_gp;
+	int activate = 0, supported;
+
+	INIT_LIST_HEAD(&old_lba_map_list);
+	spin_lock(&dev->t10_alua.lba_map_lock);
+	dev->t10_alua.lba_map_segment_size = segment_size;
+	dev->t10_alua.lba_map_segment_multiplier = segment_mult;
+	list_splice_init(&dev->t10_alua.lba_map_list, &old_lba_map_list);
+	if (lba_map_list) {
+		list_splice_init(lba_map_list, &dev->t10_alua.lba_map_list);
+		activate = 1;
+	}
+	spin_unlock(&dev->t10_alua.lba_map_lock);
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+	list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list,
+			    tg_pt_gp_list) {
+
+		if (!tg_pt_gp->tg_pt_gp_valid_id)
+			continue;
+		supported = tg_pt_gp->tg_pt_gp_alua_supported_states;
+		if (activate)
+			supported |= ALUA_LBD_SUP;
+		else
+			supported &= ~ALUA_LBD_SUP;
+		tg_pt_gp->tg_pt_gp_alua_supported_states = supported;
+	}
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
+	core_alua_free_lba_map(&old_lba_map_list);
+}
+
 struct t10_alua_lu_gp *
 core_alua_allocate_lu_gp(const char *name, int def_group)
 {
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index e4ba452..c83935c 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -86,6 +86,8 @@ extern struct kmem_cache *t10_alua_lu_gp_cache;
 extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
 extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
 extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
+extern struct kmem_cache *t10_alua_lba_map_cache;
+extern struct kmem_cache *t10_alua_lba_map_mem_cache;
 
 extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *);
 extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *);
@@ -97,6 +99,12 @@ extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
 extern char *core_alua_dump_state(int);
 extern int core_alua_parse_state(const char *);
 extern char *core_alua_dump_status(int);
+extern struct t10_alua_lba_map *core_alua_allocate_lba_map(
+				struct list_head *, u64, u64);
+extern int core_alua_allocate_lba_map_mem(struct t10_alua_lba_map *, int, int);
+extern void core_alua_free_lba_map(struct list_head *);
+extern void core_alua_set_lba_map(struct se_device *, struct list_head *,
+				int, int);
 extern struct t10_alua_lu_gp *core_alua_allocate_lu_gp(const char *, int);
 extern int core_alua_set_lu_gp_id(struct t10_alua_lu_gp *, u16);
 extern void core_alua_free_lu_gp(struct t10_alua_lu_gp *);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 50f058c..04d683d 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -1741,6 +1741,176 @@ static struct target_core_configfs_attribute target_core_attr_dev_alua_lu_gp = {
 	.store	= target_core_store_alua_lu_gp,
 };
 
+static ssize_t target_core_show_dev_lba_map(void *p, char *page)
+{
+	struct se_device *dev = p;
+	struct t10_alua_lba_map *map;
+	struct t10_alua_lba_map_member *mem;
+	char *b = page;
+	int bl = 0;
+	char state;
+
+	spin_lock(&dev->t10_alua.lba_map_lock);
+	if (!list_empty(&dev->t10_alua.lba_map_list))
+	    bl += sprintf(b + bl, "%u %u\n",
+			  dev->t10_alua.lba_map_segment_size,
+			  dev->t10_alua.lba_map_segment_multiplier);
+	list_for_each_entry(map, &dev->t10_alua.lba_map_list, lba_map_list) {
+		bl += sprintf(b + bl, "%llu %llu",
+			      map->lba_map_first_lba, map->lba_map_last_lba);
+		list_for_each_entry(mem, &map->lba_map_mem_list,
+				    lba_map_mem_list) {
+			switch (mem->lba_map_mem_alua_state) {
+			case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
+				state = 'O';
+				break;
+			case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
+				state = 'A';
+				break;
+			case ALUA_ACCESS_STATE_STANDBY:
+				state = 'S';
+				break;
+			case ALUA_ACCESS_STATE_UNAVAILABLE:
+				state = 'U';
+				break;
+			default:
+				state = '.';
+				break;
+			}
+			bl += sprintf(b + bl, " %d:%c",
+				      mem->lba_map_mem_alua_pg_id, state);
+		}
+		bl += sprintf(b + bl, "\n");
+	}
+	spin_unlock(&dev->t10_alua.lba_map_lock);
+	return bl;
+}
+
+static ssize_t target_core_store_dev_lba_map(
+	void *p,
+	const char *page,
+	size_t count)
+{
+	struct se_device *dev = p;
+	struct t10_alua_lba_map *lba_map = NULL;
+	struct list_head lba_list;
+	char *map_entries, *ptr;
+	char state;
+	int pg_num = -1, pg;
+	int ret = 0, num = 0, pg_id, alua_state;
+	unsigned long start_lba = -1, end_lba = -1;
+	unsigned long segment_size = -1, segment_mult = -1;
+
+	map_entries = kstrdup(page, GFP_KERNEL);
+	if (!map_entries)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&lba_list);
+	while ((ptr = strsep(&map_entries, "\n")) != NULL) {
+		if (!*ptr)
+			continue;
+
+		if (num == 0) {
+			if (sscanf(ptr, "%lu %lu\n",
+				   &segment_size, &segment_mult) != 2) {
+				pr_err("Invalid line %d\n", num);
+				ret = -EINVAL;
+				break;
+			}
+			num++;
+			continue;
+		}
+		if (sscanf(ptr, "%lu %lu", &start_lba, &end_lba) != 2) {
+			pr_err("Invalid line %d\n", num);
+			ret = -EINVAL;
+			break;
+		}
+		ptr = strchr(ptr, ' ');
+		if (!ptr) {
+			pr_err("Invalid line %d, missing end lba\n", num);
+			ret = -EINVAL;
+			break;
+		}
+		ptr++;
+		ptr = strchr(ptr, ' ');
+		if (!ptr) {
+			pr_err("Invalid line %d, missing state definitions\n",
+			       num);
+			ret = -EINVAL;
+			break;
+		}
+		ptr++;
+		lba_map = core_alua_allocate_lba_map(&lba_list,
+						     start_lba, end_lba);
+		if (IS_ERR(lba_map)) {
+			ret = PTR_ERR(lba_map);
+			break;
+		}
+		pg = 0;
+		while (sscanf(ptr, "%d:%c", &pg_id, &state) == 2) {
+			switch (state) {
+			case 'O':
+				alua_state = ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED;
+				break;
+			case 'A':
+				alua_state = ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED;
+				break;
+			case 'S':
+				alua_state = ALUA_ACCESS_STATE_STANDBY;
+				break;
+			case 'U':
+				alua_state = ALUA_ACCESS_STATE_UNAVAILABLE;
+				break;
+			default:
+				pr_err("Invalid ALUA state '%c'\n", state);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			ret = core_alua_allocate_lba_map_mem(lba_map,
+							     pg_id, alua_state);
+			if (ret) {
+				pr_err("Invalid target descriptor %d:%c "
+				       "at line %d\n",
+				       pg_id, state, num);
+				break;
+			}
+			pg++;
+			ptr = strchr(ptr, ' ');
+			if (ptr)
+				ptr++;
+			else
+				break;
+		}
+		if (pg_num == -1)
+		    pg_num = pg;
+		else if (pg != pg_num) {
+			pr_err("Only %d from %d port groups definitions "
+			       "at line %d\n", pg, pg_num, num);
+			ret = -EINVAL;
+			break;
+		}
+		num++;
+	}
+out:
+	if (ret) {
+		core_alua_free_lba_map(&lba_list);
+		count = ret;
+	} else
+		core_alua_set_lba_map(dev, &lba_list,
+				      segment_size, segment_mult);
+	kfree(map_entries);
+	return count;
+}
+
+static struct target_core_configfs_attribute target_core_attr_dev_lba_map = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "lba_map",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= target_core_show_dev_lba_map,
+	.store	= target_core_store_dev_lba_map,
+};
+
 static struct configfs_attribute *lio_core_dev_attrs[] = {
 	&target_core_attr_dev_info.attr,
 	&target_core_attr_dev_control.attr,
@@ -1748,6 +1918,7 @@ static struct configfs_attribute *lio_core_dev_attrs[] = {
 	&target_core_attr_dev_udev_path.attr,
 	&target_core_attr_dev_enable.attr,
 	&target_core_attr_dev_alua_lu_gp.attr,
+	&target_core_attr_dev_lba_map.attr,
 	NULL,
 };
 
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 3c08f99..376a4d3 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1585,6 +1585,7 @@ void target_free_device(struct se_device *dev)
 	}
 
 	core_alua_free_lu_gp_mem(dev);
+	core_alua_set_lba_map(dev, NULL, 0, 0);
 	core_scsi3_free_all_registrations(dev);
 	se_release_vpd_for_dev(dev);
 
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 269a798..ea4dc1b 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -62,6 +62,8 @@ struct kmem_cache *t10_alua_lu_gp_cache;
 struct kmem_cache *t10_alua_lu_gp_mem_cache;
 struct kmem_cache *t10_alua_tg_pt_gp_cache;
 struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
+struct kmem_cache *t10_alua_lba_map_cache;
+struct kmem_cache *t10_alua_lba_map_mem_cache;
 
 static void transport_complete_task_attr(struct se_cmd *cmd);
 static void transport_handle_queue_full(struct se_cmd *cmd,
@@ -128,14 +130,36 @@ int init_se_kmem_caches(void)
 				"mem_t failed\n");
 		goto out_free_tg_pt_gp_cache;
 	}
+	t10_alua_lba_map_cache = kmem_cache_create(
+			"t10_alua_lba_map_cache",
+			sizeof(struct t10_alua_lba_map),
+			__alignof__(struct t10_alua_lba_map), 0, NULL);
+	if (!t10_alua_lba_map_cache) {
+		pr_err("kmem_cache_create() for t10_alua_lba_map_"
+				"cache failed\n");
+		goto out_free_tg_pt_gp_mem_cache;
+	}
+	t10_alua_lba_map_mem_cache = kmem_cache_create(
+			"t10_alua_lba_map_mem_cache",
+			sizeof(struct t10_alua_lba_map_member),
+			__alignof__(struct t10_alua_lba_map_member), 0, NULL);
+	if (!t10_alua_lba_map_mem_cache) {
+		pr_err("kmem_cache_create() for t10_alua_lba_map_mem_"
+				"cache failed\n");
+		goto out_free_lba_map_cache;
+	}
 
 	target_completion_wq = alloc_workqueue("target_completion",
 					       WQ_MEM_RECLAIM, 0);
 	if (!target_completion_wq)
-		goto out_free_tg_pt_gp_mem_cache;
+		goto out_free_lba_map_mem_cache;
 
 	return 0;
 
+out_free_lba_map_mem_cache:
+	kmem_cache_destroy(t10_alua_lba_map_mem_cache);
+out_free_lba_map_cache:
+	kmem_cache_destroy(t10_alua_lba_map_cache);
 out_free_tg_pt_gp_mem_cache:
 	kmem_cache_destroy(t10_alua_tg_pt_gp_mem_cache);
 out_free_tg_pt_gp_cache:
@@ -164,6 +188,8 @@ void release_se_kmem_caches(void)
 	kmem_cache_destroy(t10_alua_lu_gp_mem_cache);
 	kmem_cache_destroy(t10_alua_tg_pt_gp_cache);
 	kmem_cache_destroy(t10_alua_tg_pt_gp_mem_cache);
+	kmem_cache_destroy(t10_alua_lba_map_cache);
+	kmem_cache_destroy(t10_alua_lba_map_mem_cache);
 }
 
 /* This code ensures unique mib indexes are handed out. */
-- 
1.7.12.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCHv2 00/18] ALUA update and Referrals support
  2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
                   ` (17 preceding siblings ...)
  2013-11-19  8:08 ` [PATCH 18/18] target_core_alua: Referrals configfs integration Hannes Reinecke
@ 2013-11-19 23:42 ` Nicholas A. Bellinger
  2013-11-20  0:06   ` Nicholas A. Bellinger
  18 siblings, 1 reply; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-19 23:42 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

Hey Hannes!

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> Hi Nic,
> 
> here's the second version of my ALUA update & Referrals support patches.
> As per request I've split up the supported states into individual
> attributes, and while there I've also renamed the rather confusing
> 'alua_access_type' and 'alua_access_status' into 'alua_management_type'
> and 'alua_status_modification', respectively.
> 
> The other features are:
> 
> - Make supported states configurable:
>   We should make the list of supported ALUA states configurable,
>   as some setups would possibly like to support a small subset
>   of ALUA states only.
> - Asynchronous transitioning: I've switched 'transitioning'
>   handling to use a workqueue, that should allow us to simulate
>   asynchronous transitioning modes. IE TCM should now be capable
>   of handling requests while in transitioning, and properly terminate
>   these with the correct sense code.
> - Include target device descriptor in VPD page 83
>   For the ALUA device handler we'd need to identify the target device
>   where a given target port belongs to. So include the respective
>   values in the VPD page.
> 
> And, of course, referrals support.
> 

Ok, even though it is late, I've applied this series to for-next.

So the one main concern here is that the user visible changes to
existing ALUA configfs attributes end up breaking the lio-utils code
related to ALUA that depend upon them, which will need to be resolved
separately.

However, this breakage is pretty minor and having more sensible +
consistent attribute naming is worth the inconvenience.

--nab

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCHv2 00/18] ALUA update and Referrals support
  2013-11-19 23:42 ` [PATCHv2 00/18] ALUA update and Referrals support Nicholas A. Bellinger
@ 2013-11-20  0:06   ` Nicholas A. Bellinger
  2013-11-20  7:44     ` Hannes Reinecke
  0 siblings, 1 reply; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20  0:06 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 15:42 -0800, Nicholas A. Bellinger wrote:
> Hey Hannes!
> 
> On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> > Hi Nic,
> > 
> > here's the second version of my ALUA update & Referrals support patches.
> > As per request I've split up the supported states into individual
> > attributes, and while there I've also renamed the rather confusing
> > 'alua_access_type' and 'alua_access_status' into 'alua_management_type'
> > and 'alua_status_modification', respectively.
> > 
> > The other features are:
> > 
> > - Make supported states configurable:
> >   We should make the list of supported ALUA states configurable,
> >   as some setups would possibly like to support a small subset
> >   of ALUA states only.
> > - Asynchronous transitioning: I've switched 'transitioning'
> >   handling to use a workqueue, that should allow us to simulate
> >   asynchronous transitioning modes. IE TCM should now be capable
> >   of handling requests while in transitioning, and properly terminate
> >   these with the correct sense code.
> > - Include target device descriptor in VPD page 83
> >   For the ALUA device handler we'd need to identify the target device
> >   where a given target port belongs to. So include the respective
> >   values in the VPD page.
> > 
> > And, of course, referrals support.
> > 
> 
> Ok, even though it is late, I've applied this series to for-next.
> 
> So the one main concern here is that the user visible changes to
> existing ALUA configfs attributes end up breaking the lio-utils code
> related to ALUA that depend upon them, which will need to be resolved
> separately.
> 
> However, this breakage is pretty minor and having more sensible +
> consistent attribute naming is worth the inconvenience.
> 

OK, I'm having second thoughts about the user-visible changes to
existing configfs attributes..

I'm fine with these types of changes, but need some more time to sort
out how it's going to effect existing userspace dependencies.  The one
that immediately made do a double take is changing 'alua_access_state'
to change input/output, but keep the same attribute name which makes
backwards compatibility alot more tricky.

So all that said, let's defer to v3.14 for this particular series, and
sort out the user visable changes first, and make adjustments as
necessary from there.

WDYT..?

--nab



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCHv2 00/18] ALUA update and Referrals support
  2013-11-20  0:06   ` Nicholas A. Bellinger
@ 2013-11-20  7:44     ` Hannes Reinecke
  2013-11-20 19:22       ` Nicholas A. Bellinger
  0 siblings, 1 reply; 31+ messages in thread
From: Hannes Reinecke @ 2013-11-20  7:44 UTC (permalink / raw)
  To: Nicholas A. Bellinger; +Cc: target-devel, linux-scsi

On 11/20/2013 01:06 AM, Nicholas A. Bellinger wrote:
> On Tue, 2013-11-19 at 15:42 -0800, Nicholas A. Bellinger wrote:
>> Hey Hannes!
>>
>> On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
>>> Hi Nic,
>>>
>>> here's the second version of my ALUA update & Referrals support patches.
>>> As per request I've split up the supported states into individual
>>> attributes, and while there I've also renamed the rather confusing
>>> 'alua_access_type' and 'alua_access_status' into 'alua_management_type'
>>> and 'alua_status_modification', respectively.
>>>
>>> The other features are:
>>>
>>> - Make supported states configurable:
>>>   We should make the list of supported ALUA states configurable,
>>>   as some setups would possibly like to support a small subset
>>>   of ALUA states only.
>>> - Asynchronous transitioning: I've switched 'transitioning'
>>>   handling to use a workqueue, that should allow us to simulate
>>>   asynchronous transitioning modes. IE TCM should now be capable
>>>   of handling requests while in transitioning, and properly terminate
>>>   these with the correct sense code.
>>> - Include target device descriptor in VPD page 83
>>>   For the ALUA device handler we'd need to identify the target device
>>>   where a given target port belongs to. So include the respective
>>>   values in the VPD page.
>>>
>>> And, of course, referrals support.
>>>
>>
>> Ok, even though it is late, I've applied this series to for-next.
>>
>> So the one main concern here is that the user visible changes to
>> existing ALUA configfs attributes end up breaking the lio-utils code
>> related to ALUA that depend upon them, which will need to be resolved
>> separately.
>>
>> However, this breakage is pretty minor and having more sensible +
>> consistent attribute naming is worth the inconvenience.
>>
> 
> OK, I'm having second thoughts about the user-visible changes to
> existing configfs attributes..
> 
> I'm fine with these types of changes, but need some more time to sort
> out how it's going to effect existing userspace dependencies.  The one
> that immediately made do a double take is changing 'alua_access_state'
> to change input/output, but keep the same attribute name which makes
> backwards compatibility alot more tricky.
> 
It's just a matter of parsing, innit?

> So all that said, let's defer to v3.14 for this particular series, and
> sort out the user visable changes first, and make adjustments as
> necessary from there.
> 
> WDYT..?
> 
Sigh.
Another patchset getting nowhere.

Okay, here's the thing:
The patchset can be split into three individual parts:
The ALUA update proper, which affects only the internal flow of
control (patches 1-6 and 11-16), then there's the ALUA configfs
modifications (patches 7-10) and the Referrals support (17 and 18).
If you have second thoughts you should be able to pull patches 7-10;
the rest will work as designed even without them.

But then, there's not much difference on having all the patches in
for 3.13, and sort out the userspace then, or wait for the next
round and adjust the userspace during that time.

Anyway, I don't mind either way. You're the maintainer, you get to
decide. As least I got feedback about the patchset, which is more
than one can hope for nowadays :-(

Give me a shout what you prefer, and I'll adapt the patchset
accordingly.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCHv2 00/18] ALUA update and Referrals support
  2013-11-20  7:44     ` Hannes Reinecke
@ 2013-11-20 19:22       ` Nicholas A. Bellinger
  2013-12-13 23:43         ` Nicholas A. Bellinger
  0 siblings, 1 reply; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:22 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Wed, 2013-11-20 at 08:44 +0100, Hannes Reinecke wrote:
> On 11/20/2013 01:06 AM, Nicholas A. Bellinger wrote:
> > On Tue, 2013-11-19 at 15:42 -0800, Nicholas A. Bellinger wrote:
> >> Hey Hannes!
> >>
> >> On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> >>> Hi Nic,
> >>>
> >>> here's the second version of my ALUA update & Referrals support patches.
> >>> As per request I've split up the supported states into individual
> >>> attributes, and while there I've also renamed the rather confusing
> >>> 'alua_access_type' and 'alua_access_status' into 'alua_management_type'
> >>> and 'alua_status_modification', respectively.
> >>>

<SNIP>

> > 
> > OK, I'm having second thoughts about the user-visible changes to
> > existing configfs attributes..
> > 
> > I'm fine with these types of changes, but need some more time to sort
> > out how it's going to effect existing userspace dependencies.  The one
> > that immediately made do a double take is changing 'alua_access_state'
> > to change input/output, but keep the same attribute name which makes
> > backwards compatibility alot more tricky.
> > 
> It's just a matter of parsing, innit?
> 
> > So all that said, let's defer to v3.14 for this particular series, and
> > sort out the user visable changes first, and make adjustments as
> > necessary from there.
> > 
> > WDYT..?
> > 
> Sigh.
> Another patchset getting nowhere.
> 

Awww, I like to think target-pending is still a whole lot more merge
friendly than linux-scsi.  ;)

> Okay, here's the thing:
> The patchset can be split into three individual parts:
> The ALUA update proper, which affects only the internal flow of
> control (patches 1-6 and 11-16), then there's the ALUA configfs
> modifications (patches 7-10) and the Referrals support (17 and 18).
> If you have second thoughts you should be able to pull patches 7-10;
> the rest will work as designed even without them.

Ok, I'm completely fine with patches 1-6, which only add new attributes
and don't change input/output or rename existing attributes.

It's 7-10 that introduce the changes that are of concern..

> But then, there's not much difference on having all the patches in
> for 3.13, and sort out the userspace then, or wait for the next
> round and adjust the userspace during that time.
> 

As much as I'd like to merge this now, the changes to existing
attributes is what needs to be thought out some more, to avoid overt
backwards compatibility ugliness.

> Anyway, I don't mind either way. You're the maintainer, you get to
> decide. As least I got feedback about the patchset, which is more
> than one can hope for nowadays :-(

Lets merge 1-6 now for v3.13, and I'll merge the rest for v3.14 into
for-next as soon as -rc1 is released, and we can duke it out on the
specific details starting next week.

--nab


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit
  2013-11-19  8:07 ` [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit Hannes Reinecke
@ 2013-11-20 19:29   ` Nicholas A. Bellinger
  0 siblings, 0 replies; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:29 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
>  drivers/target/target_core_alua.c      | 110 ++++++++++++++++-----------------
>  drivers/target/target_core_alua.h      |  20 +++---
>  drivers/target/target_core_configfs.c  |  26 ++++----
>  drivers/target/target_core_device.c    |   6 +-
>  drivers/target/target_core_file.c      |   2 +-
>  drivers/target/target_core_pr.c        |  24 +++----
>  drivers/target/target_core_spc.c       |   6 +-
>  drivers/target/target_core_transport.c |   4 +-
>  drivers/target/target_core_ua.h        |   2 +-
>  include/target/target_core_base.h      |   2 +-
>  10 files changed, 101 insertions(+), 101 deletions(-)

Applied.  Thanks Hannes!

--nab

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/18] target_core_alua: spellcheck
  2013-11-19  8:07 ` [PATCH 02/18] target_core_alua: spellcheck Hannes Reinecke
@ 2013-11-20 19:30   ` Nicholas A. Bellinger
  0 siblings, 0 replies; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:30 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
>  drivers/target/target_core_alua.c | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)

Applied.

--nab


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
  2013-11-19  8:07 ` [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED Hannes Reinecke
@ 2013-11-20 19:30   ` Nicholas A. Bellinger
  0 siblings, 0 replies; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:30 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> Rename ALUA_ACCESS_STATE_OPTMIZED to
> ALUA_ACCESS_STATE_OPTIMIZED.
> 

Applied.

--nab

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/18] target_core_alua: Store supported ALUA states
  2013-11-19  8:07 ` [PATCH 04/18] target_core_alua: Store supported ALUA states Hannes Reinecke
@ 2013-11-20 19:31   ` Nicholas A. Bellinger
  0 siblings, 0 replies; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:31 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> The supported ALUA states might be different for individual
> devices, so store it in a separate field.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.de>

Applied, with one minor change below..

> ---
>  drivers/target/target_core_alua.c | 14 ++++++++------
>  drivers/target/target_core_alua.h | 11 +++++++++++
>  include/target/target_core_base.h |  1 +
>  3 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
> index 08e41e3..a16115e 100644
> --- a/drivers/target/target_core_alua.c
> +++ b/drivers/target/target_core_alua.c
> @@ -117,12 +117,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
>  		/*
>  		 * Set supported ASYMMETRIC ACCESS State bits
>  		 */
> -		buf[off] = 0x80; /* T_SUP */
> -		buf[off] |= 0x40; /* O_SUP */
> -		buf[off] |= 0x8; /* U_SUP */
> -		buf[off] |= 0x4; /* S_SUP */
> -		buf[off] |= 0x2; /* AN_SUP */
> -		buf[off++] |= 0x1; /* AO_SUP */
> +		buf[off++] |= tg_pt_gp->tg_pt_gp_alua_supported_states;
>  		/*
>  		 * TARGET PORT GROUP
>  		 */
> @@ -1367,6 +1362,13 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
>  	tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
>  	tg_pt_gp->tg_pt_gp_implicit_trans_secs = ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
>  
> +	/*
> +	 * Enable all supported states
> +	 */
> +	tg_pt_gp->tg_pt_gp_alua_supported_states =
> +	    ALUA_T_SUP | ALUA_O_SUP | \
> +	    ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
> +

Dropping the unnecessary line continuation here..

--nab


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 05/18] target_core_alua: Make supported states configurable
  2013-11-19  8:07 ` [PATCH 05/18] target_core_alua: Make supported states configurable Hannes Reinecke
@ 2013-11-20 19:36   ` Nicholas A. Bellinger
  0 siblings, 0 replies; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:36 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---

Applied, with two minor changes below..

>  drivers/target/target_core_configfs.c | 50 +++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
> index 3a964fb..1e4ea28 100644
> --- a/drivers/target/target_core_configfs.c
> +++ b/drivers/target/target_core_configfs.c
> @@ -2131,6 +2131,55 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type(
>  SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
>  
>  /*
> + * alua_supported_states
> + */
> +static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_supported_states(
> +	struct t10_alua_tg_pt_gp *tg_pt_gp,
> +	char *page)
> +{
> +	return sprintf(page, "%02x\n",
> +		tg_pt_gp->tg_pt_gp_alua_supported_states);
> +}
> +
> +static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_supported_states(
> +	struct t10_alua_tg_pt_gp *tg_pt_gp,
> +	const char *page,
> +	size_t count)
> +{
> +	unsigned long tmp;
> +	int new_states, valid_states, ret;
> +
> +	if (!tg_pt_gp->tg_pt_gp_valid_id) {
> +		pr_err("Unable to do set supported ALUA states on non"
> +			" valid tg_pt_gp ID: %hu\n",
> +			tg_pt_gp->tg_pt_gp_valid_id);
> +		return -EINVAL;
> +	}
> +
> +	ret = strict_strtoul(page, 0, &tmp);
> +	if (ret < 0) {
> +		pr_err("Unable to extract new supported ALUA states"
> +				" from %s\n", page);
> +		return -EINVAL;
> +	}

Changed strict_strtoul() -> kstrtoul()

> +	new_states = (int)tmp;
> +	valid_states = ALUA_T_SUP | ALUA_O_SUP | ALUA_LBD_SUP | \
> +	    ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
> +

Dropping the unnecessary line continuation here..

--nab


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/18] target_core_configfs: split up ALUA supported states
  2013-11-19  8:07 ` [PATCH 06/18] target_core_configfs: split up ALUA supported states Hannes Reinecke
@ 2013-11-20 19:39   ` Nicholas A. Bellinger
  0 siblings, 0 replies; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-11-20 19:39 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> Split up the various ALUA states into individual attributes to
> make parsing easier and adhere to the one value per attribute
> sysfs principle.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---

Applied with one minor change below..

>  drivers/target/target_core_configfs.c | 127 ++++++++++++++++++++++------------
>  1 file changed, 84 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
> index 1e4ea28..8476f48 100644
> --- a/drivers/target/target_core_configfs.c
> +++ b/drivers/target/target_core_configfs.c

<SNIP>

> -SE_DEV_ALUA_TG_PT_ATTR(alua_supported_states, S_IRUGO | S_IWUSR);
> +#define SE_DEV_ALUA_SUPPORT_STATE_STORE(_name, _var, _bit)		\
> +static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
> +	struct t10_alua_tg_pt_gp *t, const char *p, size_t c)		\
> +{									\
> +	unsigned long tmp;						\
> +	int ret;							\
> +									\
> +	if (!t->tg_pt_gp_valid_id) {					\
> +		pr_err("Unable to do set ##_name ALUA state on non"	\
> +		       " valid tg_pt_gp ID: %hu\n",			\
> +		       t->tg_pt_gp_valid_id);				\
> +		return -EINVAL;						\
> +	}								\
> +									\
> +	ret = strict_strtoul(p, 0, &tmp);				\

Converted to kstrtoul()

--nab

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCHv2 00/18] ALUA update and Referrals support
  2013-11-20 19:22       ` Nicholas A. Bellinger
@ 2013-12-13 23:43         ` Nicholas A. Bellinger
  2013-12-17  8:20           ` Hannes Reinecke
  0 siblings, 1 reply; 31+ messages in thread
From: Nicholas A. Bellinger @ 2013-12-13 23:43 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: target-devel, linux-scsi

On Wed, 2013-11-20 at 11:22 -0800, Nicholas A. Bellinger wrote:
> On Wed, 2013-11-20 at 08:44 +0100, Hannes Reinecke wrote:
> > On 11/20/2013 01:06 AM, Nicholas A. Bellinger wrote:
> > > On Tue, 2013-11-19 at 15:42 -0800, Nicholas A. Bellinger wrote:
> > >> Hey Hannes!
> > >>
> > >> On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
> > >>> Hi Nic,
> > >>>
> > >>> here's the second version of my ALUA update & Referrals support patches.
> > >>> As per request I've split up the supported states into individual
> > >>> attributes, and while there I've also renamed the rather confusing
> > >>> 'alua_access_type' and 'alua_access_status' into 'alua_management_type'
> > >>> and 'alua_status_modification', respectively.
> > >>>
> 

<SNIP>

> > Okay, here's the thing:
> > The patchset can be split into three individual parts:
> > The ALUA update proper, which affects only the internal flow of
> > control (patches 1-6 and 11-16), then there's the ALUA configfs
> > modifications (patches 7-10) and the Referrals support (17 and 18).
> > If you have second thoughts you should be able to pull patches 7-10;
> > the rest will work as designed even without them.
> 
> Ok, I'm completely fine with patches 1-6, which only add new attributes
> and don't change input/output or rename existing attributes.
> 
> It's 7-10 that introduce the changes that are of concern..
> 
> > But then, there's not much difference on having all the patches in
> > for 3.13, and sort out the userspace then, or wait for the next
> > round and adjust the userspace during that time.
> > 
> 
> As much as I'd like to merge this now, the changes to existing
> attributes is what needs to be thought out some more, to avoid overt
> backwards compatibility ugliness.
> 
> > Anyway, I don't mind either way. You're the maintainer, you get to
> > decide. As least I got feedback about the patchset, which is more
> > than one can hope for nowadays :-(
> 
> Lets merge 1-6 now for v3.13, and I'll merge the rest for v3.14 into
> for-next as soon as -rc1 is released, and we can duke it out on the
> specific details starting next week.
> 

Ok, a bit longer than next week for getting back to this series, but now
I've a better idea where the user visable changes should end up.. 

What I'd really like to see for -v3 is:

Patch 7: Keep alua_access_state attribute store/show formatting (as is).
Patch 8: Keep alua_access_type attribute store/show formatting (as is)
         within a single attribute + drop support_* prefix to
         alua_supported_states attributes merged in v3.13
Patch 9: Drop alua_access_type attribute rename

So AFAICT none of these changes are strictly required to support
Referrals.  Granted, some of the early formatting decisions for these
ALUA attributes did not make a ton of sense, but regardless I very much
do not want name + formatting changes for existing attributes without a
really good reason.

I do like the usability aspects of the proposed name + formatting
changes, but these types of user facing things really should be
implemented at the rtslib + targetcli level, and not as changes to
existing configfs attributes.

That said, care to respin the series minus the above bits..?  ;)

Thank you,

--nab


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCHv2 00/18] ALUA update and Referrals support
  2013-12-13 23:43         ` Nicholas A. Bellinger
@ 2013-12-17  8:20           ` Hannes Reinecke
  0 siblings, 0 replies; 31+ messages in thread
From: Hannes Reinecke @ 2013-12-17  8:20 UTC (permalink / raw)
  To: Nicholas A. Bellinger; +Cc: target-devel, linux-scsi

On 12/14/2013 12:43 AM, Nicholas A. Bellinger wrote:
> On Wed, 2013-11-20 at 11:22 -0800, Nicholas A. Bellinger wrote:
>> On Wed, 2013-11-20 at 08:44 +0100, Hannes Reinecke wrote:
>>> On 11/20/2013 01:06 AM, Nicholas A. Bellinger wrote:
>>>> On Tue, 2013-11-19 at 15:42 -0800, Nicholas A. Bellinger wrote:
>>>>> Hey Hannes!
>>>>>
>>>>> On Tue, 2013-11-19 at 09:07 +0100, Hannes Reinecke wrote:
>>>>>> Hi Nic,
>>>>>>
>>>>>> here's the second version of my ALUA update & Referrals support patches.
>>>>>> As per request I've split up the supported states into individual
>>>>>> attributes, and while there I've also renamed the rather confusing
>>>>>> 'alua_access_type' and 'alua_access_status' into 'alua_management_type'
>>>>>> and 'alua_status_modification', respectively.
>>>>>>
>>
> 
> <SNIP>
> 
>>> Okay, here's the thing:
>>> The patchset can be split into three individual parts:
>>> The ALUA update proper, which affects only the internal flow of
>>> control (patches 1-6 and 11-16), then there's the ALUA configfs
>>> modifications (patches 7-10) and the Referrals support (17 and 18).
>>> If you have second thoughts you should be able to pull patches 7-10;
>>> the rest will work as designed even without them.
>>
>> Ok, I'm completely fine with patches 1-6, which only add new attributes
>> and don't change input/output or rename existing attributes.
>>
>> It's 7-10 that introduce the changes that are of concern..
>>
>>> But then, there's not much difference on having all the patches in
>>> for 3.13, and sort out the userspace then, or wait for the next
>>> round and adjust the userspace during that time.
>>>
>>
>> As much as I'd like to merge this now, the changes to existing
>> attributes is what needs to be thought out some more, to avoid overt
>> backwards compatibility ugliness.
>>
>>> Anyway, I don't mind either way. You're the maintainer, you get to
>>> decide. As least I got feedback about the patchset, which is more
>>> than one can hope for nowadays :-(
>>
>> Lets merge 1-6 now for v3.13, and I'll merge the rest for v3.14 into
>> for-next as soon as -rc1 is released, and we can duke it out on the
>> specific details starting next week.
>>
> 
> Ok, a bit longer than next week for getting back to this series, but now
> I've a better idea where the user visable changes should end up.. 
> 
> What I'd really like to see for -v3 is:
> 
> Patch 7: Keep alua_access_state attribute store/show formatting (as is).
> Patch 8: Keep alua_access_type attribute store/show formatting (as is)
>          within a single attribute + drop support_* prefix to
>          alua_supported_states attributes merged in v3.13
> Patch 9: Drop alua_access_type attribute rename
> 
> So AFAICT none of these changes are strictly required to support
> Referrals.  Granted, some of the early formatting decisions for these
> ALUA attributes did not make a ton of sense, but regardless I very much
> do not want name + formatting changes for existing attributes without a
> really good reason.
> 
> I do like the usability aspects of the proposed name + formatting
> changes, but these types of user facing things really should be
> implemented at the rtslib + targetcli level, and not as changes to
> existing configfs attributes.
> 
So the current interface is cast in stone forever?
Seriously?

How does one go about modifying configfs?
There _is_ a version number in /sys/kernel/config, which is supposed
to give some hints here.

And it's far easier implementing a fallback in rtslib + targetcli;
having two attributes in the kernel for exposing the old and the
new interface is not what I would call elegant.

But then I'm not the maintainer :-)

And as I've now separated those two issues we're having more
time discussing this :-)

> That said, care to respin the series minus the above bits..?  ;)
> 
Ok, done.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2013-12-17  8:20 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-19  8:07 [PATCHv2 00/18] ALUA update and Referrals support Hannes Reinecke
2013-11-19  8:07 ` [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit Hannes Reinecke
2013-11-20 19:29   ` Nicholas A. Bellinger
2013-11-19  8:07 ` [PATCH 02/18] target_core_alua: spellcheck Hannes Reinecke
2013-11-20 19:30   ` Nicholas A. Bellinger
2013-11-19  8:07 ` [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED Hannes Reinecke
2013-11-20 19:30   ` Nicholas A. Bellinger
2013-11-19  8:07 ` [PATCH 04/18] target_core_alua: Store supported ALUA states Hannes Reinecke
2013-11-20 19:31   ` Nicholas A. Bellinger
2013-11-19  8:07 ` [PATCH 05/18] target_core_alua: Make supported states configurable Hannes Reinecke
2013-11-20 19:36   ` Nicholas A. Bellinger
2013-11-19  8:07 ` [PATCH 06/18] target_core_configfs: split up ALUA supported states Hannes Reinecke
2013-11-20 19:39   ` Nicholas A. Bellinger
2013-11-19  8:07 ` [PATCH 07/18] target_core_configfs: Verbose ALUA state display Hannes Reinecke
2013-11-19  8:07 ` [PATCH 08/18] target_core_configfs: Split up ALUA access type Hannes Reinecke
2013-11-19  8:07 ` [PATCH 09/18] target_core: Rename alua_access_type in alua_mgmt_type Hannes Reinecke
2013-11-19  8:07 ` [PATCH 10/18] target_core: Rename alua_access_status to alua_status_modification Hannes Reinecke
2013-11-19  8:07 ` [PATCH 11/18] target_core_alua: Validate ALUA state transition Hannes Reinecke
2013-11-19  8:07 ` [PATCH 12/18] target_core_alua: Allocate ALUA metadata on demand Hannes Reinecke
2013-11-19  8:07 ` [PATCH 13/18] target_core_alua: store old and pending ALUA state Hannes Reinecke
2013-11-19  8:07 ` [PATCH 14/18] target_core_alua: Use workqueue for ALUA transitioning Hannes Reinecke
2013-11-19  8:08 ` [PATCH 15/18] target_core: simplify scsi_name_len calculation Hannes Reinecke
2013-11-19  8:08 ` [PATCH 16/18] target_core_spc: Include target device descriptor in VPD page 83 Hannes Reinecke
2013-11-19  8:08 ` [PATCH 17/18] target_core_alua: Referrals infrastructure Hannes Reinecke
2013-11-19  8:08 ` [PATCH 18/18] target_core_alua: Referrals configfs integration Hannes Reinecke
2013-11-19 23:42 ` [PATCHv2 00/18] ALUA update and Referrals support Nicholas A. Bellinger
2013-11-20  0:06   ` Nicholas A. Bellinger
2013-11-20  7:44     ` Hannes Reinecke
2013-11-20 19:22       ` Nicholas A. Bellinger
2013-12-13 23:43         ` Nicholas A. Bellinger
2013-12-17  8:20           ` Hannes Reinecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).