[Ocfs2-devel] [PATCH] ocfs2/dlm: allocate lvb for dlm_lock_resource which needs it -drop2

Wengang Wang wen.gang.wang at oracle.com
Tue Sep 21 00:25:13 PDT 2010


#reposting with trivial changes

Changes to drop1:
1) adds unsigned reserve_lvb:1 to dlm_lock_resource indicating lvb should be
reserved or not. This flag doesn't make sense to this patch its self, but it
helps the coming patch that allocates lvb for dlm_lock which needs it. The 1
bit flag doesn't take extra memory space, so putting it here is fine.

2) adds a new parameter to dlm_new_lockres() indicating if lvb memory should be
reserved. Determining method by checking name in v1 is discarded.

3) adds u8 reserve_lvb:1 to dlm_migratable_lockres indicating if the migration
target should reserve lvb for the dlm_lock_resouce in case of needing to create
a new dlm_lock_resouce.

4) increment dlm_protocol major version because of 3).

small changes:
1) moves the real allocation from dlm_init_lockres() to dlm_new_lockres().
since we have the new-added parameter, we know if we should do the allocation
in dlm_new_lockres(). And it's better we do allocations at the same space.

2) adds DLM_LKF_VALBLK to dlm_flags in ocfs2_lock_create.
We are missing the flag. But since it's adding a new lockres(no race), so no
problem running current codes.

3) adds some asserts on res->lvb.

Signed-off-by: Wengang Wang <wen.gang.wang at oracle.com>
---
 fs/ocfs2/dlm/dlmast.c      |    2 ++
 fs/ocfs2/dlm/dlmcommon.h   |    9 +++++++--
 fs/ocfs2/dlm/dlmconvert.c  |    5 ++++-
 fs/ocfs2/dlm/dlmdebug.c    |    6 ++++--
 fs/ocfs2/dlm/dlmdomain.c   |    6 +++++-
 fs/ocfs2/dlm/dlmmaster.c   |   16 +++++++++++++---
 fs/ocfs2/dlm/dlmrecovery.c |   34 +++++++++++++++++++++++++++-------
 fs/ocfs2/dlm/dlmunlock.c   |    2 ++
 fs/ocfs2/dlmglue.c         |    3 +++
 9 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
index f449991..cbe56c5 100644
--- a/fs/ocfs2/dlm/dlmast.c
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -191,6 +191,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
 			mlog(0, "getting lvb from lockres for %s node\n",
 				  lock->ml.node == dlm->node_num ? "master" :
 				  "remote");
+			mlog_bug_on_msg(!res->lvb, "lockname: %.*s\n",
+					res->lockname.len, res->lockname.name);
 			memcpy(lksb->lvb, res->lvb, DLM_LVB_LEN);
 		}
 		/* Do nothing for lvb put requests - they should be done in
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 4b6ae2c..4b94ede 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -324,12 +324,13 @@ struct dlm_lock_resource
 	struct dlm_ctxt *dlm;
 
 	unsigned migration_pending:1;
+	unsigned reserve_lvb:1;
 	atomic_t asts_reserved;
 	spinlock_t spinlock;
 	wait_queue_head_t wq;
 	u8  owner;              //node which owns the lock resource, or unknown
 	u16 state;
-	char lvb[DLM_LVB_LEN];
+	char *lvb;
 	unsigned int inflight_locks;
 	unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
 };
@@ -395,6 +396,8 @@ enum dlm_lockres_list {
 static inline int dlm_lvb_is_empty(char *lvb)
 {
 	int i;
+
+	BUG_ON(!lvb);
 	for (i=0; i<DLM_LVB_LEN; i++)
 		if (lvb[i])
 			return 0;
@@ -564,6 +567,7 @@ struct dlm_migratable_lockres
 	u8 lockname_len;
 	u8 num_locks;    // locks sent in this structure
 	u8 flags;
+	u8 reserve_lvb:1;
 	__be32 total_locks; // locks to be sent for this migration cookie
 	__be64 mig_cookie;  // cookie for this lockres migration
 			 // or zero if not needed
@@ -859,7 +863,8 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
 						 int flags);
 struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
 					  const char *name,
-					  unsigned int namelen);
+					  unsigned int namelen,
+					  unsigned int reserve_lvb);
 
 #define dlm_lockres_set_refmap_bit(bit,res)  \
 	__dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__)
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c
index 9f30491..93bb76b 100644
--- a/fs/ocfs2/dlm/dlmconvert.c
+++ b/fs/ocfs2/dlm/dlmconvert.c
@@ -212,8 +212,11 @@ grant:
 	if (lock->ml.node == dlm->node_num)
 		mlog(0, "doing in-place convert for nonlocal lock\n");
 	lock->ml.type = type;
-	if (lock->lksb->flags & DLM_LKSB_PUT_LVB)
+	if (lock->lksb->flags & DLM_LKSB_PUT_LVB) {
+		mlog_bug_on_msg(!res->lvb, "lockname: %*s\n", res->lockname.len,
+				res->lockname.name);
 		memcpy(res->lvb, lock->lksb->lvb, DLM_LVB_LEN);
+	}
 
 	status = DLM_NORMAL;
 	*call_ast = 1;
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index 5efdd37..15a4ca2 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -603,9 +603,11 @@ static int dump_lockres(struct dlm_lock_resource *res, char *buf, int len)
 
 	/* lvb */
 	out += snprintf(buf + out, len - out, "LVBX:");
