From f835be1355dd887437d0f6f728a0091583f97f30 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 3 May 2015 09:09:38 +0200 Subject: [PATCH] scst_sysfs: Do not suspend I/O for LUN management The previous patches make it safe to remove a LUN from sess_tgt_dev_list while I/O is in progress. Hence this patch that allows LUN management without suspending I/O. Signed-off-by: Bart Van Assche --- scst/src/scst_lib.c | 28 ++++++++++++++++++++++++++++ scst/src/scst_sysfs.c | 9 +-------- scst/src/scst_targ.c | 1 + 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index dfb888fa7..8123abe69 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -4308,6 +4308,23 @@ out: return acg_dev; } +static int scst_tgt_devs_cmds(struct list_head *tgt_dev_list) +{ + struct scst_tgt_dev *tgt_dev; + int res = 0; + + list_for_each_entry(tgt_dev, tgt_dev_list, extra_tgt_dev_list_entry) + res += atomic_read(&tgt_dev->tgt_dev_cmd_count); + + return res; +} + +static void scst_wait_for_tgt_devs(struct list_head *tgt_dev_list) +{ + while (scst_tgt_devs_cmds(tgt_dev_list) > 0) + mdelay(100); +} + int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun, bool gen_scst_report_luns_changed) { @@ -4329,6 +4346,12 @@ int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun, if (gen_scst_report_luns_changed) scst_report_luns_changed(acg); + mutex_unlock(&scst_mutex); + + scst_wait_for_tgt_devs(&tgt_dev_list); + + mutex_lock(&scst_mutex); + list_for_each_entry_safe(tgt_dev, tt, &tgt_dev_list, extra_tgt_dev_list_entry) { scst_free_tgt_dev(tgt_dev); @@ -4377,6 +4400,11 @@ int scst_acg_repl_lun(struct scst_acg *acg, struct kobject *parent, } } } + mutex_unlock(&scst_mutex); + + scst_wait_for_tgt_devs(&tgt_dev_list); + + mutex_lock(&scst_mutex); list_for_each_entry_safe(tgt_dev, tt, &tgt_dev_list, extra_tgt_dev_list_entry) { scst_free_tgt_dev(tgt_dev); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index e47da42c4..2165aace7 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -1374,13 +1374,9 @@ static int __scst_process_luns_mgmt_store(char *buffer, goto out; } - res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); - if (res != 0) - goto out; - res = mutex_lock_interruptible(&scst_mutex); if (res != 0) - goto out_resume; + goto out; /* Check if tgt and acg not already freed while we were coming here */ if (scst_check_tgt_acg_ptrs(tgt, acg) != 0) @@ -1488,9 +1484,6 @@ static int __scst_process_luns_mgmt_store(char *buffer, out_unlock: mutex_unlock(&scst_mutex); -out_resume: - scst_resume_activity(); - out: TRACE_EXIT_RES(res); return res; diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index d8cf6e33c..77e9ee343 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -3971,6 +3971,7 @@ static int scst_pre_xmit_response1(struct scst_cmd *cmd) * Those counters protect from not getting too long processing * latency, so we should decrement them after cmd completed. */ + smp_mb__before_atomic_dec(); atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count); #ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT atomic_dec(&cmd->dev->dev_cmd_count);