diff options
author | David Teigland <teigland@redhat.com> | 2008-03-14 21:09:15 +0100 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2008-04-21 18:22:28 +0200 |
commit | 2402211a8389282fd2942fad4511f02c0eeeffc5 (patch) | |
tree | 853e5818a29816e642689d7e793a845d2519711b /fs | |
parent | dlm: recover nodes that are removed and re-added (diff) | |
download | linux-2402211a8389282fd2942fad4511f02c0eeeffc5.tar.xz linux-2402211a8389282fd2942fad4511f02c0eeeffc5.zip |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dlm/Makefile | 1 | ||||
-rw-r--r-- | fs/dlm/dlm_internal.h | 2 | ||||
-rw-r--r-- | fs/dlm/main.c | 7 | ||||
-rw-r--r-- | fs/dlm/plock.c (renamed from fs/gfs2/locking/dlm/plock.c) | 169 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/Makefile | 2 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/lock_dlm.h | 12 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/main.c | 8 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/mount.c | 21 |
8 files changed, 134 insertions, 88 deletions
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile index d248e60951ba..ca1c9124c8ce 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 c70c8e58358f..caa1581e158f 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 58487fb95a4c..b80e0aa3cfa5 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\n", __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/gfs2/locking/dlm/plock.c b/fs/dlm/plock.c index 2ebd374b3143..d6d6e370f89c 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/dlm/plock.c @@ -1,17 +1,19 @@ /* - * Copyright (C) 2005 Red Hat, Inc. All rights reserved. + * 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/lock_dlm_plock.h> #include <linux/poll.h> +#include <linux/dlm.h> +#include <linux/dlm_plock.h> -#include "lock_dlm.h" - +#include "dlm_internal.h" +#include "lockspace.h" static spinlock_t ops_lock; static struct list_head send_list; @@ -22,7 +24,7 @@ static wait_queue_head_t recv_wq; struct plock_op { struct list_head list; int done; - struct gdlm_plock_info info; + struct dlm_plock_info info; }; struct plock_xop { @@ -34,22 +36,22 @@ struct plock_xop { }; -static inline void set_version(struct gdlm_plock_info *info) +static inline void set_version(struct dlm_plock_info *info) { - info->version[0] = GDLM_PLOCK_VERSION_MAJOR; - info->version[1] = GDLM_PLOCK_VERSION_MINOR; - info->version[2] = GDLM_PLOCK_VERSION_PATCH; + 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 gdlm_plock_info *info) +static int check_version(struct dlm_plock_info *info) { - if ((GDLM_PLOCK_VERSION_MAJOR != info->version[0]) || - (GDLM_PLOCK_VERSION_MINOR < info->version[1])) { - log_error("plock device version mismatch: " + 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)", - GDLM_PLOCK_VERSION_MAJOR, - GDLM_PLOCK_VERSION_MINOR, - GDLM_PLOCK_VERSION_PATCH, + DLM_PLOCK_VERSION_MAJOR, + DLM_PLOCK_VERSION_MINOR, + DLM_PLOCK_VERSION_PATCH, info->version[0], info->version[1], info->version[2]); @@ -68,25 +70,31 @@ static void send_op(struct plock_op *op) wake_up(&send_wq); } -int gdlm_plock(void *lockspace, struct lm_lockname *name, - struct file *file, int cmd, struct file_lock *fl) +int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + int cmd, struct file_lock *fl) { - struct gdlm_ls *ls = lockspace; + 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) - return -ENOMEM; + if (!xop) { + rv = -ENOMEM; + goto out; + } op = &xop->xop; - op->info.optype = GDLM_PLOCK_OP_LOCK; + 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->id; - op->info.number = name->ln_number; + 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) { @@ -107,12 +115,15 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name, if (xop->callback == NULL) wait_event(recv_wq, (op->done != 0)); - else - return -EINPROGRESS; + else { + rv = -EINPROGRESS; + goto out; + } spin_lock(&ops_lock); if (!list_empty(&op->list)) { - printk(KERN_INFO "plock op on list\n"); + log_error(ls, "dlm_posix_lock: op on list %llx", + (unsigned long long)number); list_del(&op->list); } spin_unlock(&ops_lock); @@ -121,17 +132,19 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name, 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); + 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 gdlm_plock_callback(struct plock_op *op) +static int dlm_plock_callback(struct plock_op *op) { struct file *file; struct file_lock *fl; @@ -142,7 +155,8 @@ static int gdlm_plock_callback(struct plock_op *op) spin_lock(&ops_lock); if (!list_empty(&op->list)) { - printk(KERN_INFO "plock op on list\n"); + log_print("dlm_plock_callback: op on list %llx", + (unsigned long long)op->info.number); list_del(&op->list); } spin_unlock(&ops_lock); @@ -165,19 +179,19 @@ static int gdlm_plock_callback(struct plock_op *op) * 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 + * 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_error("gdlm_plock: vfs lock error file %p fl %p", - file, fl); + 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: */ - printk("gfs2 lock granted after lock request failed;" - " dangling lock!\n"); + log_print("dlm_plock_callback: lock granted after lock request " + "failed; dangling lock!\n"); goto out; } @@ -186,25 +200,31 @@ out: return rv; } -int gdlm_punlock(void *lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl) +int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + struct file_lock *fl) { - struct gdlm_ls *ls = lockspace; + 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) - return -ENOMEM; + if (!op) { + rv = -ENOMEM; + goto out; + } 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); + log_error(ls, "dlm_posix_unlock: vfs unlock error %llx", + (unsigned long long)number); - op->info.optype = GDLM_PLOCK_OP_UNLOCK; + op->info.optype = DLM_PLOCK_OP_UNLOCK; op->info.pid = fl->fl_pid; - op->info.fsid = ls->id; - op->info.number = name->ln_number; + 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) @@ -217,7 +237,8 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name, spin_lock(&ops_lock); if (!list_empty(&op->list)) { - printk(KERN_INFO "punlock op on list\n"); + log_error(ls, "dlm_posix_unlock: op on list %llx", + (unsigned long long)number); list_del(&op->list); } spin_unlock(&ops_lock); @@ -228,25 +249,34 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name, rv = 0; kfree(op); +out: + dlm_put_lockspace(ls); return rv; } +EXPORT_SYMBOL_GPL(dlm_posix_unlock); -int gdlm_plock_get(void *lockspace, struct lm_lockname *name, - struct file *file, struct file_lock *fl) +int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, + struct file_lock *fl) { - struct gdlm_ls *ls = lockspace; + 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) - return -ENOMEM; + if (!op) { + rv = -ENOMEM; + goto out; + } - op->info.optype = GDLM_PLOCK_OP_GET; + 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->id; - op->info.number = name->ln_number; + 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) @@ -259,7 +289,8 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, spin_lock(&ops_lock); if (!list_empty(&op->list)) { - printk(KERN_INFO "plock_get op on list\n"); + log_error(ls, "dlm_posix_get: op on list %llx", + (unsigned long long)number); list_del(&op->list); } spin_unlock(&ops_lock); @@ -281,14 +312,17 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, } 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 gdlm_plock_info info; + struct dlm_plock_info info; struct plock_op *op = NULL; if (count < sizeof(info)) @@ -315,7 +349,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, static ssize_t dev_write(struct file *file, const char __user *u, size_t count, loff_t *ppos) { - struct gdlm_plock_info info; + struct dlm_plock_info info; struct plock_op *op; int found = 0; @@ -345,12 +379,12 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, struct plock_xop *xop; xop = (struct plock_xop *)op; if (xop->callback) - count = gdlm_plock_callback(op); + count = dlm_plock_callback(op); else wake_up(&recv_wq); } else - printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid, - (unsigned long long)info.number); + log_print("dev_write no op %x %llx", info.fsid, + (unsigned long long)info.number); return count; } @@ -377,11 +411,11 @@ static const struct file_operations dev_fops = { static struct miscdevice plock_dev_misc = { .minor = MISC_DYNAMIC_MINOR, - .name = GDLM_PLOCK_MISC_NAME, + .name = DLM_PLOCK_MISC_NAME, .fops = &dev_fops }; -int gdlm_plock_init(void) +int dlm_plock_init(void) { int rv; @@ -393,14 +427,13 @@ int gdlm_plock_init(void) rv = misc_register(&plock_dev_misc); if (rv) - printk(KERN_INFO "gdlm_plock_init: misc_register failed %d", - rv); + log_print("dlm_plock_init: misc_register failed %d", rv); return rv; } -void gdlm_plock_exit(void) +void dlm_plock_exit(void) { if (misc_deregister(&plock_dev_misc) < 0) - printk(KERN_INFO "gdlm_plock_exit: misc_deregister failed"); + log_print("dlm_plock_exit: misc_deregister failed"); } diff --git a/fs/gfs2/locking/dlm/Makefile b/fs/gfs2/locking/dlm/Makefile index 89b93b6b45cf..2609bb6cd013 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 58fcf8c5bf39..a243cf69c54e 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,17 +174,6 @@ 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 *); - /* mount.c */ extern const struct lm_lockops gdlm_ops; diff --git a/fs/gfs2/locking/dlm/main.c b/fs/gfs2/locking/dlm/main.c index 36a225850bd8..b9a03a7ff801 100644 --- a/fs/gfs2/locking/dlm/main.c +++ b/fs/gfs2/locking/dlm/main.c @@ -28,13 +28,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\n", __DATE__, __TIME__); return 0; @@ -42,7 +35,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 f2efff424224..470bdf650b50 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, |