[PATCH 13/13] GFS: lock_dlm module

2005-09-01 Thread David Teigland
The lock_dlm module uses the DLM in linux/drivers/dlm/ for inter-node
locking.

Signed-off-by: Ken Preslan <[EMAIL PROTECTED]>
Signed-off-by: David Teigland <[EMAIL PROTECTED]>

---

 fs/gfs2/locking/dlm/Makefile   |3 
 fs/gfs2/locking/dlm/lock.c |  533 +
 fs/gfs2/locking/dlm/lock_dlm.h |  200 +++
 fs/gfs2/locking/dlm/main.c |   62 
 fs/gfs2/locking/dlm/mount.c|  218 
 fs/gfs2/locking/dlm/plock.c|  274 +
 fs/gfs2/locking/dlm/sysfs.c|  283 +
 fs/gfs2/locking/dlm/thread.c   |  355 +++
 include/linux/lock_dlm_plock.h |   40 +++
 9 files changed, 1968 insertions(+)

diff -urpN a/fs/gfs2/locking/dlm/Makefile b/fs/gfs2/locking/dlm/Makefile
--- a/fs/gfs2/locking/dlm/Makefile  1970-01-01 07:30:00.0 +0730
+++ b/fs/gfs2/locking/dlm/Makefile  2005-09-01 17:48:48.143749048 +0800
@@ -0,0 +1,3 @@
+obj-$(CONFIG_GFS2_FS) += lock_dlm.o
+lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o
+
diff -urpN a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
--- a/fs/gfs2/locking/dlm/lock.c1970-01-01 07:30:00.0 +0730
+++ b/fs/gfs2/locking/dlm/lock.c2005-09-01 17:48:48.139749656 +0800
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
+#include "lock_dlm.h"
+
+static char junk_lvb[GDLM_LVB_SIZE];
+
+static void queue_complete(struct gdlm_lock *lp)
+{
+   struct gdlm_ls *ls = lp->ls;
+
+   clear_bit(LFL_ACTIVE, >flags);
+
+   spin_lock(>async_lock);
+   list_add_tail(>clist, >complete);
+   spin_unlock(>async_lock);
+   wake_up(>thread_wait);
+}
+
+static inline void gdlm_ast(void *astarg)
+{
+   queue_complete((struct gdlm_lock *) astarg);
+}
+
+static inline void gdlm_bast(void *astarg, int mode)
+{
+   struct gdlm_lock *lp = astarg;
+   struct gdlm_ls *ls = lp->ls;
+
+   if (!mode) {
+   printk("lock_dlm: bast mode zero %x,%"PRIx64"\n",
+   lp->lockname.ln_type, lp->lockname.ln_number);
+   return;
+   }
+
+   spin_lock(>async_lock);
+   if (!lp->bast_mode) {
+   list_add_tail(>blist, >blocking);
+   lp->bast_mode = mode;
+   } else if (lp->bast_mode < mode)
+   lp->bast_mode = mode;
+   spin_unlock(>async_lock);
+   wake_up(>thread_wait);
+}
+
+void gdlm_queue_delayed(struct gdlm_lock *lp)
+{
+   struct gdlm_ls *ls = lp->ls;
+
+   spin_lock(>async_lock);
+   list_add_tail(>delay_list, >delayed);
+   spin_unlock(>async_lock);
+}
+
+/* convert gfs lock-state to dlm lock-mode */
+
+static int16_t make_mode(int16_t lmstate)
+{
+   switch (lmstate) {
+   case LM_ST_UNLOCKED:
+   return DLM_LOCK_NL;
+   case LM_ST_EXCLUSIVE:
+   return DLM_LOCK_EX;
+   case LM_ST_DEFERRED:
+   return DLM_LOCK_CW;
+   case LM_ST_SHARED:
+   return DLM_LOCK_PR;
+   default:
+   GDLM_ASSERT(0, printk("unknown LM state %d\n", lmstate););
+   }
+}
+
+/* convert dlm lock-mode to gfs lock-state */
+
+int16_t gdlm_make_lmstate(int16_t dlmmode)
+{
+   switch (dlmmode) {
+   case DLM_LOCK_IV:
+   case DLM_LOCK_NL:
+   return LM_ST_UNLOCKED;
+   case DLM_LOCK_EX:
+   return LM_ST_EXCLUSIVE;
+   case DLM_LOCK_CW:
+   return LM_ST_DEFERRED;
+   case DLM_LOCK_PR:
+   return LM_ST_SHARED;
+   default:
+   GDLM_ASSERT(0, printk("unknown DLM mode %d\n", dlmmode););
+   }
+}
+
+/* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and
+   DLM_LOCK_IV are both considered LM_ST_UNLOCKED by GFS. */
+
+static void check_cur_state(struct gdlm_lock *lp, unsigned int cur_state)
+{
+   int16_t cur = make_mode(cur_state);
+   if (lp->cur != DLM_LOCK_IV)
+   GDLM_ASSERT(lp->cur == cur, printk("%d, %d\n", lp->cur, cur););
+}
+
+static inline unsigned int make_flags(struct gdlm_lock *lp,
+ unsigned int gfs_flags,
+ int16_t cur, int16_t req)
+{
+   unsigned int lkf = 0;
+
+   if (gfs_flags & LM_FLAG_TRY)
+   lkf |= DLM_LKF_NOQUEUE;
+
+   if (gfs_flags & LM_FLAG_TRY_1CB) {
+   lkf |= DLM_LKF_NOQUEUE;
+   lkf |= DLM_LKF_NOQUEUEBAST;
+   }
+
+   if (gfs_flags & LM_FLAG_PRIORITY) {
+   lkf |= DLM_LKF_NOORDER;
+   lkf |= DLM_LKF_HEADQUE;
+   }
+
+   if (gfs_flags & LM_FLAG_ANY) {
+   if (req == DLM_LOCK_PR)
+   

[PATCH 13/13] GFS: lock_dlm module

2005-09-01 Thread David Teigland
The lock_dlm module uses the DLM in linux/drivers/dlm/ for inter-node
locking.

Signed-off-by: Ken Preslan [EMAIL PROTECTED]
Signed-off-by: David Teigland [EMAIL PROTECTED]

---

 fs/gfs2/locking/dlm/Makefile   |3 
 fs/gfs2/locking/dlm/lock.c |  533 +
 fs/gfs2/locking/dlm/lock_dlm.h |  200 +++
 fs/gfs2/locking/dlm/main.c |   62 
 fs/gfs2/locking/dlm/mount.c|  218 
 fs/gfs2/locking/dlm/plock.c|  274 +
 fs/gfs2/locking/dlm/sysfs.c|  283 +
 fs/gfs2/locking/dlm/thread.c   |  355 +++
 include/linux/lock_dlm_plock.h |   40 +++
 9 files changed, 1968 insertions(+)

diff -urpN a/fs/gfs2/locking/dlm/Makefile b/fs/gfs2/locking/dlm/Makefile
--- a/fs/gfs2/locking/dlm/Makefile  1970-01-01 07:30:00.0 +0730
+++ b/fs/gfs2/locking/dlm/Makefile  2005-09-01 17:48:48.143749048 +0800
@@ -0,0 +1,3 @@
+obj-$(CONFIG_GFS2_FS) += lock_dlm.o
+lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o
+
diff -urpN a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
--- a/fs/gfs2/locking/dlm/lock.c1970-01-01 07:30:00.0 +0730
+++ b/fs/gfs2/locking/dlm/lock.c2005-09-01 17:48:48.139749656 +0800
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
+#include lock_dlm.h
+
+static char junk_lvb[GDLM_LVB_SIZE];
+
+static void queue_complete(struct gdlm_lock *lp)
+{
+   struct gdlm_ls *ls = lp-ls;
+
+   clear_bit(LFL_ACTIVE, lp-flags);
+
+   spin_lock(ls-async_lock);
+   list_add_tail(lp-clist, ls-complete);
+   spin_unlock(ls-async_lock);
+   wake_up(ls-thread_wait);
+}
+
+static inline void gdlm_ast(void *astarg)
+{
+   queue_complete((struct gdlm_lock *) astarg);
+}
+
+static inline void gdlm_bast(void *astarg, int mode)
+{
+   struct gdlm_lock *lp = astarg;
+   struct gdlm_ls *ls = lp-ls;
+
+   if (!mode) {
+   printk(lock_dlm: bast mode zero %x,%PRIx64\n,
+   lp-lockname.ln_type, lp-lockname.ln_number);
+   return;
+   }
+
+   spin_lock(ls-async_lock);
+   if (!lp-bast_mode) {
+   list_add_tail(lp-blist, ls-blocking);
+   lp-bast_mode = mode;
+   } else if (lp-bast_mode  mode)
+   lp-bast_mode = mode;
+   spin_unlock(ls-async_lock);
+   wake_up(ls-thread_wait);
+}
+
+void gdlm_queue_delayed(struct gdlm_lock *lp)
+{
+   struct gdlm_ls *ls = lp-ls;
+
+   spin_lock(ls-async_lock);
+   list_add_tail(lp-delay_list, ls-delayed);
+   spin_unlock(ls-async_lock);
+}
+
+/* convert gfs lock-state to dlm lock-mode */
+
+static int16_t make_mode(int16_t lmstate)
+{
+   switch (lmstate) {
+   case LM_ST_UNLOCKED:
+   return DLM_LOCK_NL;
+   case LM_ST_EXCLUSIVE:
+   return DLM_LOCK_EX;
+   case LM_ST_DEFERRED:
+   return DLM_LOCK_CW;
+   case LM_ST_SHARED:
+   return DLM_LOCK_PR;
+   default:
+   GDLM_ASSERT(0, printk(unknown LM state %d\n, lmstate););
+   }
+}
+
+/* convert dlm lock-mode to gfs lock-state */
+
+int16_t gdlm_make_lmstate(int16_t dlmmode)
+{
+   switch (dlmmode) {
+   case DLM_LOCK_IV:
+   case DLM_LOCK_NL:
+   return LM_ST_UNLOCKED;
+   case DLM_LOCK_EX:
+   return LM_ST_EXCLUSIVE;
+   case DLM_LOCK_CW:
+   return LM_ST_DEFERRED;
+   case DLM_LOCK_PR:
+   return LM_ST_SHARED;
+   default:
+   GDLM_ASSERT(0, printk(unknown DLM mode %d\n, dlmmode););
+   }
+}
+
+/* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and
+   DLM_LOCK_IV are both considered LM_ST_UNLOCKED by GFS. */
+
+static void check_cur_state(struct gdlm_lock *lp, unsigned int cur_state)
+{
+   int16_t cur = make_mode(cur_state);
+   if (lp-cur != DLM_LOCK_IV)
+   GDLM_ASSERT(lp-cur == cur, printk(%d, %d\n, lp-cur, cur););
+}
+
+static inline unsigned int make_flags(struct gdlm_lock *lp,
+ unsigned int gfs_flags,
+ int16_t cur, int16_t req)
+{
+   unsigned int lkf = 0;
+
+   if (gfs_flags  LM_FLAG_TRY)
+   lkf |= DLM_LKF_NOQUEUE;
+
+   if (gfs_flags  LM_FLAG_TRY_1CB) {
+   lkf |= DLM_LKF_NOQUEUE;
+   lkf |= DLM_LKF_NOQUEUEBAST;
+   }
+
+   if (gfs_flags  LM_FLAG_PRIORITY) {
+   lkf |= DLM_LKF_NOORDER;
+   lkf |= DLM_LKF_HEADQUE;
+   }
+
+   if (gfs_flags  LM_FLAG_ANY) {
+   if (req == DLM_LOCK_PR)
+   lkf