[Ocfs2-commits] mfasheh commits r1900 - trunk/fs/ocfs2/dlm

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Feb 22 15:22:28 CST 2005


Author: mfasheh
Signed-off-by: zab
Date: 2005-02-22 15:22:26 -0600 (Tue, 22 Feb 2005)
New Revision: 1900

Modified:
   trunk/fs/ocfs2/dlm/dlmast.c
   trunk/fs/ocfs2/dlm/dlmconvert.c
   trunk/fs/ocfs2/dlm/dlmlock.c
   trunk/fs/ocfs2/dlm/dlmmaster.c
   trunk/fs/ocfs2/dlm/dlmmod.c
   trunk/fs/ocfs2/dlm/dlmmod.h
   trunk/fs/ocfs2/dlm/dlmunlock.c
Log:
* change module author line to proper name   

* clean up some needless indents

* implement some api cleanups and basic ref counting hooks. we will actually 
  start using these in a future commit.
  - this fixes at least one memory leak in the lockres hashing code
  - we now only kmalloc when actually required, rather than on every non
    converting call to dlmlock.

* add some limits checking to network handlers

Signed-off-by: zab



Modified: trunk/fs/ocfs2/dlm/dlmast.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmast.c	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmast.c	2005-02-22 21:22:26 UTC (rev 1900)
@@ -128,13 +128,13 @@
 
 int dlm_proxy_ast_handler(net_msg *msg, u32 len, void *data)
 {
-	int ret;
-	int status;
+	int ret, status;
+	unsigned int locklen;
 	dlm_ctxt *dlm = data;
-	dlm_lock_resource *res;
+	dlm_lock_resource *res = NULL;
 	dlm_lock *lock = NULL;
 	dlm_proxy_ast *past = (dlm_proxy_ast *) msg->buf;
-	struct qstr lockname;
+	char *name;
 	struct list_head *iter, *head=NULL;
 	u64 cookie;
 	u32 flags;
@@ -143,11 +143,17 @@
 		return DLM_REJECTED;
 
 	dlm_proxy_ast_to_host(past);
-	lockname.name = past->name;
-	lockname.len = past->namelen;
+	name = past->name;
+	locklen = past->namelen;
 	cookie = past->cookie;
 	flags = past->flags;
 
+	if (locklen > DLM_LOCKID_NAME_MAX) {
+		ret = DLM_IVBUFLEN;
+		printk("Invalid name length in proxy ast handler!\n");
+		goto leave;
+	}
+
 	if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
 	     (LKM_PUT_LVB|LKM_GET_LVB)) {
 		dlmprintk("both PUT and GET lvb specified\n");
@@ -158,25 +164,23 @@
 	dlmprintk("lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" : 
 		  (flags & LKM_GET_LVB ? "get lvb" : "none"));
 
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
-
 	dlmprintk("type=%d, blocked_type=%d\n", past->type, past->blocked_type);
 
 	if (past->type != DLM_AST && 
 	    past->type != DLM_BAST) {
 		dlmprintk("Eeeek unknown ast type! %d, cookie=%llu, "
 			  "name=%*s\n", 
-		       past->type, cookie, lockname.len, lockname.name);
+		       past->type, cookie, locklen, name);
 		ret = DLM_IVLOCKID;
 		goto leave;
 	}
 
-	res = dlm_lookup_lock(dlm, &lockname);
+	res = dlm_lookup_lock(dlm, name, locklen);
 	if (!res) {
 		dlmprintk("eek! got %sast for unknown lockres!  cookie=%llu, "
-			  "name=%*s, namelen=%d\n", 
+			  "name=%*s, namelen=%u\n", 
 			  past->type == DLM_AST ? "" : "b", 
-			  cookie, lockname.len, lockname.name, lockname.len);
+			  cookie, locklen, name, locklen);
 		ret = DLM_IVLOCKID;
 		goto leave;
 	}
@@ -208,9 +212,9 @@
 	}
 
 	dlmprintk("eek! got %sast for unknown lock!  cookie=%llu, "
-		  "name=%*s, namelen=%d\n", 
+		  "name=%*s, namelen=%u\n", 
 		  past->type == DLM_AST ? "" : "b", 
-		  cookie, lockname.len, lockname.name, lockname.len);
+		  cookie, locklen, name, locklen);
 	spin_unlock(&res->spinlock);
 	if (!dlm_is_recovery_lock(past->name, past->namelen))
 		up_read(&dlm->recovery_sem);
@@ -258,6 +262,9 @@
 
 leave:
 
+	if (res)
+		dlm_lockres_put(dlm, res);
+
 	dlm_put(dlm);
 	return ret;
 }
@@ -275,7 +282,6 @@
 		  res->lockname.len, res->lockname.name, lock->node, 
 		  type, blocked_type);
 
-
 	memset(&past, 0, sizeof(dlm_proxy_ast));
 	past.node_idx = dlm->group_index;
 	past.type = type;

Modified: trunk/fs/ocfs2/dlm/dlmconvert.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmconvert.c	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmconvert.c	2005-02-22 21:22:26 UTC (rev 1900)
@@ -374,7 +374,6 @@
 	dlm_lock *lock = NULL;
 	dlm_lockstatus *lksb;
 	dlm_status status = DLM_NORMAL;
