FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 04-15-2008, 09:02 PM
David Teigland
 
Default dlm: move plock code from gfs2

Move the code that handles cluster posix locks from gfs2 into the dlm
so that it can be used by both gfs2 and ocfs2.

Signed-off-by: David Teigland <teigland@redhat.com>
---
fs/dlm/Makefile | 1 +
fs/dlm/dlm_internal.h | 2 +
fs/dlm/main.c | 7 +
fs/dlm/plock.c | 439 ++++++++++++++++++++++++++++++++++++++++
fs/gfs2/locking/dlm/Makefile | 2 +-
fs/gfs2/locking/dlm/lock_dlm.h | 11 +-
fs/gfs2/locking/dlm/main.c | 8 -
fs/gfs2/locking/dlm/mount.c | 21 ++
fs/gfs2/locking/dlm/plock.c | 406 -------------------------------------
include/linux/Kbuild | 2 +-
include/linux/dlm_plock.h | 50 +++++
include/linux/lock_dlm_plock.h | 41 ----
12 files changed, 523 insertions(+), 467 deletions(-)
create mode 100644 fs/dlm/plock.c
delete mode 100644 fs/gfs2/locking/dlm/plock.c
create mode 100644 include/linux/dlm_plock.h
delete mode 100644 include/linux/lock_dlm_plock.h

diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile
index d248e60..ca1c912 100644
--- a/fs/dlm/Makefile
+++ b/fs/dlm/Makefile
@@ -10,6 +10,7 @@ dlm-y := ast.o
midcomms.o
netlink.o
lowcomms.o
+ plock.o
rcom.o
recover.o
recoverd.o
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index c70c8e5..caa1581 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -582,6 +582,8 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
int dlm_netlink_init(void);
void dlm_netlink_exit(void);
void dlm_timeout_warn(struct dlm_lkb *lkb);
+int dlm_plock_init(void);
+void dlm_plock_exit(void);

#ifdef CONFIG_DLM_DEBUG
int dlm_register_debugfs(void);
diff --git a/fs/dlm/main.c b/fs/dlm/main.c
index 58487fb..b80e0aa 100644
--- a/fs/dlm/main.c
+++ b/fs/dlm/main.c
@@ -46,10 +46,16 @@ static int __init init_dlm(void)
if (error)
goto out_user;