-	for (i = 0; i < DLM_LVB_LEN; i++)
-		out += snprintf(buf + out, len - out,
+	if (res->lvb) {
+		for (i = 0; i < DLM_LVB_LEN; i++)
+			out += snprintf(buf + out, len - out,
 					"%02x", (unsigned char)res->lvb[i]);
+	}
 	out += snprintf(buf + out, len - out, "\n");
 
 	/* granted */
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 153abb5..ecadf78 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -128,9 +128,13 @@ static DECLARE_WAIT_QUEUE_HEAD(dlm_domain_events);
  * will have a negotiated version with the same major number and a minor
  * number equal or smaller.  The dlm_ctxt->dlm_locking_proto field should
  * be used to determine what a running domain is actually using.
+ *
+ * history:
+ * 1.0	base
+ * 2.0	changes dlm_migratable_lockres struct for DLM_MIG_LOCKRES_MSG
  */
 static const struct dlm_protocol_version dlm_protocol = {
-	.pv_major = 1,
+	.pv_major = 2,
 	.pv_minor = 0,
 };
 
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index ffb4c68..090f896 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -545,6 +545,7 @@ static void dlm_lockres_release(struct kref *kref)
 
 	kmem_cache_free(dlm_lockname_cache, (void *)res->lockname.name);
 
+	kfree(res->lvb);
 	kmem_cache_free(dlm_lockres_cache, res);
 }
 
@@ -603,13 +604,13 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
 	list_add_tail(&res->tracking, &dlm->tracking_list);
 	spin_unlock(&dlm->spinlock);
 
-	memset(res->lvb, 0, DLM_LVB_LEN);
 	memset(res->refmap, 0, sizeof(res->refmap));
 }
 
 struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
 				   const char *name,
-				   unsigned int namelen)
+				   unsigned int namelen,
+				   unsigned int reserve_lvb)
 {
 	struct dlm_lock_resource *res = NULL;
 
@@ -621,6 +622,15 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
 	if (!res->lockname.name)
 		goto error;
 
+	res->reserve_lvb = !!reserve_lvb;
+	if (res->reserve_lvb) {
+		res->lvb = kzalloc(DLM_LVB_LEN, GFP_NOFS);
+		if (!res->lvb)
+			goto error;
+	} else {
+		res->lvb = NULL;
+	}
+
 	dlm_init_lockres(dlm, res, name, namelen);
 	return res;
 
@@ -754,7 +764,7 @@ lookup:
 		alloc_mle = kmem_cache_alloc(dlm_mle_cache, GFP_NOFS);
 		if (!alloc_mle)
 			goto leave;
-		res = dlm_new_lockres(dlm, lockid, namelen);
+		res = dlm_new_lockres(dlm, lockid, namelen, flags & LKM_VALBLK);
 		if (!res)
 			goto leave;
 		goto lookup;
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index aaaffbc..bb0fade 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -71,7 +71,7 @@ static inline int dlm_num_locks_in_lockres(struct dlm_lock_resource *res);
 static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres,
 					const char *lockname, int namelen,
 					int total_locks, u64 cookie,
-					u8 flags, u8 master);
+					u8 flags, u8 master, u8 reserve_lvb);
 static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
 				    struct dlm_migratable_lockres *mres,
 				    u8 send_to,