-	struct qstr lockname;
 	u32 flags;
 	int call_ast = 0, kick_thread = 0;
 	int found = 0;
@@ -383,8 +382,12 @@
 		return DLM_REJECTED;
 
 	dlm_convert_lock_to_host(cnv);
-	lockname.name = cnv->name;
-	lockname.len = cnv->namelen;
+
+	if (cnv->namelen > DLM_LOCKID_NAME_MAX) {
+		status = DLM_IVBUFLEN;
+		goto leave;
+	}
+
 	flags = cnv->flags;
 
 	if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
@@ -396,11 +399,9 @@
 
 	dlmprintk("lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" : 
 		  (flags & LKM_GET_LVB ? "get lvb" : "none"));
-	
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
 
 	status = DLM_IVLOCKID;
-	res = dlm_lookup_lock(dlm, &lockname);
+	res = dlm_lookup_lock(dlm, cnv->name, cnv->namelen);
 	if (!res)
 		goto leave;
 
@@ -451,6 +452,9 @@
 	if (kick_thread)
 		dlm_kick_thread(dlm, res);
 
+	if (res)
+		dlm_lockres_put(dlm, res);
+
 	dlm_put(dlm);
 
 	return status;

Modified: trunk/fs/ocfs2/dlm/dlmlock.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmlock.c	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmlock.c	2005-02-22 21:22:26 UTC (rev 1900)
@@ -240,11 +240,12 @@
 {
 	dlm_ctxt *dlm = data;
 	dlm_create_lock *create = (dlm_create_lock *)msg->buf;
-	dlm_lock_resource *res;
-	dlm_lock *newlock;
+	dlm_lock_resource *res = NULL;
+	dlm_lock *newlock = NULL;
 	dlm_lockstatus *lksb = NULL;
 	dlm_status status = DLM_NORMAL;
-	struct qstr lockname;
+	char *name;
+	unsigned int namelen;
 
 	DLM_ASSERT(dlm);
 
@@ -254,10 +255,12 @@
 		return DLM_REJECTED;
 
 	dlm_create_lock_to_host(create);
-	lockname.name = create->name;
-	lockname.len = create->namelen;
+	name = create->name;
+	namelen = create->namelen;
 
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
+	status = DLM_IVBUFLEN;
+	if (namelen > DLM_LOCKID_NAME_MAX)
+		goto leave;
 
 	status = DLM_SYSERR;
 	newlock = kmalloc(sizeof(dlm_lock), GFP_KERNEL);
@@ -292,7 +295,7 @@
 	}
 
 	status = DLM_IVLOCKID;
-	res = dlm_lookup_lock(dlm, &lockname);
+	res = dlm_lookup_lock(dlm, name, namelen);
 	if (!res)
 		goto leave;
 
@@ -308,6 +311,9 @@
 			kfree(lksb);
 	}
 
+	if (res)
+		dlm_lockres_put(dlm, res);
+
 	dlm_put(dlm);
 
 	return status;

Modified: trunk/fs/ocfs2/dlm/dlmmaster.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmaster.c	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmmaster.c	2005-02-22 21:22:26 UTC (rev 1900)
@@ -56,13 +56,14 @@
 /* gives a really vague idea of the system load */
 atomic_t dlm_num_resources = ATOMIC_INIT(0);
 
-
-static int dlm_init_mle(dlm_master_list_entry *mle, enum dlm_mle_type type,
-                       dlm_ctxt *dlm, dlm_lock_resource *res,
-                       struct qstr *name, int locked);
+static int dlm_init_mle(dlm_master_list_entry *mle,
+			enum dlm_mle_type type,
+			dlm_ctxt *dlm,
+			dlm_lock_resource *res,
+			const char *name,
+			unsigned int namelen,
+			int locked);
 static void dlm_put_mle(dlm_master_list_entry *mle);
