[stgt] [PATCH 12/12] Add a mutex and protect nexus_list

Chandra Seetharaman sekharan at us.ibm.com
Mon Sep 27 07:21:33 CEST 2010


Serialize the access of it_nexus_list by protecting it by a mutex.

Signed-off-by: Chandra Seetharaman <sekharan at us.ibm.com>

---
 usr/target.c |   34 ++++++++++++++++++++++++++++++++--
 usr/target.h |    2 ++
 2 files changed, 34 insertions(+), 2 deletions(-)

Index: tgt-1.0.8.4/usr/target.h
===================================================================
--- tgt-1.0.8.4.orig/usr/target.h
+++ tgt-1.0.8.4/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-1.0.8.4/usr/target.c
===================================================================
--- tgt-1.0.8.4.orig/usr/target.c
+++ tgt-1.0.8.4/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)
@@ -1762,6 +1789,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;
 }
 
@@ -1857,6 +1886,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 at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list