[Ocfs2-commits] khackel commits r2470 - trunk/fs/ocfs2/dlm

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Jul 19 16:50:32 CDT 2005


Author: khackel
Signed-off-by: mfasheh
Date: 2005-07-19 16:50:30 -0500 (Tue, 19 Jul 2005)
New Revision: 2470

Modified:
   trunk/fs/ocfs2/dlm/dlmapi.h
   trunk/fs/ocfs2/dlm/dlmcommon.h
   trunk/fs/ocfs2/dlm/dlmdomain.c
   trunk/fs/ocfs2/dlm/dlmlock.c
   trunk/fs/ocfs2/dlm/dlmmaster.c
   trunk/fs/ocfs2/dlm/dlmthread.c
   trunk/fs/ocfs2/dlm/dlmunlock.c
Log:
* fixes bug521: dlm BUG at dlmlock.c:292
* add a waitqueue woken at the end of AST/BAST flushing, make use of
  this in dlm_mark_lockres_migrating and the dlmunlock paths
* move the KERNEL_ALLOCATED flag off of the lksb and onto the dlm_lock
  to avoid having to reference the lksb in the lock release path,
  if possible

Signed-off-by: mfasheh



Modified: trunk/fs/ocfs2/dlm/dlmapi.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmapi.h	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmapi.h	2005-07-19 21:50:30 UTC (rev 2470)
@@ -86,8 +86,7 @@
 
 
 
-#define DLM_LKSB_KERNEL_ALLOCATED  0x01  /* allocated on master node on
-					    behalf of remote node */
+#define DLM_LKSB_UNUSED1           0x01  
 #define DLM_LKSB_PUT_LVB           0x02
 #define DLM_LKSB_GET_LVB           0x04
 #define DLM_LKSB_UNUSED2           0x08

Modified: trunk/fs/ocfs2/dlm/dlmcommon.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmcommon.h	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmcommon.h	2005-07-19 21:50:30 UTC (rev 2470)
@@ -124,6 +124,7 @@
 	struct task_struct *dlm_reco_thread_task;
 	wait_queue_head_t dlm_thread_wq;
 	wait_queue_head_t dlm_reco_thread_wq;
+	wait_queue_head_t ast_wq;
 
 	struct work_struct dispatched_work;
 	struct list_head work_list;
@@ -276,12 +277,12 @@
 		 convert_pending:1,
 		 lock_pending:1,
 		 cancel_pending:1,
-		 unlock_pending:1;
+		 unlock_pending:1,
+		 lksb_kernel_allocated:1;
 };
 
 
-#define DLM_LKSB_KERNEL_ALLOCATED  0x01  /* allocated on master node on
-					    behalf of remote node */
+#define DLM_LKSB_UNUSED1           0x01
 #define DLM_LKSB_PUT_LVB           0x02
 #define DLM_LKSB_GET_LVB           0x04
 #define DLM_LKSB_UNUSED2           0x08
@@ -1045,6 +1046,7 @@
 			   struct dlm_node_iter *iter);
 void dlm_clean_master_list(struct dlm_ctxt *dlm,
 			   u8 dead_node);
+int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 
 
 int dlm_dump_all_mles(const char __user *data, unsigned int len);

Modified: trunk/fs/ocfs2/dlm/dlmdomain.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmdomain.c	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmdomain.c	2005-07-19 21:50:30 UTC (rev 2470)
@@ -1228,6 +1228,7 @@
 	init_waitqueue_head(&dlm->dlm_thread_wq);
 	init_waitqueue_head(&dlm->dlm_reco_thread_wq);
 	init_waitqueue_head(&dlm->reco.event);
+	init_waitqueue_head(&dlm->ast_wq);
 	INIT_LIST_HEAD(&dlm->master_list);
 	INIT_LIST_HEAD(&dlm->mle_hb_events);
 

Modified: trunk/fs/ocfs2/dlm/dlmlock.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmlock.c	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmlock.c	2005-07-19 21:50:30 UTC (rev 2470)
@@ -284,12 +284,9 @@
 static void dlm_lock_release(struct kref *kref)
 {
 	struct dlm_lock *lock;
-	struct dlm_lockstatus *lksb;
 
 	lock = container_of(kref, struct dlm_lock, lock_refs);
 
-	lksb = lock->lksb;
-	BUG_ON(lksb->lockid != lock);
 	BUG_ON(!list_empty(&lock->list));
 	BUG_ON(!list_empty(&lock->ast_list));
 	BUG_ON(!list_empty(&lock->bast_list));
@@ -298,12 +295,9 @@
 
 	dlm_lock_detach_lockres(lock);
 
-	if (lksb->flags & DLM_LKSB_KERNEL_ALLOCATED) {
+	if (lock->lksb_kernel_allocated) {
 		mlog(0, "freeing kernel-allocated lksb\n");
-		kfree(lksb);
-	} else {
-		mlog(0, "clearing lockid pointer on user-allocated lksb\n");
-		lksb->lockid = NULL;
+		kfree(lock->lksb);
 	}
 	kfree(lock);
 }
@@ -353,6 +347,7 @@
 	newlock->lock_pending = 0;
 	newlock->unlock_pending = 0;
 	newlock->cancel_pending = 0;
+	newlock->lksb_kernel_allocated = 0;
 
 	kref_init(&newlock->lock_refs, dlm_lock_release);
 }
