From: David Teigland <teigland@redhat.com> Date: Mon, 6 Oct 2008 17:31:34 -0500 Subject: [dlm] add old plock interface Message-id: 20081006223134.GA32067@redhat.com O-Subject: [RHEL5.3 PATCH] dlm: add old plock interface Bugzilla: 462354 RH-Acked-by: Steven Whitehouse <swhiteho@redhat.com> RH-Acked-by: Christine Caulfield <ccaulfie@redhat.com> bz 462354 dlm: add old plock interface In bug 450138 we backported upstream plock changes directly to RHEL (moving the plock code from gfs2 into the dlm). This patch munges the backport patch a bit, adding back the old/original device interface expected by the old version of gfs_controld (in userspace cman package). This patch exports dlm_posix_set_fsid(), which gfs(1) would need on the whitelist. brew build including this patch https://brewweb.devel.redhat.com/taskinfo?taskID=1508305 This second version is updated per comments from Steve Whitehouse: compare file f_op instead of using private_data to point at file_operations. diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 300583a..30c068d 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -433,6 +433,7 @@ struct dlm_ls { struct list_head ls_list; /* list of lockspaces */ dlm_lockspace_t *ls_local_handle; uint32_t ls_global_id; /* global unique lockspace ID */ + uint32_t ls_fsid; uint32_t ls_exflags; int ls_lvblen; int ls_count; /* reference count */ diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 4b94784..d2a1df1 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -346,6 +346,20 @@ void dlm_put_lockspace(struct dlm_ls *ls) spin_unlock(&lslist_lock); } +void dlm_global_to_fsid(uint32_t global_id, uint32_t *fsid) +{ + struct dlm_ls *ls; + + spin_lock(&lslist_lock); + list_for_each_entry(ls, &lslist, ls_list) { + if (ls->ls_global_id == global_id) { + *fsid = ls->ls_fsid; + break; + } + } + spin_unlock(&lslist_lock); +} + static void remove_lockspace(struct dlm_ls *ls) { for (;;) { diff --git a/fs/dlm/lockspace.h b/fs/dlm/lockspace.h index 891eabb..cb75d05 100644 --- a/fs/dlm/lockspace.h +++ b/fs/dlm/lockspace.h @@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id); struct dlm_ls *dlm_find_lockspace_local(void *id); struct dlm_ls *dlm_find_lockspace_device(int minor); void dlm_put_lockspace(struct dlm_ls *ls); +void dlm_global_to_fsid(uint32_t global_id, uint32_t *fsid); #endif /* __LOCKSPACE_DOT_H__ */ diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 204f254..c31a4dc 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -321,6 +321,39 @@ out: } EXPORT_SYMBOL_GPL(dlm_posix_get); +int dlm_posix_set_fsid(dlm_lockspace_t *lockspace, u32 id) +{ + struct dlm_ls *ls; + + ls = dlm_find_lockspace_local(lockspace); + if (!ls) + return -EINVAL; + + ls->ls_fsid = id; + + dlm_put_lockspace(ls); + return 0; +} +EXPORT_SYMBOL_GPL(dlm_posix_set_fsid); + +static struct file_operations dev_fops; + +static void munge_fsid(struct file *file, struct plock_op *op) +{ + u32 id = 0; + + /* op was read through new device */ + if (file->f_op == &dev_fops) + return; + + /* op was read through old device, so we need to change the fsid + in the op into what the fs has set */ + + dlm_global_to_fsid(op->info.fsid, &id); + if (id) + op->info.fsid = id; +} + /* 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) @@ -334,6 +367,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, spin_lock(&ops_lock); if (!list_empty(&send_list)) { op = list_entry(send_list.next, struct plock_op, list); + munge_fsid(file, op); list_move(&op->list, &recv_list); memcpy(&info, &op->info, sizeof(info)); } @@ -404,6 +438,19 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) return 0; } +static struct file_operations old_dev_fops = { + .read = dev_read, + .write = dev_write, + .poll = dev_poll, + .owner = THIS_MODULE +}; + +static struct miscdevice old_plock_dev_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "lock_dlm_plock", + .fops = &old_dev_fops +}; + static struct file_operations dev_fops = { .read = dev_read, .write = dev_write, @@ -428,8 +475,17 @@ int dlm_plock_init(void) init_waitqueue_head(&recv_wq); rv = misc_register(&plock_dev_misc); - if (rv) + if (rv) { log_print("dlm_plock_init: misc_register failed %d", rv); + goto out; + } + + rv = misc_register(&old_plock_dev_misc); + if (rv) { + misc_deregister(&plock_dev_misc); + log_print("dlm_plock_init: old misc_register failed %d", rv); + } + out: return rv; } @@ -437,5 +493,7 @@ void dlm_plock_exit(void) { if (misc_deregister(&plock_dev_misc) < 0) log_print("dlm_plock_exit: misc_deregister failed"); + if (misc_deregister(&old_plock_dev_misc) < 0) + log_print("dlm_plock_exit: old misc_deregister failed"); } diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index de0b7be..84da1f1 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c @@ -155,6 +155,8 @@ static int gdlm_mount(char *table_name, char *host_data, goto out_kobj; } + dlm_posix_set_fsid(ls->dlm_lockspace, ls->id); + lockstruct->ls_jid = ls->jid; lockstruct->ls_first = ls->first; lockstruct->ls_lockspace = ls; diff --git a/include/linux/dlm_plock.h b/include/linux/dlm_plock.h index 18d5fdb..4b06215 100644 --- a/include/linux/dlm_plock.h +++ b/include/linux/dlm_plock.h @@ -44,6 +44,7 @@ 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); +int dlm_posix_set_fsid(dlm_lockspace_t *lockspace, u32 id); #endif /* __KERNEL__ */ #endif