ALUA update and Referrals support
Subsystems (2)
v2 cover ALUA update and Referrals support
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(-)
Signature · 1 line
1.7.12.4
PATCH v2 1/18 target core: rename (ex,im)plict -> (ex,im)plicit
--- 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(-)
drivers/target/target_core_alua.c +55 -55
@@ -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 ;
drivers/target/target_core_alua.h +10 -10
@@ -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 *);
drivers/target/target_core_configfs.c +13 -13
@@ -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,
drivers/target/target_core_device.c +3 -3
@@ -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 ; }
drivers/target/target_core_file.c +1 -1
@@ -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. */
drivers/target/target_core_pr.c +12 -12
@@ -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
drivers/target/target_core_spc.c +3 -3
@@ -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 ;
drivers/target/target_core_transport.c +2 -2
@@ -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 &&
drivers/target/target_core_ua.h +1 -1
@@ -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
include/target/target_core_base.h +1 -1
@@ -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 */
Signature · 1 line
1.7.12.4
Nicholas A. Bellinger
AppliedRe: [PATCH 01/18] target core: rename (ex,im)plict -> (ex,im)plicit
Quoted 13 lines · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>--- 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
PATCH v2 2/18 target_core_alua: spellcheck
In reply to Hannes Reinecke--- drivers/target/target_core_alua.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/target/target_core_alua.c +9 -9
@@ -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);
Signature · 1 line
1.7.12.4
Nicholas A. Bellinger
AppliedRe: [PATCH 02/18] target_core_alua: spellcheck
Quoted 4 lines · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>--- drivers/target/target_core_alua.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
Applied.
--nab
PATCH v2 3/18 target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
In reply to Hannes ReineckeRename ALUA_ACCESS_STATE_OPTMIZED toALUA_ACCESS_STATE_OPTIMIZED.
--- drivers/target/target_core_alua.c | 10 +++++----- drivers/target/target_core_alua.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/target/target_core_alua.c +5 -5
@@ -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 */
drivers/target/target_core_alua.h +1 -1
@@ -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
Signature · 1 line
1.7.12.4
Nicholas A. Bellinger
AppliedRe: [PATCH 03/18] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
Quoted 3 lines · Hannes Reinecke
Rename
ALUA_ACCESS_STATE_OPTMIZEDtoALUA_ACCESS_STATE_OPTIMIZED.
Applied.
--nab
PATCH v2 4/18 target_core_alua: Store supported ALUA states
In reply to Hannes ReineckeThe supported ALUA states might be different for individual devices, so store it in a separate field.
--- 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(-)
drivers/target/target_core_alua.c +8 -6
@@ -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 =
drivers/target/target_core_alua.h +11 -0
@@ -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
include/target/target_core_base.h +1 -0
@@ -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;
Signature · 1 line
1.7.12.4
Nicholas A. Bellinger
AppliedRe: [PATCH 04/18] target_core_alua: Store supported ALUA states
Quoted 4 lines · Hannes Reinecke
The supported ALUA states might be different for individual devices, so store it in a separate field.
Signed-off-by Hannes Reinecke <[email protected]>
Applied, with one minor change below..
Quoted 25 lines
--- 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(-)drivers/target/target_core_alua.c +1
-6@@ -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 */
drivers/target/target_core_alua.c struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev, · line 1371
Quoted 10 lines
drivers/target/target_core_alua.c +7
-0@@ -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
PATCH v2 5/18 target_core_alua: Make supported states configurable
In reply to Hannes Reinecke--- drivers/target/target_core_configfs.c | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
drivers/target/target_core_configfs.c +50 -0
@@ -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,
Signature · 1 line
1.7.12.4
Nicholas A. Bellinger
AppliedRe: [PATCH 05/18] target_core_alua: Make supported states configurable
Quoted 2 lines · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>---
Applied, with two minor changes below..
Quoted 32 lines
drivers/target/target_core_configfs.c | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)drivers/target/target_core_configfs.c +21
-0@@ -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",
drivers/target/target_core_configfs.c static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type( · line 2164
Quoted 10 lines
drivers/target/target_core_configfs.c +10
-0+ 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()
drivers/target/target_core_configfs.c static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type( · line 2168
Quoted 4 lines
drivers/target/target_core_configfs.c +4
-0+ 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
PATCH v2 6/18 target_core_configfs: split up ALUA supported states
In reply to Hannes ReineckeSplit up the various ALUA states into individual attributes to make parsing easier and adhere to the one value per attribute sysfs principle.
--- drivers/target/target_core_configfs.c | 127 ++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 43 deletions(-)
drivers/target/target_core_configfs.c +84 -43
@@ -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,
Signature · 1 line
1.7.12.4
Re: [PATCH 06/18] target_core_configfs: split up ALUA supported states
Quoted 6 lines · 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 <[email protected]>---
Applied with one minor change below..
Quoted 7 lines
drivers/target/target_core_configfs.c | 127 ++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 43 deletions(-)drivers/target/target_core_configfs.c +0
-0
<SNIP>
Quoted 6 lines
drivers/target/target_core_configfs.c +5
-1-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; \
drivers/target/target_core_configfs.c SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR); · line 2158
Quoted 10 lines
drivers/target/target_core_configfs.c +10
-0+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
PATCH v2 7/18 target_core_configfs: Verbose ALUA state display
In reply to Hannes ReineckeInstead of printing out the ALUA state number we should be using proper strings; this helps administration and reduces confusion.
--- 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(-)
drivers/target/target_core_alua.c +17 -1
@@ -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) {
drivers/target/target_core_alua.h +2 -0
@@ -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 );
drivers/target/target_core_configfs.c +14 -10
@@ -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 ;
Signature · 1 line
1.7.12.4
PATCH v2 8/18 target_core_configfs: Split up ALUA access type
In reply to Hannes ReineckeInstead of lumping two independent values into one attribute we should be using on attribute per value.
--- 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(-)
drivers/target/target_core_alua.c +0 -46
@@ -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)
drivers/target/target_core_alua.h +0 -3
@@ -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 *,
drivers/target/target_core_configfs.c +38 -41
129 lines not on this page · raw message
Signature · 1 line
1.7.12.4
PATCH v2 9/18 target_core: Rename alua_access_type in alua_mgmt_type
In reply to Hannes Reinecke'alua_access_type' is not very descriptive and leads to confusion, so rename it to 'alua_mgmt_type'.
--- 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(-)
drivers/target/target_core_alua.c +5 -5
@@ -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 */
drivers/target/target_core_alua.h +3 -3
@@ -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
drivers/target/target_core_configfs.c +16 -16
@@ -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,
drivers/target/target_core_spc.c +1 -1
@@ -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); }
include/target/target_core_base.h +1 -1
@@ -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;
Signature · 1 line
1.7.12.4
PATCH v2 10/18 target_core: Rename alua_access_status to alua_status_modification
In reply to Hannes ReineckeIt 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.
--- 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(-)
drivers/target/target_core_alua.c +5 -5
@@ -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));
drivers/target/target_core_configfs.c +7 -7
@@ -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,
include/target/target_core_base.h +1 -1
@@ -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;
Signature · 1 line
1.7.12.4
PATCH v2 11/18 target_core_alua: Validate ALUA state transition
In reply to Hannes ReineckeAs we now can modify the list of supported states we need to validate the requested ALUA state when doing a state transition.
--- drivers/target/target_core_alua.c | 117 +++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 45 deletions(-)
drivers/target/target_core_alua.c +72 -45
@@ -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 );
Signature · 1 line
1.7.12.4
PATCH v2 12/18 target_core_alua: Allocate ALUA metadata on demand
In reply to Hannes ReineckeWe should only allocate ALUA metadata if we're actually going to write them.
--- 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(-)
drivers/target/target_core_alua.c +31 -39
@@ -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 );/*
drivers/target/target_core_alua.h +3 -0
@@ -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;
include/target/target_core_base.h +0 -3
@@ -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;
Signature · 1 line
1.7.12.4
PATCH v2 13/18 target_core_alua: store old and pending ALUA state
In reply to Hannes ReineckeDuring state transition we should be storing both the original and the pending state.
--- drivers/target/target_core_alua.c | 15 ++++++++++----- include/target/target_core_base.h | 6 ++++-- 2 files changed, 14 insertions(+), 7 deletions(-)
drivers/target/target_core_alua.c +10 -5
@@ -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 ; }
include/target/target_core_base.h +4 -2
@@ -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;
Signature · 1 line
1.7.12.4
PATCH v2 14/18 target_core_alua: Use workqueue for ALUA transitioning
In reply to Hannes ReineckeUse a workqueue for processing ALUA state transitions; this allows us to process implicit delay properly.
--- drivers/target/target_core_alua.c | 174 +++++++++++++++++++++++++++----------- include/target/target_core_base.h | 4 + 2 files changed, 128 insertions(+), 50 deletions(-)
drivers/target/target_core_alua.c +124 -50
@@ -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
include/target/target_core_base.h +4 -0
@@ -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 {
Signature · 1 line
1.7.12.4
PATCH v2 15/18 target_core: simplify scsi_name_len calculation
In reply to Hannes Reineckescsi_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.
--- drivers/target/target_core_spc.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/target/target_core_spc.c +3 -10
@@ -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;
Signature · 1 line
1.7.12.4
PATCH v2 16/18 target_core_spc: Include target device descriptor in VPD page 83
In reply to Hannes ReineckeWe should be including a descriptor referring to the target device to allow identification of different TCM instances.
--- drivers/target/target_core_spc.c | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-)
drivers/target/target_core_spc.c +42 -1
@@ -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 */
Signature · 1 line
1.7.12.4
PATCH v2 17/18 target_core_alua: Referrals infrastructure
In reply to Hannes ReineckeAdd infrastructure for referrals.
--- 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(-)
drivers/target/target_core_alua.c +155 -0
@@ -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
drivers/target/target_core_alua.h +3 -1
@@ -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 *,
drivers/target/target_core_configfs.c +8 -1
@@ -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 );
drivers/target/target_core_device.c +2 -0
@@ -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;
drivers/target/target_core_sbc.c +4 -1
@@ -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 );
drivers/target/target_core_spc.c +20 -0
@@ -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 */
include/scsi/scsi.h +1 -0
@@ -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
include/target/target_core_base.h +18 -0
@@ -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 */
Signature · 1 line
1.7.12.4
PATCH v2 18/18 target_core_alua: Referrals configfs integration
In reply to Hannes ReineckeReferrals 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.
--- 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(-)
drivers/target/target_core_alua.c +101 -0
@@ -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) {
drivers/target/target_core_alua.h +8 -0
@@ -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 *);
drivers/target/target_core_configfs.c +171 -0
183 lines not on this page · raw message
drivers/target/target_core_device.c +1 -0
@@ -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);
drivers/target/target_core_transport.c +27 -1
@@ -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. */
Signature · 1 line
1.7.12.4
Hey Hannes!
Quoted 24 lines · 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.
Quoted 2 lines
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
Quoted 32 lines · Nicholas A. Bellinger
Hey Hannes!
Quoted 24 lines · 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.Quoted 2 lines
And, of course, referrals support.
Ok, even though it is late, I've applied this series to for-next.
Quoted 8 lines
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
Quoted 42 lines · Nicholas A. Bellinger
Quoted 32 lines · Nicholas A. Bellinger
Hey Hannes!
Quoted 24 lines · 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.Quoted 2 lines
And, of course, referrals support.
Ok, even though it is late, I've applied this series to for-next.
Quoted 8 lines
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.
Quoted 9 lines
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?
Quoted 6 lines
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
Signature · 4 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +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)
Quoted 13 lines · Hannes Reinecke
Quoted 12 lines · Nicholas A. Bellinger
Quoted 11 lines · Nicholas A. Bellinger
Hey Hannes!
Quoted 8 lines · 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.
<SNIP>
Quoted 12 lines
Quoted 10 lines
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?
Quoted 9 lines
Quoted 6 lines
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. ;)
Quoted 7 lines
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..
Quoted 4 lines
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.
Quoted 3 lines
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
Quoted 15 lines · Nicholas A. Bellinger
Quoted 13 lines · Hannes Reinecke
Quoted 12 lines · Nicholas A. Bellinger
Quoted 11 lines · Nicholas A. Bellinger
Hey Hannes!
Quoted 8 lines · 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.
<SNIP>
Quoted 22 lines
Quoted 7 lines
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..
Quoted 4 lines
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.
Quoted 8 lines
Quoted 3 lines
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
Quoted 67 lines · Nicholas A. Bellinger
Quoted 15 lines · Nicholas A. Bellinger
Quoted 13 lines · Hannes Reinecke
Quoted 12 lines · Nicholas A. Bellinger
Quoted 11 lines · Nicholas A. Bellinger
Hey Hannes!
Quoted 8 lines · 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.<SNIP>
Quoted 22 lines
Quoted 7 lines
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..
Quoted 4 lines
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.
Quoted 8 lines
Quoted 3 lines
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_stateattribute store/show formatting (as is). Patch 8: Keepalua_access_typeattribute store/show formatting (as is)
within a single attribute + drop support_* prefix toalua_supported_statesattributes merged in v3.13
Patch 9: Dropalua_access_typeattribute renameSo 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.
Quoted 5 lines
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 :-)
Quoted 2 lines
That said, care to respin the series minus the above bits..? ;)
Ok, done.
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +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)