Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 603

kernel-2.6.18-238.el5.src.rpm

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