[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