On Tue, 2013-12-17 at 09:18 +0100, 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 <h...@suse.de>
> ---
>  drivers/target/target_core_alua.c | 55 
> ++++++++++++++++++++++++++++++++-------
>  1 file changed, 45 insertions(+), 10 deletions(-)
> 

Applied to for-next.

Thanks Hannes!

--nab

> diff --git a/drivers/target/target_core_alua.c 
> b/drivers/target/target_core_alua.c
> index fdcee32..292ecce 100644
> --- a/drivers/target/target_core_alua.c
> +++ b/drivers/target/target_core_alua.c
> @@ -41,11 +41,14 @@
>  #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);
>  
> +static char *core_alua_dump_state(int state);
> +
>  static u16 alua_lu_gps_counter;
>  static u32 alua_lu_gps_count;
>  
> @@ -210,7 +213,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 +255,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 +267,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
> @@ -618,17 +623,31 @@ out:
>   * 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,14 +655,27 @@ 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;
> +     case ALUA_ACCESS_STATE_TRANSITION:
> +             /*
> +              * Transitioning is set internally, and
> +              * cannot be selected manually.
> +              */
> +             goto not_supported;
>       default:
>               pr_err("Unknown ALUA access state: 0x%02x\n", state);
>               return TCM_INVALID_PARAMETER_LIST;
>       }
>  
>       return 0;
> +
> +not_supported:
> +     pr_err("ALUA access state %s not supported",
> +            core_alua_dump_state(state));
> +     return TCM_INVALID_PARAMETER_LIST;
>  }
>  
>  static char *core_alua_dump_state(int state)
> @@ -659,6 +691,8 @@ static 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";
>       }
> @@ -884,9 +918,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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to