diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 3de9fbc56..d7b1c6ba6 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -14101,31 +14101,37 @@ int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun) } if (lun != NO_SUCH_LUN) { - struct list_head *head = - &sess->sess_tgt_dev_list[SESS_TGT_DEV_LIST_HASH_FN(lun)]; + struct list_head *head; struct scst_tgt_dev *tgt_dev; - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { + rcu_read_lock(); + head = &sess->sess_tgt_dev_list[SESS_TGT_DEV_LIST_HASH_FN(lun)]; + + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt_dev->lun == lun) { res = tgt_dev->dev->max_tgt_dev_commands; - TRACE_DBG("tgt_dev %p, dev %s, max_tgt_dev_commands " - "%d (res %d)", tgt_dev, tgt_dev->dev->virt_name, - tgt_dev->dev->max_tgt_dev_commands, res); + TRACE_DBG("tgt_dev %p, dev %s, max_tgt_dev_commands %d (res %d)", + tgt_dev, tgt_dev->dev->virt_name, + tgt_dev->dev->max_tgt_dev_commands, res); break; } } + rcu_read_unlock(); + goto out_unlock; } + rcu_read_lock(); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { if (res > tgt_dev->dev->max_tgt_dev_commands) res = tgt_dev->dev->max_tgt_dev_commands; } } + rcu_read_unlock(); out_unlock: mutex_unlock(&scst_mutex); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index b5d1cfe4f..14db1349b 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -2557,11 +2557,12 @@ static ssize_t scst_tgt_forward_dst_store(struct kobject *kobj, list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { int i; + rcu_read_lock(); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { + list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt->tgt_forward_dst) set_bit(SCST_TGT_DEV_FORWARD_DST, &tgt_dev->tgt_dev_flags); @@ -2570,6 +2571,7 @@ static ssize_t scst_tgt_forward_dst_store(struct kobject *kobj, &tgt_dev->tgt_dev_flags); } } + rcu_read_unlock(); } if (tgt->tgt_forward_dst) diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index d57a7067a..8667b3bbc 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -6153,7 +6153,6 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd, int res; int i; struct scst_session *sess = mcmd->sess; - struct scst_tgt_dev *tgt_dev; TRACE_ENTRY(); @@ -6168,6 +6167,7 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd, rcu_read_lock(); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + struct scst_tgt_dev *tgt_dev; list_for_each_entry_rcu(tgt_dev, head, sess_tgt_dev_list_entry) { @@ -6175,8 +6175,8 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd, scst_call_dev_task_mgmt_fn_received(mcmd, tgt_dev); - tm_dbg_task_mgmt(tgt_dev->dev, "NEXUS LOSS SESS or " - "ABORT ALL SESS or UNREG SESS", + tm_dbg_task_mgmt(tgt_dev->dev, + "NEXUS LOSS SESS or ABORT ALL SESS or UNREG SESS", (mcmd->fn == SCST_UNREG_SESS_TM)); } if (nexus_loss_unreg_sess) { @@ -6184,7 +6184,8 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd, * We need at first abort all affected commands and * only then release them as part of clearing ACA */ - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { + list_for_each_entry_rcu(tgt_dev, head, + sess_tgt_dev_list_entry) { scst_clear_aca(tgt_dev, (tgt_dev != mcmd->mcmd_tgt_dev)); } @@ -6253,22 +6254,23 @@ static int scst_abort_all_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd, struct scst_tgt_dev *tgt_dev; list_for_each_entry_rcu(tgt_dev, head, - sess_tgt_dev_list_entry) { + sess_tgt_dev_list_entry) { __scst_abort_task_set(mcmd, tgt_dev); if (mcmd->sess == tgt_dev->sess) scst_call_dev_task_mgmt_fn_received( mcmd, tgt_dev); - tm_dbg_task_mgmt(tgt_dev->dev, "NEXUS LOSS or " - "ABORT ALL", 0); + tm_dbg_task_mgmt(tgt_dev->dev, + "NEXUS LOSS or ABORT ALL", 0); } if (nexus_loss) { /* * We need at first abort all affected commands and * only then release them as part of clearing ACA */ - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { + list_for_each_entry_rcu(tgt_dev, head, + sess_tgt_dev_list_entry) { scst_clear_aca(tgt_dev, (tgt_dev != mcmd->mcmd_tgt_dev)); }