@@ -361,6 +356,7 @@
 			       struct dlm_lockstatus *lksb)
 {
 	struct dlm_lock *lock;
+	int kernel_allocated = 0;
 
 	lock = kcalloc(1, sizeof(*lock), GFP_KERNEL);
 	if (!lock)
@@ -373,10 +369,12 @@
 			kfree(lock);
 			return NULL;
 		}
-		lksb->flags |= DLM_LKSB_KERNEL_ALLOCATED;
+		kernel_allocated = 1;
 	}
 
 	dlm_init_lock(lock, type, node, cookie);
+	if (kernel_allocated)
+		lock->lksb_kernel_allocated = 1;
 	lock->lksb = lksb;
 	lksb->lockid = lock;
 	return lock;

Modified: trunk/fs/ocfs2/dlm/dlmmaster.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmaster.c	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmmaster.c	2005-07-19 21:50:30 UTC (rev 2470)
@@ -1878,7 +1878,44 @@
 }
 EXPORT_SYMBOL_GPL(dlm_migrate_lockres);
 
+int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	int ret;
+	spin_lock(&dlm->ast_lock);
+	spin_lock(&lock->spinlock);
+	ret = (list_empty(&lock->bast_list) && !lock->bast_pending);
+	spin_unlock(&lock->spinlock);
+	spin_unlock(&dlm->ast_lock);
+	return ret;
+}
 
+static int dlm_lockres_asts_flushed(struct dlm_ctxt *dlm,
+				    struct dlm_lock_resource *res)
+{
+	int ret = 1;
+	int i;
+	struct list_head *queue, *iter;
+	struct dlm_lock *lock;
+
+	spin_lock(&res->spinlock);
+
+	for (i=DLM_GRANTED_LIST; i<=DLM_BLOCKED_LIST; i++) {
+		queue = dlm_list_idx_to_ptr(res, i);
+		list_for_each(iter, queue) {
+			lock = list_entry(iter, struct dlm_lock, list);
+			if (!list_empty(&lock->ast_list) ||
+			    !list_empty(&lock->bast_list)) {
+				ret = 0;
+				goto leave;
+			}
+		}
+	}	
+leave:
+	spin_unlock(&res->spinlock);
+	return ret;
+}
+
+
 static void dlm_mark_lockres_migrating(struct dlm_ctxt *dlm,
 				       struct dlm_lock_resource *res)
 {
@@ -1894,6 +1931,7 @@
 
 	/* now flush all the pending asts.. hang out for a bit */
 	dlm_flush_lockres_asts(dlm, res);
+	wait_event(dlm->ast_wq, dlm_lockres_asts_flushed(dlm, res));
 	dlm_lockres_release_ast(res);
 
 	/* if the extra ref we just put was the final one, this

Modified: trunk/fs/ocfs2/dlm/dlmthread.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmthread.c	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmthread.c	2005-07-19 21:50:30 UTC (rev 2470)
@@ -591,6 +591,7 @@
 		dlm_lockres_release_ast(res);
 	}
 	spin_unlock(&dlm->ast_lock);
+	wake_up(&dlm->ast_wq);
 }
 
 

Modified: trunk/fs/ocfs2/dlm/dlmunlock.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmunlock.c	2005-07-13 23:58:20 UTC (rev 2469)
+++ trunk/fs/ocfs2/dlm/dlmunlock.c	2005-07-19 21:50:30 UTC (rev 2470)
@@ -627,6 +627,17 @@
 
 	if (call_ast) {
 		mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status);
+		if (is_master) {
+			/* it is possible that there is one last bast 
+			 * pending.  make sure it is flushed, then
+			 * call the unlockast.
+			 * not an issue if this is a mastered remotely,
+			 * since this lock has been removed from the
+			 * lockres queues and cannot be found. */
+			dlm_kick_thread(dlm, NULL);
+			wait_event(dlm->ast_wq, 
+				   dlm_lock_basts_flushed(dlm, lock));
+		}
 		(*unlockast)(data, lksb->status);
 	}
 



More information about the Ocfs2-commits mailing list