-static int dlm_do_master_request_resp(dlm_ctxt *dlm, struct qstr *name, 
-			       int response, int to);
 static int dlm_do_master_request(dlm_master_list_entry *mle, int to);
 static int dlm_do_assert_master(dlm_master_list_entry *mle);
 static void dlm_mle_node_up(struct inode *group, struct inode *node, 
@@ -70,9 +71,6 @@
 static void dlm_mle_node_down(struct inode *group, struct inode *node, 
 		       int idx, void *data);
 
-
-
-
 /* remove from list and free */
 static void dlm_put_mle(dlm_master_list_entry *mle)
 {
@@ -90,14 +88,16 @@
 	atomic_inc(&mle->refcnt);
 }
 
-
-
-static int dlm_init_mle(dlm_master_list_entry *mle, enum dlm_mle_type type,
-			dlm_ctxt *dlm, dlm_lock_resource *res,
-			struct qstr *name, int locked)
+static int dlm_init_mle(dlm_master_list_entry *mle,
+			enum dlm_mle_type type,
+			dlm_ctxt *dlm,
+			dlm_lock_resource *res,
+			const char *name,
+			unsigned int namelen,
+			int locked)
 {
 	int ret = 0;
-	
+
 	mle->dlm = dlm;
 	mle->type = type;
 	INIT_LIST_HEAD(&mle->list);
@@ -113,8 +113,8 @@
 	if (mle->type == DLM_MLE_MASTER) 
 		mle->u.res = res;
 	else 
-		strncpy(mle->u.name.name, name->name, name->len);
-		
+		strncpy(mle->u.name.name, name, namelen);
+
 	if (!locked)
 		spin_lock(&dlm->spinlock);
 
@@ -139,9 +139,6 @@
 	return ret;
 }
 
-
-
-
 /////////////////////////////////////////////////
 //
 // TODO: change these comments to reflect reality
@@ -179,12 +176,104 @@
 //
 /////////////////////////////////////////////////
 
+static void dlm_lockres_release(struct kref *kref)
+{
+	dlm_lock_resource *res;
 
+	BUG_ON(!kref);
 
+	res = container_of(kref, dlm_lock_resource, refs);
 
+	/* This should not happen -- all lockres' have a name
+	 * associated with them at init time. */
+	BUG_ON(!res->lockname.name);
+
+	dlmprintk("destroying lockres %*s\n", res->lockname.len,
+		  res->lockname.name);
+
+	/* By the time we're ready to blow this guy away, we shouldn't
+	 * be on any lists. */
+	BUG_ON(!list_empty(&res->list));
+	BUG_ON(!list_empty(&res->granted));
+	BUG_ON(!list_empty(&res->converting));
+	BUG_ON(!list_empty(&res->blocked));
+	BUG_ON(!list_empty(&res->dirty));
+	BUG_ON(!list_empty(&res->recovering));
+
+	kfree(res->lockname.name);
+
+	kfree(res);
+}
+
+void __dlm_lockres_get(dlm_lock_resource *res)
+{
+	kref_get(&res->refs);
+}
+
+void dlm_lockres_put(dlm_ctxt *dlm,
+		     dlm_lock_resource *res)
+{
+	spin_lock(&dlm->spinlock);
+	kref_put(&res->refs, dlm_lockres_release);
+	spin_unlock(&dlm->spinlock);
+}
+
+static void dlm_init_lockres(dlm_lock_resource *res,
+			     const char *name,
+			     unsigned int namelen)
+{
+	char *qname;
+
+	/* If we memset here, we lose our reference to the kmalloc'd
+	 * res->lockname.name, so be sure to init every field
+	 * correctly! */
+
+	qname = (char *) res->lockname.name;
+	strncpy(qname, name, namelen);
+
+	res->lockname.len = namelen;
+	res->lockname.hash = full_name_hash(name, namelen);
+
+	init_waitqueue_head(&res->wq);
+	spin_lock_init(&res->spinlock);
+	INIT_LIST_HEAD(&res->list);
+	INIT_LIST_HEAD(&res->granted);
+	INIT_LIST_HEAD(&res->converting);
+	INIT_LIST_HEAD(&res->blocked);
+	INIT_LIST_HEAD(&res->dirty);
+	INIT_LIST_HEAD(&res->recovering);
+
+	kref_init(&res->refs, dlm_lockres_release);
+
+	res->owner = DLM_LOCK_RES_OWNER_UNKNOWN;
+	res->state = DLM_LOCK_RES_IN_PROGRESS;
+
+	memset(res->lvb, 0, DLM_LVB_LEN);
+}
+
+static dlm_lock_resource *dlm_new_lockres(const char *name,
+					  unsigned int namelen)
+{
+	dlm_lock_resource *res;
+
+	res = kmalloc(sizeof(dlm_lock_resource), GFP_KERNEL);
+	if (!res)
+		return NULL;
+
+	res->lockname.name = kmalloc(namelen, GFP_KERNEL);
+	if (!res->lockname.name) {
+		kfree(res);
+		return NULL;
+	}
+
+	dlm_init_lockres(res, name, namelen);
+	return res;
+}
+
 /*
  * lookup a lock resource by name.
  * may already exist in the hashtable.
+ * lockid is null terminated
  * 
  * if not, allocate enough for the lockres and for
  * the temporary structure used in doing the mastering.
@@ -198,41 +287,51 @@
  *
  */
 dlm_lock_resource * dlm_get_lock_resource(dlm_ctxt *dlm, 
-					  struct qstr *lockname, int flags)
+					  const char *lockid,
+					  int flags)
 {
 	dlm_lock_resource *tmpres=NULL, *res=NULL;
-	struct list_head *bucket;
 	dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
 	struct list_head *iter;
 	int blocked = 0;
 	int map_changed = 0, restart = 0, assert = 0;
 	int ret, start, bit;
+	unsigned int namelen;
 
-	bucket = &(dlm->resources[lockname->hash & DLM_HASH_MASK]);
+	BUG_ON(!lockid);
+	BUG_ON(!dlm);
 
+	namelen = strlen(lockid);
+
+	dlmprintk("get lockres %s (len %d)\n", lockid, namelen);
+
 lookup:
 	spin_lock(&dlm->spinlock);
-	tmpres = __dlm_lookup_lock(dlm, lockname);
+	tmpres = __dlm_lookup_lock(dlm, lockid, namelen);
 	if (tmpres) {
 		spin_unlock(&dlm->spinlock);
 
+		dlmprintk("found in hash!\n");
+
 		if (mle)
 			kfree(mle);
+
 		if (res)
-			kfree(res);
+			dlm_lockres_put(dlm, res);
 
 		return tmpres;
 	}
 
 	if (!res) {
 		spin_unlock(&dlm->spinlock);
+		dlmprintk("allocating a new resource\n");
 
 		/* nothing found and we need to allocate one. */
 		mle = kmalloc(sizeof(dlm_master_list_entry), GFP_KERNEL);
 		if (!mle)
 			return NULL;
 
-		res = kmalloc(sizeof(dlm_lock_resource), GFP_KERNEL);
+		res = dlm_new_lockres(lockid, namelen);
 		if (!res) {
 			kfree(mle);
 			return NULL;
@@ -241,13 +340,12 @@
 		goto lookup;
 	}
 
-	/* Ok, no lockres found and we have one to insert... */
-	dlm_init_lockres(res, lockname);
+	dlmprintk("no lockres found, allocated our own: %p\n", res);
 
 	if (flags & LKM_LOCAL) {
 		/* caller knows it's safe to assume it's not mastered elsewhere
 		 * DONE!  return right away */
-		list_add_tail(&res->list, bucket);
+		__dlm_insert_lock(dlm, res);
 		res->owner = dlm->group_index;
 		atomic_inc(&dlm_num_resources);
 		spin_unlock(&dlm->spinlock);
@@ -259,7 +357,7 @@
 	spin_lock(&dlm_master_lock);
 	list_for_each(iter, &dlm_master_list) {
 		tmpmle = list_entry(iter, dlm_master_list_entry, list);
-		if (!dlm_mle_equal(dlm, tmpmle, lockname))
+		if (!dlm_mle_equal(dlm, tmpmle, lockid, namelen))
 			continue;
 
 		if (tmpmle->type == DLM_MLE_MASTER) {
@@ -275,7 +373,7 @@
 
 	if (!blocked) {
 		/* go ahead and try to master lock on this node */
-		if (dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 1)) {
+		if (dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 0, 1)) {
 			dlmprintk0("bug! failed to register hb callbacks\n");
 			BUG();
 		}
@@ -294,7 +392,7 @@
 	 * to come in and put their mle on the list and sleep ?? */
 
 	/* finally add the lockres to its hash bucket */
-	list_add_tail(&res->list, bucket);
+	__dlm_insert_lock(dlm, res);
 	atomic_inc(&dlm_num_resources);
 	spin_unlock(&dlm->spinlock);
 
@@ -313,7 +411,7 @@
 			dlmprintk0("no more nodes\n");
 			break;
 		}
-		
+
 		ret = dlm_do_master_request(mle, bit);
 		if (ret < 0) {
 			// TODO
@@ -389,8 +487,8 @@
 					 * the vote_map, zero everything out 
 					 * and start over */
 					dlmprintk("need to handle this case.  "
-						  "winning node %u just died\n",
-						  bit);
+						  "winning node %u just "
+						  "died\n", bit);
 					restart = 1;
 				}
 
@@ -483,9 +581,6 @@
 	return res;
 }
 
-
-
-
 /*
  * locks that can be taken here:
  * dlm->spinlock
@@ -502,7 +597,8 @@
 	dlm_lock_resource *res;
 	dlm_master_request *request = (dlm_master_request *) msg->buf;
 	dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
-	struct qstr lockname;
+	char *name;
+	unsigned int namelen;
 	int found;
 	struct list_head *iter;
 
@@ -510,13 +606,17 @@
 		return DLM_MASTER_RESP_NO;
 
 	dlm_master_request_to_host(request);
-	lockname.name = request->name;
-	lockname.len = request->namelen;
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
+	name = request->name;
+	namelen = request->namelen;
 
-way_up_top:	
+	if (namelen > DLM_LOCKID_NAME_MAX) {
+		response = DLM_IVBUFLEN;
+		goto send_response;
+	}
+
+way_up_top:
 	spin_lock(&dlm->spinlock);
-	res = __dlm_lookup_lock(dlm, &lockname);
+	res = __dlm_lookup_lock(dlm, name, namelen);
 	if (res) {
 		spin_unlock(&dlm->spinlock);
 
@@ -552,7 +652,7 @@
 		spin_lock(&dlm_master_lock);
 		list_for_each(iter, &dlm_master_list) {
 			tmpmle = list_entry(iter, dlm_master_list_entry, list);
-			if (!dlm_mle_equal(dlm, tmpmle, &lockname))
+			if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
 				continue;
 
 			dlm_get_mle(tmpmle);
@@ -593,7 +693,7 @@
 	spin_lock(&dlm_master_lock);
 	list_for_each(iter, &dlm_master_list) {
 		tmpmle = list_entry(iter, dlm_master_list_entry, list);
-		if (!dlm_mle_equal(dlm, tmpmle, &lockname))
+		if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
 			continue;
 		dlm_get_mle(tmpmle);
 		found = 1;
@@ -608,14 +708,14 @@
 			spin_unlock(&dlm->spinlock);
 
 			mle = kmalloc(sizeof(dlm_master_list_entry) + 
-				      lockname.len, GFP_KERNEL);
+				      namelen, GFP_KERNEL);
 			if (!mle) {
 				// bad bad bad... this sucks.
 				response = DLM_MASTER_RESP_ERROR;
 				goto send_response;
 			}
 			if (dlm_init_mle(mle, DLM_MLE_BLOCK, dlm, NULL, 
-					 &lockname, 0)) {
+					 name, namelen, 0)) {
 				dlmprintk0("eeek!\n");
 				response = DLM_MASTER_RESP_ERROR;
 				dlm_put_mle(mle);
@@ -645,10 +745,6 @@
 
 send_response:
 	dlm_put(dlm);
-	//ret = dlm_do_master_request_resp(dlm, &lockname, response, 
-	//				   request->node_idx);
-	//dlmprintk("response returned %d\n", ret);
-	//dlmprintk("sending response %d to other node\n", response);
 	return response;
 }
 
@@ -669,20 +765,21 @@
 	dlm_master_request_resp *resp = (dlm_master_request_resp *) msg->buf;
 	int found = 0, wake = 0;
 	struct list_head *iter;
-	struct qstr lockname;
 
 	if (!dlm_grab(dlm))
 		return 0;
 
 	dlm_master_request_resp_to_host(resp);
-	lockname.name = resp->name;
-	lockname.len = resp->namelen;
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
 
+	if (resp->namelen > DLM_LOCKID_NAME_MAX) {
+		printk("Invalid name length in master request response!\n");
+		goto done;
+	}
+
 	spin_lock(&dlm_master_lock);
 	list_for_each(iter, &dlm_master_list) {
 		mle = list_entry(iter, dlm_master_list_entry, list);
-		if (!dlm_mle_equal(dlm, mle, &lockname)) {
+		if (!dlm_mle_equal(dlm, mle, resp->name, resp->namelen)) {
 			mle = NULL;
 			continue;
 		}
@@ -746,6 +843,7 @@
 		dlmprintk0("hrrm... got a master resp but found no matching "
 			   "request\n");
 
+done:
 	dlm_put(dlm);
 	return 0;
 }
@@ -767,23 +865,28 @@
 	dlm_lock_resource *res;
 	int bit;
 	struct list_head *iter;
-	struct qstr lockname;
+	char *name;
+	unsigned int namelen;
 
 	if (!dlm_grab(dlm))
 		return 0;
 
 	dlm_assert_master_to_host(assert);	
-	lockname.name = assert->name;
-	lockname.len = assert->namelen;
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
+	name = assert->name;
+	namelen = assert->namelen;
 
+	if (namelen > DLM_LOCKID_NAME_MAX) {
+		printk("Invalid name length in master assert handler!\n");
+		goto done;
+	}
+
 	spin_lock(&dlm->spinlock);
 
 	/* find the MLE */
 	spin_lock(&dlm_master_lock);
 	list_for_each(iter, &dlm_master_list) {
 		mle = list_entry(iter, dlm_master_list_entry, list);
-		if (dlm_mle_equal(dlm, mle, &lockname)) {
+		if (dlm_mle_equal(dlm, mle, name, namelen)) {
 			dlm_get_mle(mle);
 			break;
 		}
@@ -812,7 +915,7 @@
 	/* ok everything checks out with the MLE
 	 * now check to see if there is a lockres */
 check_lockres:
-	res = __dlm_lookup_lock(dlm, &lockname);
+	res = __dlm_lookup_lock(dlm, name, namelen);
 	if (res) {
 		spin_lock(&res->spinlock);
 		if (!mle) {
@@ -855,11 +958,11 @@
 		dlm_put_mle(mle);
 	}
 
+done:
 	dlm_put(dlm);
 	return 0;
 }
 
-
 static int dlm_do_master_request(dlm_master_list_entry *mle, int to)
 {
 	struct inode *inode = NULL;
@@ -928,30 +1031,6 @@
 	return ret;
 }
 
-static int dlm_do_master_request_resp(dlm_ctxt *dlm, struct qstr *name, 
-			       int response, int to)
-{
-	struct inode *inode = NULL;
-	dlm_master_request_resp resp;
-	int ret;
-
-	memset(&resp, 0, sizeof(resp));
-	resp.node_idx = dlm->group_index;
-	resp.response = response;
-	resp.namelen = name->len;
-	strncpy(resp.name, name->name, name->len);
-
-	inode = nm_get_group_node_by_index(dlm->group, to);
-	if (!inode)
-		return -EINVAL;
-
-	dlm_master_request_resp_to_net(&resp);
-	ret = net_send_message(DLM_MASTER_REQUEST_RESP_MSG, dlm->key, 
-			       &resp, sizeof(resp), inode, NULL);
-	iput(inode);
-	return ret;
-}
-
 /*
  * NOTE: this can be used for debugging
  * can periodically run all locks owned by this node
@@ -1009,11 +1088,6 @@
 	return ret;
 }
 
-
-
-
-
-
 static void dlm_mle_node_down(struct inode *group, struct inode *node, 
 		       int idx, void *data)
 {

Modified: trunk/fs/ocfs2/dlm/dlmmod.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmod.c	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmmod.c	2005-02-22 21:22:26 UTC (rev 1900)
@@ -51,8 +51,7 @@
 #include "dlmmod.h"
 
 MODULE_LICENSE ("GPL");
-MODULE_AUTHOR("Oracle Corporation");
-//MODULE_DESCRIPTION("Oracle DLM");
+MODULE_AUTHOR("Oracle");
 
 
 /*
@@ -150,18 +149,15 @@
 	}
 	spin_unlock(&dlm_cookie_lock);
 }
- 
 
 dlm_status dlmlock(dlm_ctxt *dlm, int mode, dlm_lockstatus *lksb, int flags, 
-		   char *name, dlm_astlockfunc_t *ast, void *data, 
+		   const char *name, dlm_astlockfunc_t *ast, void *data, 
 		   dlm_bastlockfunc_t *bast)
 {
 	dlm_status status;
 	dlm_lock_resource *res;
 	dlm_lock *lock = NULL;
-	char *buf = NULL;
 	int convert = 0, recovery = 0;
-	struct qstr q;
 
 	if (!lksb)
 		return DLM_BADARGS;
@@ -192,7 +188,7 @@
 		if (!lksb->lockid || !lksb->lockid->lockres)
 			goto error_status;
 		lock = lksb->lockid;
-	
+
 		/* XXX: for ocfs2 purposes, the ast/bast/astdata/lksb are 
 	 	 * static after the original lock call.  convert requests will 
 		 * ensure that everything is the same, or return DLM_BADARGS.
@@ -223,32 +219,20 @@
 			goto error;
 
 		status = DLM_IVBUFLEN;
-		q.len = strlen(name);
-		if (q.len > DLM_LOCKID_NAME_MAX)
+		if (strlen(name) > DLM_LOCKID_NAME_MAX)
 			goto error;
 
-		/* take care of all allocs before any locking */
-		status = DLM_SYSERR;
-		buf = kmalloc(q.len+1, GFP_KERNEL);  /* lockres name */
-		if (!buf)
-			goto error;
-
-		memcpy(buf, name, q.len);
-		buf[q.len] = 0;
-		q.name = buf;
-		q.hash = full_name_hash(q.name, q.len);
-
 		lock = kmalloc(sizeof(dlm_lock), GFP_KERNEL);  /* dlm_lock */
 		if (!lock)
 			goto error;
 
 		lksb->lockid = lock;
 
-		if (!recovery)		
+		if (!recovery)
 			down_read(&dlm->recovery_sem);
 
 		/* find or create the lock resource */
-		res = dlm_get_lock_resource(dlm, &q, flags);
+		res = dlm_get_lock_resource(dlm, name, flags);
 		if (!res) {
 			status = DLM_IVLOCKID;
 			goto up_error;
@@ -305,8 +289,6 @@
 	if (!recovery)
 		up_read(&dlm->recovery_sem);
 error:
-	if (buf)
-		kfree(buf);
 	if (lock && !convert) {
 		kfree(lock);
 		lksb->lockid = NULL;
@@ -382,33 +364,63 @@
 }
 EXPORT_SYMBOL(dlmunlock);
 
-dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname)
+void __dlm_insert_lock(dlm_ctxt *dlm,
+		       dlm_lock_resource *res)
 {
+	struct list_head *bucket;
+	struct qstr *q;
+
+	q = &res->lockname;
+	q->hash = full_name_hash(q->name, q->len);
+	bucket = &(dlm->resources[q->hash & DLM_HASH_MASK]);
+
+	/* get a reference for our hashtable */
+	__dlm_lockres_get(res);
+
+	list_add_tail(&res->list, bucket);
+}
+
+dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm,
+				      const char *name,
+				      unsigned int len)
+{
+	unsigned int hash;
 	struct list_head *iter;
 	dlm_lock_resource *tmpres=NULL;
 	struct list_head *bucket;
 
+	BUG_ON(!name);
+
 	dlmprintk0("\n");
 
-	bucket = &(dlm->resources[lockname->hash & DLM_HASH_MASK]);
+	hash = full_name_hash(name, len);
 
+	bucket = &(dlm->resources[hash & DLM_HASH_MASK]);
+
 	/* check for pre-existing lock */
 	list_for_each(iter, bucket) {
 		tmpres = list_entry(iter, dlm_lock_resource, list);
-		if (tmpres->lockname.len == lockname->len &&
-		    strncmp(tmpres->lockname.name, lockname->name, 
-			    lockname->len) == 0)
+		if (tmpres->lockname.len == len &&
+		    strncmp(tmpres->lockname.name, name, len) == 0) {
+			__dlm_lockres_get(tmpres);
 			break;
+		}
+
 		tmpres = NULL;
 	}
 	return tmpres;
 }
 
-dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname)
+dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm, 
+				    const char *name,
+				    unsigned int len)
 {
 	dlm_lock_resource *res;
+
+	BUG_ON(!dlm);
+
 	spin_lock(&dlm->spinlock);
-	res = __dlm_lookup_lock(dlm, lockname);
+	res = __dlm_lookup_lock(dlm, name, len);
 	spin_unlock(&dlm->spinlock);
 	return res;
 }
@@ -866,25 +878,6 @@
 }
 EXPORT_SYMBOL(dlm_register_domain);
 
