Serialize the access of it_nexus_list by protecting it by a mutex. Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> Signed-off-by: Chandra Seetharaman <sekharan@xxxxxxxxxx> --- usr/target.c | 34 ++++++++++++++++++++++++++++++++-- usr/target.h | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) Index: tgt-102236c/usr/target.h =================================================================== --- tgt-102236c.orig/usr/target.h +++ tgt-102236c/usr/target.h @@ -34,6 +34,8 @@ struct target { struct list_head it_nexus_list; + pthread_mutex_t it_nexus_lock; + struct backingstore_template *bst; struct list_head acl_list; Index: tgt-102236c/usr/target.c =================================================================== --- tgt-102236c.orig/usr/target.c +++ tgt-102236c/usr/target.c @@ -27,6 +27,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <pthread.h> #include <sys/socket.h> #include <sys/time.h> @@ -90,10 +91,14 @@ static struct it_nexus *it_nexus_lookup( if (!target) return NULL; + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { - if (itn->itn_id == itn_id) + if (itn->itn_id == itn_id) { + pthread_mutex_unlock(&target->it_nexus_lock); return itn; + } } + pthread_mutex_unlock(&target->it_nexus_lock); return NULL; } @@ -215,6 +220,7 @@ void ua_sense_add_other_it_nexus(uint64_ struct it_nexus_lu_info *itn_lu; int ret; + pthread_mutex_lock(&lu->tgt->it_nexus_lock); list_for_each_entry(itn, &lu->tgt->it_nexus_list, nexus_siblings) { if (itn->itn_id == itn_id) @@ -232,6 +238,7 @@ void ua_sense_add_other_it_nexus(uint64_ lu->lun, itn_id); } } + pthread_mutex_unlock(&lu->tgt->it_nexus_lock); } int it_nexus_create(int tid, uint64_t itn_id, int host_no, char *info) @@ -284,7 +291,9 @@ int it_nexus_create(int tid, uint64_t it for (i = 0; i < ARRAY_SIZE(itn->cmd_hash_list); i++) INIT_LIST_HEAD(&itn->cmd_hash_list[i]); + pthread_mutex_lock(&target->it_nexus_lock); list_add_tail(&itn->nexus_siblings, &target->it_nexus_list); + pthread_mutex_unlock(&target->it_nexus_lock); return 0; out: @@ -313,7 +322,9 @@ int it_nexus_destroy(int tid, uint64_t i it_nexus_del_lu_info(itn); + pthread_mutex_lock(&itn->nexus_target->it_nexus_lock); list_del(&itn->nexus_siblings); + pthread_mutex_unlock(&itn->nexus_target->it_nexus_lock); free(itn); return 0; } @@ -570,6 +581,7 @@ int tgt_device_create(int tid, int dev_t } list_add_tail(&lu->device_siblings, &pos->device_siblings); + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { itn_lu = zalloc(sizeof(*itn_lu)); if (!itn_lu) @@ -589,6 +601,7 @@ int tgt_device_create(int tid, int dev_t ASC_REPORTED_LUNS_DATA_HAS_CHANGED); } } + pthread_mutex_unlock(&target->it_nexus_lock); if (backing && !path) lu->dev_type_template.lu_offline(lu); @@ -645,6 +658,7 @@ int tgt_device_destroy(int tid, uint64_t if (lu->bst->bs_exit) lu->bst->bs_exit(lu); + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { list_for_each_entry_safe(itn_lu, next, &itn->it_nexus_lu_info_list, lu_info_siblings) { @@ -654,6 +668,7 @@ int tgt_device_destroy(int tid, uint64_t } } } + pthread_mutex_unlock(&target->it_nexus_lock); list_del(&lu->device_siblings); @@ -664,6 +679,7 @@ int tgt_device_destroy(int tid, uint64_t free(lu); + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { list_for_each_entry(itn_lu, &itn->it_nexus_lu_info_list, lu_info_siblings) { @@ -672,6 +688,7 @@ int tgt_device_destroy(int tid, uint64_t ASC_REPORTED_LUNS_DATA_HAS_CHANGED); } } + pthread_mutex_unlock(&target->it_nexus_lock); return 0; } @@ -1095,6 +1112,7 @@ static int abort_task_set(struct mgmt_re eprintf("found %" PRIx64 " %d\n", tag, all); + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { for (i = 0; i < ARRAY_SIZE(itn->cmd_hash_list); i++) { struct list_head *list = &itn->cmd_hash_list[i]; @@ -1110,6 +1128,7 @@ static int abort_task_set(struct mgmt_re } } } + pthread_mutex_unlock(&target->it_nexus_lock); return count; } @@ -1167,6 +1186,7 @@ enum mgmt_req_result target_mgmt_request if (mreq->busy) send = 0; + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { list_for_each_entry(itn_lu, &itn->it_nexus_lu_info_list, lu_info_siblings) { @@ -1181,6 +1201,7 @@ enum mgmt_req_result target_mgmt_request } } } + pthread_mutex_unlock(&target->it_nexus_lock); break; case LOGICAL_UNIT_RESET: lun = scsi_get_devid(target->lid, lun_buf); @@ -1189,6 +1210,7 @@ enum mgmt_req_result target_mgmt_request if (mreq->busy) send = 0; + pthread_mutex_lock(&target->it_nexus_lock); list_for_each_entry(itn, &target->it_nexus_list, nexus_siblings) { list_for_each_entry(itn_lu, &itn->it_nexus_lu_info_list, lu_info_siblings) { @@ -1198,6 +1220,7 @@ enum mgmt_req_result target_mgmt_request } } } + pthread_mutex_unlock(&target->it_nexus_lock); break; default: err = -EINVAL; @@ -1685,7 +1708,7 @@ static char *print_type(int type) int tgt_target_show_all(char *buf, int rest) { - int total = 0, max = rest; + int total = 0, max = rest, mutex_held = 0; char strflags[128]; struct target *target; struct scsi_lu *lu; @@ -1705,12 +1728,16 @@ int tgt_target_show_all(char *buf, int r shprintf(total, buf, rest, _TAB1 "I_T nexus information:\n"); + pthread_mutex_lock(&target->it_nexus_lock); + mutex_held = 1; list_for_each_entry(nexus, &target->it_nexus_list, nexus_siblings) { shprintf(total, buf, rest, _TAB2 "I_T nexus: %" PRIu64 "\n", nexus->itn_id); if (nexus->info) shprintf(total, buf, rest, "%s", nexus->info); } + mutex_held = 0; + pthread_mutex_unlock(&target->it_nexus_lock); shprintf(total, buf, rest, _TAB1 "LUN information:\n"); list_for_each_entry(lu, &target->device_list, device_siblings) @@ -1764,6 +1791,8 @@ int tgt_target_show_all(char *buf, int r } return total; overflow: + if (mutex_held) + pthread_mutex_unlock(&target->it_nexus_lock); return max; } @@ -1859,6 +1888,7 @@ int tgt_target_create(int lld, int tid, INIT_LIST_HEAD(&target->acl_list); INIT_LIST_HEAD(&target->it_nexus_list); + pthread_mutex_init(&target->it_nexus_lock, NULL); tgt_device_create(tid, TYPE_RAID, 0, NULL, 0); -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html