@@ -1148,14 +1148,20 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
 	/* zero and reinit the message buffer */
 	dlm_init_migratable_lockres(mres, res->lockname.name,
 				    res->lockname.len, mres_total_locks,
-				    mig_cookie, orig_flags, orig_master);
+				    mig_cookie, orig_flags, orig_master,
+				    res->reserve_lvb);
 	return ret;
 }
 
 static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres,
-					const char *lockname, int namelen,
-					int total_locks, u64 cookie,
-					u8 flags, u8 master)
+					const char *lockname,
+					int namelen,
+					int total_locks,
+					u64 cookie,
+					u8 flags,
+					u8 master,
+					u8 reserve_lvb
+					)
 {
 	/* mres here is one full page */
 	clear_page(mres);
@@ -1166,6 +1172,7 @@ static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres,
 	mres->mig_cookie = cpu_to_be64(cookie);
 	mres->flags = flags;
 	mres->master = master;
+	mres->reserve_lvb = !!reserve_lvb;
 }
 
 static void dlm_prepare_lvb_for_migration(struct dlm_lock *lock,
@@ -1183,6 +1190,9 @@ static void dlm_prepare_lvb_for_migration(struct dlm_lock *lock,
 	if (lock->ml.type != LKM_EXMODE && lock->ml.type != LKM_PRMODE)
 		return;
 
+	if (!mres->reserve_lvb)
+		return;
+
 	if (dlm_lvb_is_empty(mres->lvb)) {
 		memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN);
 		return;
@@ -1282,7 +1292,8 @@ int dlm_send_one_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
 
 	dlm_init_migratable_lockres(mres, res->lockname.name,
 				    res->lockname.len, total_locks,
-				    mig_cookie, flags, res->owner);
+				    mig_cookie, flags, res->owner,
+				    res->reserve_lvb);
 
 	total_locks = 0;
 	for (i=DLM_GRANTED_LIST; i<=DLM_BLOCKED_LIST; i++) {
@@ -1410,7 +1421,8 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
 	} else {
 		/* need to allocate, just like if it was
 		 * mastered here normally  */
-		res = dlm_new_lockres(dlm, mres->lockname, mres->lockname_len);
+		res = dlm_new_lockres(dlm, mres->lockname, mres->lockname_len,
+				      mres->reserve_lvb);
 		if (!res)
 			goto leave;
 
@@ -1883,6 +1895,14 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
 		if (ml->type == LKM_NLMODE)
 			goto skip_lvb;
 
+		if (!mres->reserve_lvb) {
+			mlog_bug_on_msg(res->lvb, "lockname: %.*s\n",
+					res->lockname.len, res->lockname.name);
+			goto skip_lvb;
+		}
+
+		mlog_bug_on_msg(!res->lvb, "lockname: %.*s\n",
+				res->lockname.len, res->lockname.name);
 		if (!dlm_lvb_is_empty(mres->lvb)) {
 			if (lksb->flags & DLM_LKSB_PUT_LVB) {
 				/* other node was trying to update
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c
index 817287c..9de2e4e 100644
--- a/fs/ocfs2/dlm/dlmunlock.c
+++ b/fs/ocfs2/dlm/dlmunlock.c
@@ -163,6 +163,8 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
 	/* By now this has been masked out of cancel requests. */
 	if (flags & LKM_VALBLK) {
 		/* make the final update to the lvb */
+		mlog_bug_on_msg(!res->lvb, "lockname: %.*s\n",
+				res->lockname.len, res->lockname.name);
 		if (master_node)
 			memcpy(res->lvb, lksb->lvb, DLM_LVB_LEN);
 		else
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 5e02a89..089cb9b 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -1265,6 +1265,9 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
 	mlog(0, "lock %s, level = %d, flags = %u\n", lockres->l_name, level,
 	     dlm_flags);
 
+	if (lockres->l_ops->flags & LOCK_TYPE_USES_LVB)
+		dlm_flags |= DLM_LKF_VALBLK;
+
 	spin_lock_irqsave(&lockres->l_lock, flags);
 	if ((lockres->l_flags & OCFS2_LOCK_ATTACHED) ||
 	    (lockres->l_flags & OCFS2_LOCK_BUSY)) {
-- 
1.7.2.2




More information about the Ocfs2-devel mailing list