-void dlm_init_lockres(dlm_lock_resource *res, struct qstr *lockname)
-{
-	memset(res, 0, sizeof(dlm_lock_resource));
-	res->lockname.name = lockname->name;
-	res->lockname.len = lockname->len;
-	res->lockname.hash = lockname->hash;
-	init_waitqueue_head(&res->wq);
-	spin_lock_init(&res->spinlock);
-	INIT_LIST_HEAD(&res->list);
-	INIT_LIST_HEAD(&res->granted);
-	INIT_LIST_HEAD(&res->converting);
-	INIT_LIST_HEAD(&res->blocked);
-	INIT_LIST_HEAD(&res->dirty);
-	INIT_LIST_HEAD(&res->recovering);
-
-	res->owner = DLM_LOCK_RES_OWNER_UNKNOWN;
-	res->state |= DLM_LOCK_RES_IN_PROGRESS;
-}
-
 /* will exit holding res->spinlock, but may drop in function */
 void __dlm_wait_on_lockres(dlm_lock_resource *res)
 {
@@ -903,10 +896,6 @@
 	current->state = TASK_RUNNING;
 }
 
-
-
-
-
 void dlm_dump_everything(void)
 {
 	dlm_ctxt *dlm;

Modified: trunk/fs/ocfs2/dlm/dlmmod.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmod.h	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmmod.h	2005-02-22 21:22:26 UTC (rev 1900)
@@ -117,7 +117,7 @@
 #define DLM_RECOVERY_LOCK_NAME       "$RECOVERY"
 #define DLM_RECOVERY_LOCK_NAME_LEN   9
 
-static inline int dlm_is_recovery_lock(char *lock_name, int name_len)
+static inline int dlm_is_recovery_lock(const char *lock_name, int name_len)
 {
 	if (name_len == DLM_RECOVERY_LOCK_NAME_LEN &&
 	    strncmp(lock_name, DLM_RECOVERY_LOCK_NAME, DLM_RECOVERY_LOCK_NAME_LEN)==0)
@@ -220,8 +220,11 @@
 
 typedef struct _dlm_lock_resource
 {
+	/* WARNING: Please see the comment in dlm_init_lockres before
+	 * adding fields here. */
 	struct list_head list;
-	
+	struct kref      refs;
+
 	/* please keep these next 3 in this order 
 	 * some funcs want to iterate over all lists */
 	struct list_head granted;
@@ -232,7 +235,7 @@
 	struct list_head recovering; // dlm_recovery_ctxt.resources list
 	spinlock_t spinlock;
 	wait_queue_head_t wq;
-	u8  owner;              // node which owns the lock resource, or unknown
+	u8  owner;              //node which owns the lock resource, or unknown
 	u16 state;
 	struct qstr lockname;
 	char lvb[DLM_LVB_LEN];
@@ -534,8 +537,14 @@
 int dlm_launch_thread(dlm_ctxt *dlm);
 void dlm_complete_thread(dlm_ctxt *dlm);
 
-dlm_status dlmlock(dlm_ctxt *dlm, int mode, dlm_lockstatus *lksb, int flags, char *name, 
-		   dlm_astlockfunc_t *ast, void *data, dlm_bastlockfunc_t *bast);
+dlm_status dlmlock(dlm_ctxt *dlm,
+		   int mode,
+		   dlm_lockstatus *lksb,
+		   int flags,
+		   const char *name,
+		   dlm_astlockfunc_t *ast,
+		   void *data,
+		   dlm_bastlockfunc_t *bast);
 		   
 dlm_status dlmlock_master(dlm_ctxt *dlm, dlm_lock_resource *res, 
 			  dlm_lock *lock, int flags);
@@ -574,7 +583,21 @@
 void dlm_put(dlm_ctxt *dlm);
 dlm_ctxt *dlm_grab(dlm_ctxt *dlm);
 
-dlm_lock_resource * dlm_get_lock_resource(dlm_ctxt *dlm, struct qstr *lockname, int flags);
+void __dlm_lockres_get(dlm_lock_resource *res);
+void dlm_lockres_put(dlm_ctxt *dlm,
+		     dlm_lock_resource *res);
+void __dlm_insert_lock(dlm_ctxt *dlm,
+		       dlm_lock_resource *res);
+dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm,
+				      const char *name,
+				      unsigned int len);
+dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm,
+				    const char *name,
+				    unsigned int len);
+dlm_lock_resource * dlm_get_lock_resource(dlm_ctxt *dlm, 
+					  const char *lockid,
+					  int flags);
+
 int dlm_lock_owner_broadcast(dlm_ctxt *dlm, dlm_lock_resource *res);
 int dlm_refresh_lock_resource(dlm_ctxt *dlm, dlm_lock_resource *res);
 int dlm_do_ast(dlm_ctxt *dlm, dlm_lock_resource *res, dlm_lock *lock);
@@ -584,9 +607,6 @@
 
 int dlm_nm_init(dlm_ctxt *dlm);
 int dlm_heartbeat_init(dlm_ctxt *dlm);
-
-dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname);
-
 void dlm_hb_node_down_cb(struct inode *group, struct inode *node, int idx, void *data);
 void dlm_hb_node_up_cb(struct inode *group, struct inode *node, int idx, void *data);
 int dlm_hb_node_dead(dlm_ctxt *dlm, int node);
