diff options
author | Hannes Reinecke <hare@suse.de> | 2015-06-11 10:01:24 +0200 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-06-16 00:38:27 -0700 |
commit | ee8c07d0c32622b6fa44108b0141434575e43188 (patch) | |
tree | 444e57178c7910a7f43c5808a5fcd6617d4353e8 | |
parent | 0fb1f14e88f6f814fc578d0b8b3de666d1c9327e (diff) | |
download | op-kernel-dev-ee8c07d0c32622b6fa44108b0141434575e43188.zip op-kernel-dev-ee8c07d0c32622b6fa44108b0141434575e43188.tar.gz |
target_core_alua: Correct UA handling when switching states
When switching target port group ALUA states we need to send
one UA when setting the ALUA state to 'transitioning', and
another one once the final state has been set.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_alua.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 2318e6e..228a3c7 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -941,16 +941,11 @@ static int core_alua_update_tpg_primary_metadata( return rc; } -static void core_alua_do_transition_tg_pt_work(struct work_struct *work) +static void core_alua_queue_state_change_ua(struct t10_alua_tg_pt_gp *tg_pt_gp) { - 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 *lun; struct se_lun_acl *lacl; - bool explicit = (tg_pt_gp->tg_pt_gp_alua_access_status == - ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG); spin_lock(&tg_pt_gp->tg_pt_gp_lock); list_for_each_entry(lun, &tg_pt_gp->tg_pt_gp_lun_list, @@ -1002,6 +997,16 @@ static void core_alua_do_transition_tg_pt_work(struct work_struct *work) percpu_ref_put(&lun->lun_ref); } spin_unlock(&tg_pt_gp->tg_pt_gp_lock); +} + +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; + bool explicit = (tg_pt_gp->tg_pt_gp_alua_access_status == + ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG); + /* * Update the ALUA metadata buf that has been allocated in * core_alua_do_port_transition(), this metadata will be written @@ -1031,6 +1036,9 @@ static void core_alua_do_transition_tg_pt_work(struct work_struct *work) 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)); + + core_alua_queue_state_change_ua(tg_pt_gp); + spin_lock(&dev->t10_alua.tg_pt_gps_lock); atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); spin_unlock(&dev->t10_alua.tg_pt_gps_lock); @@ -1083,6 +1091,8 @@ static int core_alua_do_transition_tg_pt( ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG : ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA; + core_alua_queue_state_change_ua(tg_pt_gp); + /* * Check for the optional ALUA primary state transition delay */ |