+ error = dlm_plock_init();
+ if (error)
+ goto out_netlink;
+
printk("DLM (built %s %s) installed
", __DATE__, __TIME__);

return 0;

+ out_netlink:
+ dlm_netlink_exit();
out_user:
dlm_user_exit();
out_debug:
@@ -66,6 +72,7 @@ static int __init init_dlm(void)

static void __exit exit_dlm(void)
{
+ dlm_plock_exit();
dlm_netlink_exit();
dlm_user_exit();
dlm_config_exit();
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
new file mode 100644
index 0000000..d6d6e37
--- /dev/null
+++ b/fs/dlm/plock.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2005-2008 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 version 2.
+ */
+
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include <linux/dlm.h>
+#include <linux/dlm_plock.h>
+
+#include "dlm_internal.h"
+#include "lockspace.h"
+
+static spinlock_t ops_lock;
+static struct list_head send_list;
+static struct list_head recv_list;
+static wait_queue_head_t send_wq;
+static wait_queue_head_t recv_wq;
+
+struct plock_op {
+ struct list_head list;
+ int done;
+ struct dlm_plock_info info;
+};
+
+struct plock_xop {
+ struct plock_op xop;
+ void *callback;
+ void *fl;
+ void *file;
+ struct file_lock flc;
+};
+
+
+static inline void set_version(struct dlm_plock_info *info)
+{
+ info->version[0] = DLM_PLOCK_VERSION_MAJOR;
+ info->version[1] = DLM_PLOCK_VERSION_MINOR;
+ info->version[2] = DLM_PLOCK_VERSION_PATCH;
+}
+
+static int check_version(struct dlm_plock_info *info)
+{
+ if ((DLM_PLOCK_VERSION_MAJOR != info->version[0]) ||
+ (DLM_PLOCK_VERSION_MINOR < info->version[1])) {
+ log_print("plock device version mismatch: "
+ "kernel (%u.%u.%u), user (%u.%u.%u)",
+ DLM_PLOCK_VERSION_MAJOR,
+ DLM_PLOCK_VERSION_MINOR,
+ DLM_PLOCK_VERSION_PATCH,
+ info->version[0],
+ info->version[1],
+ info->version[2]);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void send_op(struct plock_op *op)
+{
+ set_version(&op->info);
+ INIT_LIST_HEAD(&op->list);
+ spin_lock(&ops_lock);
+ list_add_tail(&op->list, &send_list);
+ spin_unlock(&ops_lock);
+ wake_up(&send_wq);
+}
+
+int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
+ int cmd, struct file_lock *fl)
+{
+ struct dlm_ls *ls;
+ struct plock_op *op;
+ struct plock_xop *xop;
+ int rv;
+
+ ls = dlm_find_lockspace_local(lockspace);
+ if (!ls)
+ return -EINVAL;
+
+ xop = kzalloc(sizeof(*xop), GFP_KERNEL);
+ if (!xop) {
+ rv = -ENOMEM;
+ goto out;
+ }
+
+ op = &xop->xop;
+ op->info.optype = DLM_PLOCK_OP_LOCK;
+ op->info.pid = fl->fl_pid;
+ op->info.ex = (fl->fl_type == F_WRLCK);
+ op->info.wait = IS_SETLKW(cmd);
+ op->info.fsid = ls->ls_global_id;
+ op->info.number = number;
+ op->info.start = fl->fl_start;
+ op->info.end = fl->fl_end;
+ if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
+ /* fl_owner is lockd which doesn't distinguish
+ processes on the nfs client */
+ op->info.owner = (__u64) fl->fl_pid;
+ xop->callback = fl->fl_lmops->fl_grant;
+ locks_init_lock(&xop->flc);
+ locks_copy_lock(&xop->flc, fl);
+ xop->fl = fl;
+ xop->file = file;
+ } else {
+ op->info.owner = (__u64)(long) fl->fl_owner;
+ xop->callback = NULL;
+ }
+
+ send_op(op);
+
+ if (xop->callback == NULL)
+ wait_event(recv_wq, (op->done != 0));
+ else {
+ rv = -EINPROGRESS;
+ goto out;
+ }
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ log_error(ls, "dlm_posix_lock: op on list %llx",
+ (unsigned long long)number);
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ rv = op->info.rv;
+
+ if (!rv) {
+ if (posix_lock_file_wait(file, fl) < 0)
+ log_error(ls, "dlm_posix_lock: vfs lock error %llx",
+ (unsigned long long)number);
+ }
+
+ kfree(xop);
+out:
+ dlm_put_lockspace(ls);
+ return rv;
+}
+EXPORT_SYMBOL_GPL(dlm_posix_lock);
+
+/* Returns failure iff a succesful lock operation should be canceled */
+static int dlm_plock_callback(struct plock_op *op)
+{
+ struct file *file;
+ struct file_lock *fl;
+ struct file_lock *flc;
+ int (*notify)(void *, void *, int) = NULL;
+ struct plock_xop *xop = (struct plock_xop *)op;
+ int rv = 0;
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ log_print("dlm_plock_callback: op on list %llx",
+ (unsigned long long)op->info.number);
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ /* check if the following 2 are still valid or make a copy */
+ file = xop->file;
+ flc = &xop->flc;
+ fl = xop->fl;
+ notify = xop->callback;
+
+ if (op->info.rv) {
+ notify(flc, NULL, op->info.rv);
+ goto out;
+ }
+
+ /* got fs lock; bookkeep locally as well: */
+ flc->fl_flags &= ~FL_SLEEP;
+ if (posix_lock_file(file, flc, NULL)) {
+ /*
+ * This can only happen in the case of kmalloc() failure.
+ * The filesystem's own lock is the authoritative lock,
+ * so a failure to get the lock locally is not a disaster.
+ * As long as the fs cannot reliably cancel locks (especially
+ * in a low-memory situation), we're better off ignoring
+ * this failure than trying to recover.
+ */
+ log_print("dlm_plock_callback: vfs lock error %llx file %p fl %p",
+ (unsigned long long)op->info.number, file, fl);
+ }
+
+ rv = notify(flc, NULL, 0);
+ if (rv) {
+ /* XXX: We need to cancel the fs lock here: */
+ log_print("dlm_plock_callback: lock granted after lock request "
+ "failed; dangling lock!
");
+ goto out;
+ }
+
+out:
+ kfree(xop);
+ return rv;
+}
+
+int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
+ struct file_lock *fl)
+{
+ struct dlm_ls *ls;
+ struct plock_op *op;
+ int rv;
+
+ ls = dlm_find_lockspace_local(lockspace);
+ if (!ls)
+ return -EINVAL;
+
+ op = kzalloc(sizeof(*op), GFP_KERNEL);
+ if (!op) {
+ rv = -ENOMEM;
+ goto out;
+ }
+
+ if (posix_lock_file_wait(file, fl) < 0)
+ log_error(ls, "dlm_posix_unlock: vfs unlock error %llx",
+ (unsigned long long)number);
+
+ op->info.optype = DLM_PLOCK_OP_UNLOCK;
+ op->info.pid = fl->fl_pid;
+ op->info.fsid = ls->ls_global_id;
+ op->info.number = number;
+ op->info.start = fl->fl_start;
+ op->info.end = fl->fl_end;
+ if (fl->fl_lmops && fl->fl_lmops->fl_grant)
+ op->info.owner = (__u64) fl->fl_pid;
+ else
+ op->info.owner = (__u64)(long) fl->fl_owner;
+
+ send_op(op);
+ wait_event(recv_wq, (op->done != 0));
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ log_error(ls, "dlm_posix_unlock: op on list %llx",
+ (unsigned long long)number);
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ rv = op->info.rv;
+
+ if (rv == -ENOENT)
+ rv = 0;
+
+ kfree(op);
+out:
+ dlm_put_lockspace(ls);
+ return rv;
+}
+EXPORT_SYMBOL_GPL(dlm_posix_unlock);
+
+int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
+ struct file_lock *fl)
+{
+ struct dlm_ls *ls;
+ struct plock_op *op;
+ int rv;
+
+ ls = dlm_find_lockspace_local(lockspace);
+ if (!ls)
+ return -EINVAL;
+
+ op = kzalloc(sizeof(*op), GFP_KERNEL);
+ if (!op) {
+ rv = -ENOMEM;
+ goto out;
+ }
+
+ op->info.optype = DLM_PLOCK_OP_GET;
+ op->info.pid = fl->fl_pid;
+ op->info.ex = (fl->fl_type == F_WRLCK);
+ op->info.fsid = ls->ls_global_id;
+ op->info.number = number;
+ op->info.start = fl->fl_start;
+ op->info.end = fl->fl_end;
+ if (fl->fl_lmops && fl->fl_lmops->fl_grant)
+ op->info.owner = (__u64) fl->fl_pid;
+ else
+ op->info.owner = (__u64)(long) fl->fl_owner;
+
+ send_op(op);
+ wait_event(recv_wq, (op->done != 0));
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ log_error(ls, "dlm_posix_get: op on list %llx",
+ (unsigned long long)number);
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ /* info.rv from userspace is 1 for conflict, 0 for no-conflict,
+ -ENOENT if there are no locks on the file */
+
+ rv = op->info.rv;
+
+ fl->fl_type = F_UNLCK;
+ if (rv == -ENOENT)
+ rv = 0;
+ else if (rv > 0) {
+ fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
+ fl->fl_pid = op->info.pid;
+ fl->fl_start = op->info.start;
+ fl->fl_end = op->info.end;
+ rv = 0;
+ }
+
+ kfree(op);
+out:
+ dlm_put_lockspace(ls);
+ return rv;
+}
+EXPORT_SYMBOL_GPL(dlm_posix_get);
+
+/* a read copies out one plock request from the send list */
+static ssize_t dev_read(struct file *file, char __user *u, size_t count,
+ loff_t *ppos)
+{
+ struct dlm_plock_info info;
+ struct plock_op *op = NULL;
+
+ if (count < sizeof(info))
+ return -EINVAL;
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&send_list)) {
+ op = list_entry(send_list.next, struct plock_op, list);
+ list_move(&op->list, &recv_list);
+ memcpy(&info, &op->info, sizeof(info));
+ }
+ spin_unlock(&ops_lock);
+
+ if (!op)
+ return -EAGAIN;
+
+ if (copy_to_user(u, &info, sizeof(info)))
+ return -EFAULT;
+ return sizeof(info);
+}
+
+/* a write copies in one plock result that should match a plock_op
+ on the recv list */
+static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
+ loff_t *ppos)
+{
+ struct dlm_plock_info info;
+ struct plock_op *op;
+ int found = 0;
+
+ if (count != sizeof(info))
+ return -EINVAL;
+
+ if (copy_from_user(&info, u, sizeof(info)))
+ return -EFAULT;
+
+ if (check_version(&info))
+ return -EINVAL;
+
+ spin_lock(&ops_lock);
+ list_for_each_entry(op, &recv_list, list) {
+ if (op->info.fsid == info.fsid && op->info.number == info.number &&
+ op->info.owner == info.owner) {
+ list_del_init(&op->list);
+ found = 1;
+ op->done = 1;
+ memcpy(&op->info, &info, sizeof(info));
+ break;
+ }
+ }
+ spin_unlock(&ops_lock);
+
+ if (found) {
+ struct plock_xop *xop;
+ xop = (struct plock_xop *)op;
+ if (xop->callback)
+ count = dlm_plock_callback(op);
+ else
+ wake_up(&recv_wq);
+ } else
+ log_print("dev_write no op %x %llx", info.fsid,
+ (unsigned long long)info.number);
+ return count;
+}
+
+static unsigned int dev_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask = 0;
+
+ poll_wait(file, &send_wq, wait);
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&send_list))
+ mask = POLLIN | POLLRDNORM;
+ spin_unlock(&ops_lock);
+
+ return mask;
+}
+
+static const struct file_operations dev_fops = {
+ .read = dev_read,
+ .write = dev_write,
+ .poll = dev_poll,
+ .owner = THIS_MODULE
+};
+
+static struct miscdevice plock_dev_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = DLM_PLOCK_MISC_NAME,
+ .fops = &dev_fops
+};
+
+int dlm_plock_init(void)
+{
+ int rv;
+
+ spin_lock_init(&ops_lock);
+ INIT_LIST_HEAD(&send_list);
+ INIT_LIST_HEAD(&recv_list);
+ init_waitqueue_head(&send_wq);
+ init_waitqueue_head(&recv_wq);
+
+ rv = misc_register(&plock_dev_misc);
+ if (rv)
+ log_print("dlm_plock_init: misc_register failed %d", rv);
+ return rv;
+}
+
+void dlm_plock_exit(void)
+{
+ if (misc_deregister(&plock_dev_misc) < 0)
+ log_print("dlm_plock_exit: misc_deregister failed");
+}
+
diff --git a/fs/gfs2/locking/dlm/Makefile b/fs/gfs2/locking/dlm/Makefile
index 89b93b6..2609bb6 100644
--- a/fs/gfs2/locking/dlm/Makefile
+++ b/fs/gfs2/locking/dlm/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o
-lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o
+lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o

diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h
index 9e8265d..55e92af 100644
--- a/fs/gfs2/locking/dlm/lock_dlm.h
+++ b/fs/gfs2/locking/dlm/lock_dlm.h
@@ -25,6 +25,7 @@
#include <net/sock.h>

#include <linux/dlm.h>
+#include <linux/dlm_plock.h>
#include <linux/lm_interface.h>

/*
@@ -173,15 +174,5 @@ void gdlm_cancel(void *);
int gdlm_hold_lvb(void *, char **);
void gdlm_unhold_lvb(void *, char *);

-/* plock.c */
-
-int gdlm_plock_init(void);
-void gdlm_plock_exit(void);
-int gdlm_plock(void *, struct lm_lockname *, struct file *, int,
- struct file_lock *);
-int gdlm_plock_get(void *, struct lm_lockname *, struct file *,
- struct file_lock *);
-int gdlm_punlock(void *, struct lm_lockname *, struct file *,
- struct file_lock *);
#endif

diff --git a/fs/gfs2/locking/dlm/main.c b/fs/gfs2/locking/dlm/main.c
index a0e7eda..867763c 100644
--- a/fs/gfs2/locking/dlm/main.c
+++ b/fs/gfs2/locking/dlm/main.c
@@ -30,13 +30,6 @@ static int __init init_lock_dlm(void)
return error;
}

- error = gdlm_plock_init();
- if (error) {
- gdlm_sysfs_exit();
- gfs2_unregister_lockproto(&gdlm_ops);
- return error;
- }
-
printk(KERN_INFO
"Lock_DLM (built %s %s) installed
", __DATE__, __TIME__);
return 0;
@@ -44,7 +37,6 @@ static int __init init_lock_dlm(void)

static void __exit exit_lock_dlm(void)
{
- gdlm_plock_exit();
gdlm_sysfs_exit();
gfs2_unregister_lockproto(&gdlm_ops);
}
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c
index f2efff4..470bdf6 100644
--- a/fs/gfs2/locking/dlm/mount.c
+++ b/fs/gfs2/locking/dlm/mount.c
@@ -236,6 +236,27 @@ static void gdlm_withdraw(void *lockspace)
gdlm_kobject_release(ls);
}

+static int gdlm_plock(void *lockspace, struct lm_lockname *name,
+ struct file *file, int cmd, struct file_lock *fl)
+{
+ struct gdlm_ls *ls = lockspace;
+ return dlm_posix_lock(ls->dlm_lockspace, name->ln_number, file, cmd, fl);
+}
+
+static int gdlm_punlock(void *lockspace, struct lm_lockname *name,
+ struct file *file, struct file_lock *fl)
+{
+ struct gdlm_ls *ls = lockspace;
+ return dlm_posix_unlock(ls->dlm_lockspace, name->ln_number, file, fl);
+}
+
+static int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
+ struct file *file, struct file_lock *fl)
+{
+ struct gdlm_ls *ls = lockspace;
+ return dlm_posix_get(ls->dlm_lockspace, name->ln_number, file, fl);
+}
+
const struct lm_lockops gdlm_ops = {
.lm_proto_name = "lock_dlm",
.lm_mount = gdlm_mount,
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
deleted file mode 100644
index 2ebd374..0000000
--- a/fs/gfs2/locking/dlm/plock.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 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 version 2.
- */
-
-#include <linux/miscdevice.h>
-#include <linux/lock_dlm_plock.h>
-#include <linux/poll.h>
-
-#include "lock_dlm.h"
-
-
-static spinlock_t ops_lock;
-static struct list_head send_list;
-static struct list_head recv_list;
-static wait_queue_head_t send_wq;
-static wait_queue_head_t recv_wq;
-
-struct plock_op {
- struct list_head list;
- int done;
- struct gdlm_plock_info info;
-};
-
-struct plock_xop {
- struct plock_op xop;
- void *callback;
- void *fl;
- void *file;
- struct file_lock flc;
-};
-
-
-static inline void set_version(struct gdlm_plock_info *info)
-{
- info->version[0] = GDLM_PLOCK_VERSION_MAJOR;
- info->version[1] = GDLM_PLOCK_VERSION_MINOR;
- info->version[2] = GDLM_PLOCK_VERSION_PATCH;
-}
-
-static int check_version(struct gdlm_plock_info *info)
-{
- if ((GDLM_PLOCK_VERSION_MAJOR != info->version[0]) ||
- (GDLM_PLOCK_VERSION_MINOR < info->version[1])) {
- log_error("plock device version mismatch: "
- "kernel (%u.%u.%u), user (%u.%u.%u)",
- GDLM_PLOCK_VERSION_MAJOR,
- GDLM_PLOCK_VERSION_MINOR,
- GDLM_PLOCK_VERSION_PATCH,
- info->version[0],
- info->version[1],
- info->version[2]);
- return -EINVAL;
- }
- return 0;
-}
-
-static void send_op(struct plock_op *op)
-{
- set_version(&op->info);
- INIT_LIST_HEAD(&op->list);
- spin_lock(&ops_lock);
- list_add_tail(&op->list, &send_list);
- spin_unlock(&ops_lock);
- wake_up(&send_wq);
-}
-
-int gdlm_plock(void *lockspace, struct lm_lockname *name,
- struct file *file, int cmd, struct file_lock *fl)
-{
- struct gdlm_ls *ls = lockspace;
- struct plock_op *op;
- struct plock_xop *xop;
- int rv;
-
- xop = kzalloc(sizeof(*xop), GFP_KERNEL);
- if (!xop)
- return -ENOMEM;
-
- op = &xop->xop;
- op->info.optype = GDLM_PLOCK_OP_LOCK;
- op->info.pid = fl->fl_pid;
- op->info.ex = (fl->fl_type == F_WRLCK);
- op->info.wait = IS_SETLKW(cmd);
- op->info.fsid = ls->id;
- op->info.number = name->ln_number;
- op->info.start = fl->fl_start;
- op->info.end = fl->fl_end;
- if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
- /* fl_owner is lockd which doesn't distinguish
- processes on the nfs client */
- op->info.owner = (__u64) fl->fl_pid;
- xop->callback = fl->fl_lmops->fl_grant;
- locks_init_lock(&xop->flc);
- locks_copy_lock(&xop->flc, fl);
- xop->fl = fl;
- xop->file = file;
- } else {
- op->info.owner = (__u64)(long) fl->fl_owner;
- xop->callback = NULL;
- }
-
- send_op(op);
-
- if (xop->callback == NULL)
- wait_event(recv_wq, (op->done != 0));
- else
- return -EINPROGRESS;
-
- spin_lock(&ops_lock);
- if (!list_empty(&op->list)) {
- printk(KERN_INFO "plock op on list
");
- list_del(&op->list);
- }
- spin_unlock(&ops_lock);
-
- rv = op->info.rv;
-
- if (!rv) {
- if (posix_lock_file_wait(file, fl) < 0)
- log_error("gdlm_plock: vfs lock error %x,%llx",
- name->ln_type,
- (unsigned long long)name->ln_number);
- }
-
- kfree(xop);
- return rv;
-}
-
-/* Returns failure iff a succesful lock operation should be canceled */
-static int gdlm_plock_callback(struct plock_op *op)
-{
- struct file *file;
- struct file_lock *fl;
- struct file_lock *flc;
- int (*notify)(void *, void *, int) = NULL;
- struct plock_xop *xop = (struct plock_xop *)op;
- int rv = 0;
-
- spin_lock(&ops_lock);
- if (!list_empty(&op->list)) {
- printk(KERN_INFO "plock op on list
");
- list_del(&op->list);
- }
- spin_unlock(&ops_lock);
-
- /* check if the following 2 are still valid or make a copy */
- file = xop->file;
- flc = &xop->flc;
- fl = xop->fl;
- notify = xop->callback;
-
- if (op->info.rv) {
- notify(flc, NULL, op->info.rv);
- goto out;
- }
-
- /* got fs lock; bookkeep locally as well: */
- flc->fl_flags &= ~FL_SLEEP;
- if (posix_lock_file(file, flc, NULL)) {
- /*
- * This can only happen in the case of kmalloc() failure.
- * The filesystem's own lock is the authoritative lock,
- * so a failure to get the lock locally is not a disaster.
- * As long as GFS cannot reliably cancel locks (especially
- * in a low-memory situation), we're better off ignoring
- * this failure than trying to recover.
- */
- log_error("gdlm_plock: vfs lock error file %p fl %p",
- file, fl);
- }
-
- rv = notify(flc, NULL, 0);
- if (rv) {
- /* XXX: We need to cancel the fs lock here: */
- printk("gfs2 lock granted after lock request failed;"
- " dangling lock!
");
- goto out;
- }
-
-out:
- kfree(xop);
- return rv;
-}
-
-int gdlm_punlock(void *lockspace, struct lm_lockname *name,
- struct file *file, struct file_lock *fl)
-{
- struct gdlm_ls *ls = lockspace;
- struct plock_op *op;
- int rv;
-
- op = kzalloc(sizeof(*op), GFP_KERNEL);
- if (!op)
- return -ENOMEM;
-
- if (posix_lock_file_wait(file, fl) < 0)
- log_error("gdlm_punlock: vfs unlock error %x,%llx",
- name->ln_type, (unsigned long long)name->ln_number);
-
- op->info.optype = GDLM_PLOCK_OP_UNLOCK;
- op->info.pid = fl->fl_pid;
- op->info.fsid = ls->id;
- op->info.number = name->ln_number;
- op->info.start = fl->fl_start;
- op->info.end = fl->fl_end;
- if (fl->fl_lmops && fl->fl_lmops->fl_grant)
- op->info.owner = (__u64) fl->fl_pid;
- else
- op->info.owner = (__u64)(long) fl->fl_owner;
-
- send_op(op);
- wait_event(recv_wq, (op->done != 0));
-
- spin_lock(&ops_lock);
- if (!list_empty(&op->list)) {
- printk(KERN_INFO "punlock op on list
");
- list_del(&op->list);
- }
- spin_unlock(&ops_lock);
-
- rv = op->info.rv;
-
- if (rv == -ENOENT)
- rv = 0;
-
- kfree(op);
- return rv;
-}
-
-int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
- struct file *file, struct file_lock *fl)
-{
- struct gdlm_ls *ls = lockspace;
- struct plock_op *op;
- int rv;
-
- op = kzalloc(sizeof(*op), GFP_KERNEL);
- if (!op)
- return -ENOMEM;
-
- op->info.optype = GDLM_PLOCK_OP_GET;
- op->info.pid = fl->fl_pid;
- op->info.ex = (fl->fl_type == F_WRLCK);
- op->info.fsid = ls->id;
- op->info.number = name->ln_number;
- op->info.start = fl->fl_start;
- op->info.end = fl->fl_end;
- if (fl->fl_lmops && fl->fl_lmops->fl_grant)
- op->info.owner = (__u64) fl->fl_pid;
- else
- op->info.owner = (__u64)(long) fl->fl_owner;
-
- send_op(op);
- wait_event(recv_wq, (op->done != 0));
-
- spin_lock(&ops_lock);
- if (!list_empty(&op->list)) {
- printk(KERN_INFO "plock_get op on list
");
- list_del(&op->list);
- }
- spin_unlock(&ops_lock);
-
- /* info.rv from userspace is 1 for conflict, 0 for no-conflict,
- -ENOENT if there are no locks on the file */
-
- rv = op->info.rv;
-
- fl->fl_type = F_UNLCK;
- if (rv == -ENOENT)
- rv = 0;
- else if (rv > 0) {
- fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
- fl->fl_pid = op->info.pid;
- fl->fl_start = op->info.start;
- fl->fl_end = op->info.end;
- rv = 0;
- }
-
- kfree(op);
- return rv;
-}
-
-/* a read copies out one plock request from the send list */
-static ssize_t dev_read(struct file *file, char __user *u, size_t count,
- loff_t *ppos)
-{
- struct gdlm_plock_info info;
- struct plock_op *op = NULL;
-
- if (count < sizeof(info))
- return -EINVAL;
-
- spin_lock(&ops_lock);
- if (!list_empty(&send_list)) {
- op = list_entry(send_list.next, struct plock_op, list);
- list_move(&op->list, &recv_list);
- memcpy(&info, &op->info, sizeof(info));
- }
- spin_unlock(&ops_lock);
-
- if (!op)
- return -EAGAIN;
-
- if (copy_to_user(u, &info, sizeof(info)))
- return -EFAULT;
- return sizeof(info);
-}
-
-/* a write copies in one plock result that should match a plock_op
- on the recv list */
-static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
- loff_t *ppos)
-{
- struct gdlm_plock_info info;
- struct plock_op *op;
- int found = 0;
-
- if (count != sizeof(info))
- return -EINVAL;
-
- if (copy_from_user(&info, u, sizeof(info)))
- return -EFAULT;
-
- if (check_version(&info))
- return -EINVAL;
-
- spin_lock(&ops_lock);
- list_for_each_entry(op, &recv_list, list) {
- if (op->info.fsid == info.fsid && op->info.number == info.number &&
- op->info.owner == info.owner) {
- list_del_init(&op->list);
- found = 1;
- op->done = 1;
- memcpy(&op->info, &info, sizeof(info));
- break;
- }
- }
- spin_unlock(&ops_lock);
-
- if (found) {
- struct plock_xop *xop;
- xop = (struct plock_xop *)op;
- if (xop->callback)
- count = gdlm_plock_callback(op);
- else
- wake_up(&recv_wq);
- } else
- printk(KERN_INFO "gdlm dev_write no op %x %llx
", info.fsid,
- (unsigned long long)info.number);
- return count;
-}
-
-static unsigned int dev_poll(struct file *file, poll_table *wait)
-{
- unsigned int mask = 0;
-
- poll_wait(file, &send_wq, wait);
-
- spin_lock(&ops_lock);
- if (!list_empty(&send_list))
- mask = POLLIN | POLLRDNORM;
- spin_unlock(&ops_lock);
-
- return mask;
-}
-
-static const struct file_operations dev_fops = {
- .read = dev_read,
- .write = dev_write,
- .poll = dev_poll,
- .owner = THIS_MODULE
-};
-
-static struct miscdevice plock_dev_misc = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = GDLM_PLOCK_MISC_NAME,
- .fops = &dev_fops
-};
-
-int gdlm_plock_init(void)
-{
- int rv;
-
- spin_lock_init(&ops_lock);
- INIT_LIST_HEAD(&send_list);
- INIT_LIST_HEAD(&recv_list);
- init_waitqueue_head(&send_wq);
- init_waitqueue_head(&recv_wq);
-
- rv = misc_register(&plock_dev_misc);
- if (rv)
- printk(KERN_INFO "gdlm_plock_init: misc_register failed %d",
- rv);
- return rv;
-}
-
-void gdlm_plock_exit(void)
-{
- if (misc_deregister(&plock_dev_misc) < 0)
- printk(KERN_INFO "gdlm_plock_exit: misc_deregister failed");
-}
-
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 9cdd12a..7fd04ba 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -99,7 +99,7 @@ header-y += ixjuser.h
header-y += jffs2.h
header-y += keyctl.h
header-y += limits.h
-header-y += lock_dlm_plock.h
+header-y += dlm_plock.h
header-y += magic.h
header-y += major.h
header-y += matroxfb.h
diff --git a/include/linux/dlm_plock.h b/include/linux/dlm_plock.h
new file mode 100644
index 0000000..18d5fdb
--- /dev/null
+++ b/include/linux/dlm_plock.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2008 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.
+ */
+
+#ifndef __DLM_PLOCK_DOT_H__
+#define __DLM_PLOCK_DOT_H__
+
+#define DLM_PLOCK_MISC_NAME "dlm_plock"
+
+#define DLM_PLOCK_VERSION_MAJOR 1
+#define DLM_PLOCK_VERSION_MINOR 1
+#define DLM_PLOCK_VERSION_PATCH 0
+
+enum {
+ DLM_PLOCK_OP_LOCK = 1,
+ DLM_PLOCK_OP_UNLOCK,
+ DLM_PLOCK_OP_GET,
+};
+
+struct dlm_plock_info {
+ __u32 version[3];
+ __u8 optype;
+ __u8 ex;
+ __u8 wait;
+ __u8 pad;
+ __u32 pid;
+ __s32 nodeid;
+ __s32 rv;
+ __u32 fsid;
+ __u64 number;
+ __u64 start;
+ __u64 end;
+ __u64 owner;
+};
+
+#ifdef __KERNEL__
+int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
+ int cmd, struct file_lock *fl);
+int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
+ struct file_lock *fl);
+int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
+ struct file_lock *fl);
+#endif /* __KERNEL__ */
+
+#endif
+
diff --git a/include/linux/lock_dlm_plock.h b/include/linux/lock_dlm_plock.h
deleted file mode 100644
index fc34151..0000000
--- a/include/linux/lock_dlm_plock.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef __LOCK_DLM_PLOCK_DOT_H__
-#define __LOCK_DLM_PLOCK_DOT_H__
-
-#define GDLM_PLOCK_MISC_NAME "lock_dlm_plock"
-
-#define GDLM_PLOCK_VERSION_MAJOR 1
-#define GDLM_PLOCK_VERSION_MINOR 1
-#define GDLM_PLOCK_VERSION_PATCH 0
-
-enum {
- GDLM_PLOCK_OP_LOCK = 1,
- GDLM_PLOCK_OP_UNLOCK,
- GDLM_PLOCK_OP_GET,
-};
-
-struct gdlm_plock_info {
- __u32 version[3];
- __u8 optype;
- __u8 ex;
- __u8 wait;
- __u8 pad;
- __u32 pid;
- __s32 nodeid;
- __s32 rv;
- __u32 fsid;
- __u64 number;
- __u64 start;
- __u64 end;
- __u64 owner;
-};
-
-#endif
-
--
1.5.3.3
 
