Re: [PATCH 06/11] target_core_alua: Validate ALUA state transition

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

 



On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
> As we now can modify the list of supported states we need to
> validate the requested ALUA state when doing a state transition.
> 
> Signed-off-by: Hannes Reinecke <hare@xxxxxxx>
> ---

Looks good.

--nab

>  drivers/target/target_core_alua.c | 85 ++++++++++++++++++++++++++-------------
>  1 file changed, 56 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
> index a16115e..a420778 100644
> --- a/drivers/target/target_core_alua.c
> +++ b/drivers/target/target_core_alua.c
> @@ -41,7 +41,8 @@
>  #include "target_core_alua.h"
>  #include "target_core_ua.h"
>  
> -static sense_reason_t core_alua_check_transition(int state, int *primary);
> +static sense_reason_t core_alua_check_transition(int state, int valid,
> +						 int *primary);
>  static int core_alua_set_tg_pt_secondary_state(
>  		struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
>  		struct se_port *port, int explicit, int offline);
> @@ -210,7 +211,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
>  	unsigned char *ptr;
>  	sense_reason_t rc = TCM_NO_SENSE;
>  	u32 len = 4; /* Skip over RESERVED area in header */
> -	int alua_access_state, primary = 0;
> +	int alua_access_state, primary = 0, valid_states;
>  	u16 tg_pt_id, rtpi;
>  
>  	if (!l_port)
> @@ -252,6 +253,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
>  		rc = TCM_UNSUPPORTED_SCSI_OPCODE;
>  		goto out;
>  	}
> +	valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states;
>  
>  	ptr = &buf[4]; /* Skip over RESERVED area in header */
>  
> @@ -263,7 +265,8 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
>  		 * the state is a primary or secondary target port asymmetric
>  		 * access state.
>  		 */
> -		rc = core_alua_check_transition(alua_access_state, &primary);
> +		rc = core_alua_check_transition(alua_access_state,
> +						valid_states, &primary);
>  		if (rc) {
>  			/*
>  			 * If the SET TARGET PORT GROUPS attempts to establish
> @@ -614,21 +617,57 @@ out:
>  	return 0;
>  }
>  
> +static char *core_alua_dump_state(int state)
> +{
> +	switch (state) {
> +	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
> +		return "Active/Optimized";
> +	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
> +		return "Active/NonOptimized";
> +	case ALUA_ACCESS_STATE_STANDBY:
> +		return "Standby";
> +	case ALUA_ACCESS_STATE_UNAVAILABLE:
> +		return "Unavailable";
> +	case ALUA_ACCESS_STATE_OFFLINE:
> +		return "Offline";
> +	case ALUA_ACCESS_STATE_TRANSITION:
> +		return "Transitioning";
> +	default:
> +		return "Unknown";
> +	}
> +
> +	return NULL;
> +}
> +
>  /*
>   * Check implicit and explicit ALUA state change request.
>   */
>  static sense_reason_t
> -core_alua_check_transition(int state, int *primary)
> +core_alua_check_transition(int state, int valid, int *primary)
>  {
> +	/*
> +	 * 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:
> -		/*
> -		 * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
> -		 * defined as primary target port asymmetric access states.
> -		 */
> +		if (!(valid & ALUA_U_SUP))
> +			goto not_supported;
>  		*primary = 1;
>  		break;
>  	case ALUA_ACCESS_STATE_OFFLINE:
> @@ -636,6 +675,8 @@ core_alua_check_transition(int state, int *primary)
>  		 * OFFLINE state is defined as a secondary target port
>  		 * asymmetric access state.
>  		 */
> +		if (!(valid & ALUA_O_SUP))
> +			goto not_supported;
>  		*primary = 0;
>  		break;
>  	default:
> @@ -644,26 +685,11 @@ core_alua_check_transition(int state, int *primary)
>  	}
>  
>  	return 0;
> -}
>  
> -static char *core_alua_dump_state(int state)
> -{
> -	switch (state) {
> -	case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
> -		return "Active/Optimized";
> -	case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
> -		return "Active/NonOptimized";
> -	case ALUA_ACCESS_STATE_STANDBY:
> -		return "Standby";
> -	case ALUA_ACCESS_STATE_UNAVAILABLE:
> -		return "Unavailable";
> -	case ALUA_ACCESS_STATE_OFFLINE:
> -		return "Offline";
> -	default:
> -		return "Unknown";
> -	}
> -
> -	return NULL;
> +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)
> @@ -884,9 +910,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);


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




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux