From f59e86a6597e28572128885ad2744d50460d35ba Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Fri, 11 Mar 2016 03:10:04 +0000 Subject: [PATCH] This limits target group state changes to only apply to targets local to the host. This prevents the devices being blocked offline by changes to non-local targets. Signed-off-by: Adrian Saul with some minor corrections git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6827 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_tg.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index b610fa6f9..b8cc4456c 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -962,6 +962,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, struct scst_tg_tgt *tg_tgt; struct scst_tgt *tgt; enum scst_tg_state old_state = tg->state; + bool dev_changed; sBUG_ON(state >= ARRAY_SIZE(scst_alua_filter)); lockdep_assert_held(&scst_dg_mutex); @@ -973,8 +974,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, list_for_each_entry(dg_dev, &tg->dg->dev_list, entry) { dev = dg_dev->dev; - if (dev->handler->on_alua_state_change_start != NULL) - dev->handler->on_alua_state_change_start(dev, old_state, state); + dev_changed = false; list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { tgt = tgt_dev->sess->tgt; @@ -982,6 +982,11 @@ static void __scst_tg_set_state(struct scst_target_group *tg, if (tg_tgt->tgt == tgt) { bool gen_ua = (state != SCST_TG_STATE_TRANSITIONING); + if ((dev->handler->on_alua_state_change_start != NULL) && !dev_changed) { + dev->handler->on_alua_state_change_start(dev, old_state, state); + dev_changed = true; + } + if ((tg->dg->stpg_rel_tgt_id == tgt_dev->sess->tgt->rel_tgt_id) && tid_equal(tg->dg->stpg_transport_id, tgt_dev->sess->transport_id)) gen_ua = false; @@ -991,7 +996,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, } } } - if (dev->handler->on_alua_state_change_finish != NULL) + if ((dev->handler->on_alua_state_change_finish != NULL) && dev_changed) dev->handler->on_alua_state_change_finish(dev, old_state, state); }