Old 04-15-2008, 09:16 PM
David Teigland
 
Default dlm: move plock code from gfs2

On Tue, Apr 15, 2008 at 04:02:26PM -0500, David Teigland wrote:
> Move the code that handles cluster posix locks from gfs2 into the dlm
> so that it can be used by both gfs2 and ocfs2.

Attached is a patch to gfs_controld in STABLE2 to adapt to this change.
Since the cluster STABLE2 branch is meant to run on the latest released
kernel, this won't be commited until 2.6.26 is released.

Dave
 
Old 04-16-2008, 03:53 AM
"Fabio M. Di Nitto"
 
Default dlm: move plock code from gfs2

On Tue, 15 Apr 2008, David Teigland wrote:


On Tue, Apr 15, 2008 at 04:02:26PM -0500, David Teigland wrote:

Move the code that handles cluster posix locks from gfs2 into the dlm
so that it can be used by both gfs2 and ocfs2.


Attached is a patch to gfs_controld in STABLE2 to adapt to this change.
Since the cluster STABLE2 branch is meant to run on the latest released
kernel, this won't be commited until 2.6.26 is released.


Looks like the patch is empty.

Fabio

--
I'm going to make him an offer he can't refuse.
 
Old 04-16-2008, 01:35 PM
David Teigland
 
Default dlm: move plock code from gfs2

On Wed, Apr 16, 2008 at 05:53:43AM +0200, Fabio M. Di Nitto wrote:
> On Tue, 15 Apr 2008, David Teigland wrote:
>
> >On Tue, Apr 15, 2008 at 04:02:26PM -0500, David Teigland wrote:
> >>Move the code that handles cluster posix locks from gfs2 into the dlm
> >>so that it can be used by both gfs2 and ocfs2.
> >
> >Attached is a patch to gfs_controld in STABLE2 to adapt to this change.
> >Since the cluster STABLE2 branch is meant to run on the latest released
> >kernel, this won't be commited until 2.6.26 is released.
>
> Looks like the patch is empty.

thanks, second attempt
 
Old 04-16-2008, 01:42 PM
David Teigland
 
Default dlm: move plock code from gfs2

On Wed, Apr 16, 2008 at 08:35:57AM -0500, David Teigland wrote:
> On Wed, Apr 16, 2008 at 05:53:43AM +0200, Fabio M. Di Nitto wrote:
> > On Tue, 15 Apr 2008, David Teigland wrote:
> >
> > >On Tue, Apr 15, 2008 at 04:02:26PM -0500, David Teigland wrote:
> > >>Move the code that handles cluster posix locks from gfs2 into the dlm
> > >>so that it can be used by both gfs2 and ocfs2.
> > >
> > >Attached is a patch to gfs_controld in STABLE2 to adapt to this change.
> > >Since the cluster STABLE2 branch is meant to run on the latest released
> > >kernel, this won't be commited until 2.6.26 is released.
> >
> > Looks like the patch is empty.
>
> thanks, second attempt

That attachment is empty too, baffling, here it is in the body,
 
Old 04-16-2008, 01:44 PM
"Fabio M. Di Nitto"
 
Default dlm: move plock code from gfs2

On Wed, 16 Apr 2008, David Teigland wrote:


On Wed, Apr 16, 2008 at 05:53:43AM +0200, Fabio M. Di Nitto wrote:

On Tue, 15 Apr 2008, David Teigland wrote:


On Tue, Apr 15, 2008 at 04:02:26PM -0500, David Teigland wrote:

Move the code that handles cluster posix locks from gfs2 into the dlm
so that it can be used by both gfs2 and ocfs2.


Attached is a patch to gfs_controld in STABLE2 to adapt to this change.
Since the cluster STABLE2 branch is meant to run on the latest released
kernel, this won't be commited until 2.6.26 is released.