@@ -598,8 +618,6 @@
 int dlm_master_request_handler(net_msg *msg, u32 len, void *data);
 int dlm_master_request_resp_handler(net_msg *msg, u32 len, void *data);
 int dlm_assert_master_handler(net_msg *msg, u32 len, void *data);
-dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname);
-void dlm_init_lockres(dlm_lock_resource *res, struct qstr *lockname);
 void dlm_dump_everything(void);
 void dlm_dump_dlm(dlm_ctxt *dlm);
 
@@ -635,7 +653,7 @@
 	/* EX incompatible with all non-NO_LOCK */
 	if (request == LKM_EXMODE)
 		return 0;
-	
+
 	/* request must be PR, which is compatible with PR */
 	if (existing == LKM_PRMODE)
 		return 1;
@@ -656,7 +674,10 @@
 	return 0;
 }
 
-static inline int dlm_mle_equal(dlm_ctxt *dlm, dlm_master_list_entry *mle, struct qstr *lockname)
+static inline int dlm_mle_equal(dlm_ctxt *dlm,
+				dlm_master_list_entry *mle,
+				const char *name,
+				unsigned int namelen)
 {
 	dlm_lock_resource *res;
 
@@ -664,14 +685,13 @@
 		return 0;
 
 	if (mle->type == DLM_MLE_BLOCK) {
-		if (lockname->len != mle->u.name.len ||
-    	    	    strncmp(lockname->name, mle->u.name.name, lockname->len)!=0)
+		if (namelen != mle->u.name.len ||
+    	    	    strncmp(name, mle->u.name.name, namelen)!=0)
 			return 0;
 	} else {
 		res = mle->u.res;
-		if (res->lockname.hash != lockname->hash ||
-       	    	    res->lockname.len != lockname->len ||
-       	    	    strncmp(res->lockname.name, lockname->name, lockname->len)!=0)
+		if (namelen != res->lockname.len ||
+		    strncmp(res->lockname.name, name, namelen) != 0)
 			return 0;
 	}
 	return 1;

Modified: trunk/fs/ocfs2/dlm/dlmunlock.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmunlock.c	2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmunlock.c	2005-02-22 21:22:26 UTC (rev 1900)
@@ -158,7 +158,6 @@
 	spin_unlock(&lock->spinlock);
 	spin_unlock(&res->spinlock);
 	wake_up(&res->wq);
-	
 
 	if (actions & DLM_UNLOCK_FREE_LOCK) {
 #warning this must change to proper refcounting
@@ -177,10 +176,6 @@
 	return status;
 }
 
-
-	
-
-	
 /* 
  * locking:
  *   caller needs:  none
@@ -202,7 +197,6 @@
 	struct iovec iov[2];
 	size_t iovlen = 1;
 
-
 	dlmprintk0("\n");
 
 	memset(&unlock, 0, sizeof(unlock));
@@ -260,20 +254,17 @@
 {
 	dlm_ctxt *dlm = data;
 	dlm_unlock_lock *unlock = (dlm_unlock_lock *)msg->buf;
-	dlm_lock_resource *res;
+	dlm_lock_resource *res = NULL;
 	struct list_head *iter;
 	dlm_lock *lock = NULL;
 	dlm_status status = DLM_NORMAL;
 	int found = 0, i;
 	dlm_lockstatus *lksb = NULL;
 	int ignore;
-	struct qstr lockname;
 	u32 flags;
 	struct list_head *queue;
  
 	dlm_unlock_lock_to_host(unlock);
-	lockname.name = unlock->name;
-	lockname.len = unlock->namelen;
 	flags = unlock->flags;
 
 	if (flags & LKM_GET_LVB) {
@@ -287,12 +278,18 @@
 		return DLM_BADARGS;
 	}
 
+	if (unlock->namelen > DLM_LOCKID_NAME_MAX) {
+		printk("Invalid name length in unlock handler!\n");
+		return DLM_IVBUFLEN;
+	}
+
+	if (!dlm_grab(dlm))
+		return DLM_REJECTED;
+
 	dlmprintk("lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" : "none");
 
-	lockname.hash = full_name_hash(lockname.name, lockname.len);
-
 	status = DLM_IVLOCKID;
-	res = dlm_lookup_lock(dlm, &lockname);
+	res = dlm_lookup_lock(dlm, unlock->name, unlock->namelen);
 	if (!res)
 		goto not_found;
 
@@ -316,7 +313,7 @@
 	spin_unlock(&res->spinlock);
 	if (!found)
 		goto not_found;
-	
+
 	/* lock was found on queue */
 	lksb = lock->lksb;
 	/* unlockast only called on originating node */
@@ -343,6 +340,11 @@
 		status = lksb->status;
 	}
 
+	if (res)
+		dlm_lockres_put(dlm, res);
+
+	dlm_put(dlm);
+
 	return status;
 }
 



More information about the Ocfs2-commits mailing list