Looks like the patch is empty.


thanks, second attempt




Looks like a problem with the mailing list. The copy in CC to me had the
patch. The one to the mailing list not.


Am I the only one?

Fabio

--
I'm going to make him an offer he can't refuse.
 
Old 04-16-2008, 01:54 PM
David Teigland
 
Default dlm: move plock code from gfs2

On Wed, Apr 16, 2008 at 08:42:11AM -0500, David Teigland wrote:
> On Wed, Apr 16, 2008 at 08:35:57AM -0500, David Teigland wrote:
> > On Wed, Apr 16, 2008 at 05:53:43AM +0200, Fabio M. Di Nitto wrote:
> > > On Tue, 15 Apr 2008, David Teigland wrote:
> > >
> > > >On Tue, Apr 15, 2008 at 04:02:26PM -0500, David Teigland wrote:
> > > >>Move the code that handles cluster posix locks from gfs2 into the dlm
> > > >>so that it can be used by both gfs2 and ocfs2.
> > > >
> > > >Attached is a patch to gfs_controld in STABLE2 to adapt to this change.
> > > >Since the cluster STABLE2 branch is meant to run on the latest released
> > > >kernel, this won't be commited until 2.6.26 is released.
> > >
> > > Looks like the patch is empty.
> >
> > thanks, second attempt
>
> That attachment is empty too, baffling, here it is in the body,

Looks like the patch headers confused the mailing list. Took them off
this time...


In kernels before 2.6.26, cluster posix lock ops are passed to user
space through the gfs-specific lock_dlm module. In 2.6.26, the same
ops are passed to user space through the dlm module. Update gfs_controld
to read the plock ops from either module, depending on the kernel.

Signed-off-by: David Teigland <teigland@redhat.com>
---
group/gfs_controld/lock_dlm.h | 1 +
group/gfs_controld/plock.c | 256 ++++++++++++++++++++++++++++++++---------
2 files changed, 201 insertions(+), 56 deletions(-)

diff --git a/group/gfs_controld/lock_dlm.h b/group/gfs_controld/lock_dlm.h
index 7b514df..746d0c7 100644
--- a/group/gfs_controld/lock_dlm.h
+++ b/group/gfs_controld/lock_dlm.h
@@ -121,6 +121,7 @@ struct mountpoint {
struct mountgroup {
struct list_head list;
uint32_t id;
+ uint32_t associated_ls_id;
struct list_head members;
struct list_head members_gone;
int memb_count;
diff --git a/group/gfs_controld/plock.c b/group/gfs_controld/plock.c
index 42890df..0876ae5 100644
--- a/group/gfs_controld/plock.c
+++ b/group/gfs_controld/plock.c
@@ -32,9 +32,10 @@
#include <netdb.h>
#include <limits.h>
#include <unistd.h>
+#include <dirent.h>
#include <openais/saAis.h>
#include <openais/saCkpt.h>
-#include <linux/lock_dlm_plock.h>
+#include <linux/dlm_plock.h>

#include "lock_dlm.h"

@@ -42,8 +43,9 @@
#define PROC_DEVICES "/proc/devices"
#define MISC_NAME "misc"
#define CONTROL_DIR "/dev/misc"
-#define CONTROL_NAME "lock_dlm_plock"
+#define CONTROL_NAME "dlm_plock"

+extern struct list_head mounts;
extern int our_nodeid;
extern int message_flow_control_on;

@@ -69,6 +71,7 @@ static SaCkptCallbacksT callbacks = { 0, 0 };
static SaVersionT version = { 'B', 1, 1 };
static char section_buf[1024 * 1024];
static uint32_t section_len;
+static int need_fsid_translation = 0;

struct pack_plock {
uint64_t start;
@@ -112,13 +115,13 @@ struct posix_lock {
struct lock_waiter {
struct list_head list;
uint32_t flags;
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
};


static void send_own(struct mountgroup *mg, struct resource *r, int owner);
static void save_pending_plock(struct mountgroup *mg, struct resource *r,
- struct gdlm_plock_info *in);
+ struct dlm_plock_info *in);


static int got_unown(struct resource *r)
@@ -126,7 +129,7 @@ static int got_unown(struct resource *r)
return !!(r->flags & R_GOT_UNOWN);
}

-static void info_bswap_out(struct gdlm_plock_info *i)
+static void info_bswap_out(struct dlm_plock_info *i)
{
i->version[0] = cpu_to_le32(i->version[0]);
i->version[1] = cpu_to_le32(i->version[1]);
@@ -141,7 +144,7 @@ static void info_bswap_out(struct gdlm_plock_info *i)
i->owner = cpu_to_le64(i->owner);
}

-static void info_bswap_in(struct gdlm_plock_info *i)
+static void info_bswap_in(struct dlm_plock_info *i)
{
i->version[0] = le32_to_cpu(i->version[0]);
i->version[1] = le32_to_cpu(i->version[1]);
@@ -159,11 +162,11 @@ static void info_bswap_in(struct gdlm_plock_info *i)
static char *op_str(int optype)
{
switch (optype) {
- case GDLM_PLOCK_OP_LOCK:
+ case DLM_PLOCK_OP_LOCK:
return "LK";
- case GDLM_PLOCK_OP_UNLOCK:
+ case DLM_PLOCK_OP_UNLOCK:
return "UN";
- case GDLM_PLOCK_OP_GET:
+ case DLM_PLOCK_OP_GET:
return "GET";
default:
return "??";
@@ -172,7 +175,7 @@ static char *op_str(int optype)

static char *ex_str(int optype, int ex)
{
- if (optype == GDLM_PLOCK_OP_UNLOCK || optype == GDLM_PLOCK_OP_GET)
+ if (optype == DLM_PLOCK_OP_UNLOCK || optype == DLM_PLOCK_OP_GET)
return "-";
if (ex)
return "WR";
@@ -207,10 +210,11 @@ static int get_proc_number(const char *file, const char *name, uint32_t *number)
return 0;
}

-static int control_device_number(uint32_t *major, uint32_t *minor)
+static int control_device_number(const char *plock_misc_name,
+ uint32_t *major, uint32_t *minor)
{
if (!get_proc_number(PROC_DEVICES, MISC_NAME, major) ||
- !get_proc_number(PROC_MISC, GDLM_PLOCK_MISC_NAME, minor)) {
+ !get_proc_number(PROC_MISC, plock_misc_name, minor)) {
*major = 0;
return 0;
}
@@ -277,7 +281,7 @@ static int create_control(const char *control, uint32_t major, uint32_t minor)
return 1;
}

-static int open_control(void)
+static int open_control(const char *control_name, const char *plock_misc_name)
{
char control[PATH_MAX];
uint32_t major = 0, minor = 0;
@@ -285,22 +289,20 @@ static int open_control(void)
if (control_fd != -1)
return 0;

- snprintf(control, sizeof(control), "%s/%s", CONTROL_DIR, CONTROL_NAME);
+ snprintf(control, sizeof(control), "%s/%s", CONTROL_DIR, control_name);

- if (!control_device_number(&major, &minor)) {
- log_error("Is dlm missing from kernel?");
+ if (!control_device_number(plock_misc_name, &major, &minor))
return -1;
- }

if (!control_exists(control, major, minor) &&
!create_control(control, major, minor)) {
- log_error("Failure to communicate with kernel lock_dlm");
+ log_error("Failure to create device file %s", control);
return -1;
}

control_fd = open(control, O_RDWR);
if (control_fd < 0) {
- log_error("Failure to communicate with kernel lock_dlm: %s",
+ log_error("Failure to open device %s: %s", control,
strerror(errno));
return -1;
}
@@ -308,6 +310,16 @@ static int open_control(void)
return 0;
}

+/*
+ * In kernels before 2.6.26, plocks came from gfs2's lock_dlm module.
+ * Reading plocks from there as well should allow us to use cluster3
+ * on old (RHEL5) kernels. In this case, the fsid we read in plock_info
+ * structs is the mountgroup id, which we need to translate to the ls id.
+ */
+
+#define OLD_CONTROL_NAME "lock_dlm_plock"
+#define OLD_PLOCK_MISC_NAME "lock_dlm_plock"
+
int setup_plocks(void)
{
SaAisErrorT err;
@@ -330,14 +342,29 @@ int setup_plocks(void)
log_error("ckpt init error %d - plocks unavailable", err);

control:
- rv = open_control();
- if (rv)
- return rv;
+ need_fsid_translation = 1;
+
+ rv = open_control(CONTROL_NAME, DLM_PLOCK_MISC_NAME);
+ if (rv) {
+ log_debug("setup_plocks trying old lock_dlm interface");
+ rv = open_control(OLD_CONTROL_NAME, OLD_PLOCK_MISC_NAME);
+ if (rv) {
+ log_error("Is dlm missing from kernel? No control device.");
+ return rv;
+ }
+
+ /* the fsid from the kernel is the mountgroup id in old
+ kernels, which we can use to look up the mg directly
+ without translation */
+
+ need_fsid_translation = 0;
+ }

log_debug("plocks %d", control_fd);
+ log_debug("plock need_fsid_translation %d", need_fsid_translation);
log_debug("plock cpg message size: %u bytes",
(unsigned int) (sizeof(struct gdlm_header) +
- sizeof(struct gdlm_plock_info)));
+ sizeof(struct dlm_plock_info)));

return control_fd;
}
@@ -529,7 +556,7 @@ static int shrink_range(struct posix_lock *po, uint64_t start, uint64_t end)
return shrink_range2(&po->start, &po->end, start, end);
}

-static int is_conflict(struct resource *r, struct gdlm_plock_info *in, int get)
+static int is_conflict(struct resource *r, struct dlm_plock_info *in, int get)
{
struct posix_lock *po;

@@ -578,7 +605,7 @@ static int add_lock(struct resource *r, uint32_t nodeid, uint64_t owner,
2. convert RE to RN range and mode */

static int lock_case1(struct posix_lock *po, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)
{
uint64_t start2, end2;
int rv;
@@ -605,7 +632,7 @@ static int lock_case1(struct posix_lock *po, struct resource *r,
3. convert RE to RN range and mode */

static int lock_case2(struct posix_lock *po, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)

{
int rv;
@@ -628,7 +655,7 @@ static int lock_case2(struct posix_lock *po, struct resource *r,
}

static int lock_internal(struct mountgroup *mg, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)
{
struct posix_lock *po, *safe;
int rv = 0;
@@ -691,7 +718,7 @@ static int lock_internal(struct mountgroup *mg, struct resource *r,
}

static int unlock_internal(struct mountgroup *mg, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)
{
struct posix_lock *po, *safe;
int rv = 0;
@@ -755,7 +782,7 @@ static int unlock_internal(struct mountgroup *mg, struct resource *r,
}

static int add_waiter(struct mountgroup *mg, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)

{
struct lock_waiter *w;
@@ -763,26 +790,29 @@ static int add_waiter(struct mountgroup *mg, struct resource *r,
w = malloc(sizeof(struct lock_waiter));
if (!w)
return -ENOMEM;
- memcpy(&w->info, in, sizeof(struct gdlm_plock_info));
+ memcpy(&w->info, in, sizeof(struct dlm_plock_info));
list_add_tail(&w->list, &r->waiters);
return 0;
}

-static void write_result(struct mountgroup *mg, struct gdlm_plock_info *in,
+static void write_result(struct mountgroup *mg, struct dlm_plock_info *in,
int rv)
{
int err;

+ if (need_fsid_translation)
+ in->fsid = mg->associated_ls_id;
+
in->rv = rv;
- err = write(control_fd, in, sizeof(struct gdlm_plock_info));
- if (err != sizeof(struct gdlm_plock_info))
+ err = write(control_fd, in, sizeof(struct dlm_plock_info));
+ if (err != sizeof(struct dlm_plock_info))
log_error("plock result write err %d errno %d", err, errno);
}

static void do_waiters(struct mountgroup *mg, struct resource *r)
{
struct lock_waiter *w, *safe;
- struct gdlm_plock_info *in;
+ struct dlm_plock_info *in;
int rv;

list_for_each_entry_safe(w, safe, &r->waiters, list) {
@@ -808,7 +838,7 @@ static void do_waiters(struct mountgroup *mg, struct resource *r)
}
}

-static void do_lock(struct mountgroup *mg, struct gdlm_plock_info *in,
+static void do_lock(struct mountgroup *mg, struct dlm_plock_info *in,
struct resource *r)
{
int rv;
@@ -833,7 +863,7 @@ static void do_lock(struct mountgroup *mg, struct gdlm_plock_info *in,
put_resource(r);
}

-static void do_unlock(struct mountgroup *mg, struct gdlm_plock_info *in,
+static void do_unlock(struct mountgroup *mg, struct dlm_plock_info *in,
struct resource *r)
{
int rv;
@@ -849,7 +879,7 @@ static void do_unlock(struct mountgroup *mg, struct gdlm_plock_info *in,

/* we don't even get to this function if the getlk isn't from us */

-static void do_get(struct mountgroup *mg, struct gdlm_plock_info *in,
+static void do_get(struct mountgroup *mg, struct dlm_plock_info *in,
struct resource *r)
{
int rv;
@@ -862,19 +892,19 @@ static void do_get(struct mountgroup *mg, struct gdlm_plock_info *in,
write_result(mg, in, rv);
}

-static void __receive_plock(struct mountgroup *mg, struct gdlm_plock_info *in,
+static void __receive_plock(struct mountgroup *mg, struct dlm_plock_info *in,
int from, struct resource *r)
{
switch (in->optype) {
- case GDLM_PLOCK_OP_LOCK:
+ case DLM_PLOCK_OP_LOCK:
mg->last_plock_time = time(NULL);
do_lock(mg, in, r);
break;
- case GDLM_PLOCK_OP_UNLOCK:
+ case DLM_PLOCK_OP_UNLOCK:
mg->last_plock_time = time(NULL);
do_unlock(mg, in, r);
break;
- case GDLM_PLOCK_OP_GET:
+ case DLM_PLOCK_OP_GET:
do_get(mg, in, r);
break;
default:
@@ -896,7 +926,7 @@ static void __receive_plock(struct mountgroup *mg, struct gdlm_plock_info *in,

static void _receive_plock(struct mountgroup *mg, char *buf, int len, int from)
{
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
struct gdlm_header *hd = (struct gdlm_header *) buf;
struct resource *r = NULL;
struct timeval now;
@@ -923,7 +953,7 @@ static void _receive_plock(struct mountgroup *mg, char *buf, int len, int from)
plock_recv_time = now;
}

- if (info.optype == GDLM_PLOCK_OP_GET && from != our_nodeid)
+ if (info.optype == DLM_PLOCK_OP_GET && from != our_nodeid)
return;

if (from != hd->nodeid || from != info.nodeid) {
@@ -1029,14 +1059,14 @@ void receive_plock(struct mountgroup *mg, char *buf, int len, int from)
_receive_plock(mg, buf, len, from);
}

-static int send_struct_info(struct mountgroup *mg, struct gdlm_plock_info *in,
+static int send_struct_info(struct mountgroup *mg, struct dlm_plock_info *in,
int msg_type)
{
char *buf;
int rv, len;
struct gdlm_header *hd;

- len = sizeof(struct gdlm_header) + sizeof(struct gdlm_plock_info);
+ len = sizeof(struct gdlm_header) + sizeof(struct dlm_plock_info);
buf = malloc(len);
if (!buf) {
rv = -ENOMEM;
@@ -1063,14 +1093,14 @@ static int send_struct_info(struct mountgroup *mg, struct gdlm_plock_info *in,
}

static void send_plock(struct mountgroup *mg, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)
{
send_struct_info(mg, in, MSG_PLOCK);
}

static void send_own(struct mountgroup *mg, struct resource *r, int owner)
{
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;

/* if we've already sent an own message for this resource,
(pending list is not empty), then we shouldn't send another */
@@ -1090,7 +1120,7 @@ static void send_own(struct mountgroup *mg, struct resource *r, int owner)

static void send_syncs(struct mountgroup *mg, struct resource *r)
{
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
struct posix_lock *po;
struct lock_waiter *w;
int rv;
@@ -1127,7 +1157,7 @@ static void send_syncs(struct mountgroup *mg, struct resource *r)

static void send_drop(struct mountgroup *mg, struct resource *r)
{
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;

memset(&info, 0, sizeof(info));
info.number = r->number;
@@ -1139,7 +1169,7 @@ static void send_drop(struct mountgroup *mg, struct resource *r)
so the op is saved on the pending list until the r owner is established */

static void save_pending_plock(struct mountgroup *mg, struct resource *r,
- struct gdlm_plock_info *in)
+ struct dlm_plock_info *in)
{
struct lock_waiter *w;

@@ -1148,7 +1178,7 @@ static void save_pending_plock(struct mountgroup *mg, struct resource *r,
log_error("save_pending_plock no mem");
return;
}
- memcpy(&w->info, in, sizeof(struct gdlm_plock_info));
+ memcpy(&w->info, in, sizeof(struct dlm_plock_info));
list_add_tail(&w->list, &r->pending);
}

@@ -1183,7 +1213,7 @@ static void send_pending_plocks(struct mountgroup *mg, struct resource *r)
static void _receive_own(struct mountgroup *mg, char *buf, int len, int from)
{
struct gdlm_header *hd = (struct gdlm_header *) buf;
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
struct resource *r;
int should_not_happen = 0;
int rv;
@@ -1310,7 +1340,7 @@ void receive_own(struct mountgroup *mg, char *buf, int len, int from)
_receive_own(mg, buf, len, from);
}

-static void clear_syncing_flag(struct resource *r, struct gdlm_plock_info *in)
+static void clear_syncing_flag(struct resource *r, struct dlm_plock_info *in)
{
struct posix_lock *po;
struct lock_waiter *w;
@@ -1349,7 +1379,7 @@ static void clear_syncing_flag(struct resource *r, struct gdlm_plock_info *in)

static void _receive_sync(struct mountgroup *mg, char *buf, int len, int from)
{
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
struct gdlm_header *hd = (struct gdlm_header *) buf;
struct resource *r;
int rv;
@@ -1395,7 +1425,7 @@ void receive_sync(struct mountgroup *mg, char *buf, int len, int from)

static void _receive_drop(struct mountgroup *mg, char *buf, int len, int from)
{
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
struct resource *r;
int rv;

@@ -1494,11 +1524,122 @@ static int drop_resources(struct mountgroup *mg)
return 0;
}

+/* iterate through directory names looking for matching id:
+ /sys/kernel/dlm/<name>/id */
+
+#define DLM_SYSFS_DIR "/sys/kernel/dlm"
+
+static char ls_name[256];
+
+static int get_lockspace_name(uint32_t ls_id)
+{
+ char path[PATH_MAX];
+ DIR *d;
+ FILE *file;
+ struct dirent *de;
+ uint32_t id;
+ int rv, error;
+
+ d = opendir(DLM_SYSFS_DIR);
+ if (!d) {
+ log_debug("%s: opendir failed: %d", path, errno);
+ return -1;
+ }
+
+ rv = -1;
+
+ while ((de = readdir(d))) {
+ if (de->d_name[0] == '.')
+ continue;
+
+ id = 0;
+ memset(path, 0, PATH_MAX);
+ snprintf(path, PATH_MAX, "%s/%s/id", DLM_SYSFS_DIR, de->d_name);
+
+ file = fopen(path, "r");
+ if (!file) {
+ log_error("can't open %s %d", path, errno);
+ continue;
+ }
+
+ error = fscanf(file, "%u", &id);
+ fclose(file);
+
+ if (error != 1) {
+ log_error("bad read %s %d", path, errno);
+ continue;
+ }
+ if (id != ls_id) {
+ log_debug("get_lockspace_name skip %x %s",
+ id, de->d_name);
+ continue;
+ }
+
+ log_debug("get_lockspace_name found %x %s", id, de->d_name);
+ strncpy(ls_name, de->d_name, 256);
+ rv = 0;
+ break;
+ }
+
+ closedir(d);
+ return rv;
+}
+
+/* find the locskapce with "ls_id" in sysfs, get it's name, then look for
+ the mg with with the same name in mounts list, return it's id */
+
+static void set_associated_id(uint32_t ls_id)
+{
+ struct mountgroup *mg;
+ int rv;
+
+ log_debug("set_associated_id ls_id %x %d", ls_id, ls_id);
+
+ memset(&ls_name, 0, sizeof(ls_name));
+
+ rv = get_lockspace_name(ls_id);
+ if (rv) {
+ log_error("no lockspace found with id %x", ls_id);
+ return;
+ }
+
+ mg = find_mg(ls_name);
+ if (!mg) {
+ log_error("no mountgroup found with name %s for ls_id %x",
+ ls_name, ls_id);
+ return;
+ }
+
+ log_debug("set_associated_id ls %x is mg %x", ls_id, mg->id);
+
+ mg->associated_ls_id = ls_id;
+}
+
+static uint32_t ls_to_mg_id(uint32_t fsid)
+{
+ struct mountgroup *mg;
+ int do_set = 1;
+
+ retry:
+ list_for_each_entry(mg, &mounts, list) {
+ if (mg->associated_ls_id == fsid)
+ return mg->id;
+ }
+
+ if (do_set) {
+ do_set = 0;
+ set_associated_id(fsid);
+ goto retry;
+ }
+
+ return fsid;
+}
+
int process_plocks(void)
{
struct mountgroup *mg;
struct resource *r;
- struct gdlm_plock_info info;
+ struct dlm_plock_info info;
struct timeval now;
uint64_t usec;
int rv;
@@ -1542,6 +1683,9 @@ int process_plocks(void)
goto fail;
}

+ if (need_fsid_translation)
+ info.fsid = ls_to_mg_id(info.fsid);
+
mg = find_mg_id(info.fsid);
if (!mg) {
log_debug("process_plocks: no mg id %x", info.fsid);
--
1.5.3.3
 

Thread Tools




All times are GMT. The time now is 07:35 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org