aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2007-05-18 10:00:32 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-07-09 03:22:36 -0400
commitd7db923ea4990edb5583bf54af868ba687a1bc84 (patch)
tree3efa0db00a3a6400f43a65aef2726fa813f9dfa2 /fs
parent3ae1acf93a21512512f8a78430fcde5992dd208e (diff)
[DLM] dlm_device interface changes [3/6]
Change the user/kernel device interface used by libdlm: - Add ability for userspace to check the version of the interface. libdlm can now adapt to different versions of the kernel interface. - Increase the size of the flags passed in a lock request so all possible flags can be used from userspace. - Add an opaque "xid" value for each lock. This "transaction id" will be used later to associate locks with each other during deadlock detection. - Add a "timeout" value for each lock. This is used along with the DLM_LKF_TIMEOUT flag. Also, remove a fragment of unused code in device_read(). This patch requires updating libdlm which is backward compatible with older kernels. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/dlm/dlm_internal.h2
-rw-r--r--fs/dlm/lock.c24
-rw-r--r--fs/dlm/lock.h6
-rw-r--r--fs/dlm/user.c53
4 files changed, 62 insertions, 23 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 65a5fc076b8a..a8d6e993697c 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -151,6 +151,7 @@ struct dlm_args {
151 void *bastaddr; 151 void *bastaddr;
152 int mode; 152 int mode;
153 struct dlm_lksb *lksb; 153 struct dlm_lksb *lksb;
154 unsigned long timeout;
154}; 155};
155 156
156 157
@@ -528,6 +529,7 @@ struct dlm_user_args {
528 void __user *castaddr; 529 void __user *castaddr;
529 void __user *bastparam; 530 void __user *bastparam;
530 void __user *bastaddr; 531 void __user *bastaddr;
532 uint64_t xid;
531}; 533};
532 534
533#define DLM_PROC_FLAGS_CLOSING 1 535#define DLM_PROC_FLAGS_CLOSING 1
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index ab986dfbe6d3..ad3797a37942 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1098,6 +1098,8 @@ void dlm_scan_timeout(struct dlm_ls *ls)
1098 } 1098 }
1099 1099
1100 if (do_cancel) { 1100 if (do_cancel) {
1101 log_debug("timeout cancel %x node %d %s", lkb->lkb_id,
1102 lkb->lkb_nodeid, r->res_name);
1101 lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; 1103 lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
1102 lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; 1104 lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL;
1103 del_timeout(lkb); 1105 del_timeout(lkb);
@@ -1864,7 +1866,7 @@ static void confirm_master(struct dlm_rsb *r, int error)
1864} 1866}
1865 1867
1866static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, 1868static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
1867 int namelen, uint32_t parent_lkid, void *ast, 1869 int namelen, unsigned long timeout_cs, void *ast,
1868 void *astarg, void *bast, struct dlm_args *args) 1870 void *astarg, void *bast, struct dlm_args *args)
1869{ 1871{
1870 int rv = -EINVAL; 1872 int rv = -EINVAL;
@@ -1907,10 +1909,6 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
1907 if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr) 1909 if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr)
1908 goto out; 1910 goto out;
1909 1911
1910 /* parent/child locks not yet supported */
1911 if (parent_lkid)
1912 goto out;
1913
1914 if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid) 1912 if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid)
1915 goto out; 1913 goto out;
1916 1914
@@ -1922,6 +1920,7 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
1922 args->astaddr = ast; 1920 args->astaddr = ast;
1923 args->astparam = (long) astarg; 1921 args->astparam = (long) astarg;
1924 args->bastaddr = bast; 1922 args->bastaddr = bast;
1923 args->timeout = timeout_cs;
1925 args->mode = mode; 1924 args->mode = mode;
1926 args->lksb = lksb; 1925 args->lksb = lksb;
1927 rv = 0; 1926 rv = 0;
@@ -1976,6 +1975,7 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
1976 lkb->lkb_lksb = args->lksb; 1975 lkb->lkb_lksb = args->lksb;
1977 lkb->lkb_lvbptr = args->lksb->sb_lvbptr; 1976 lkb->lkb_lvbptr = args->lksb->sb_lvbptr;
1978 lkb->lkb_ownpid = (int) current->pid; 1977 lkb->lkb_ownpid = (int) current->pid;
1978 lkb->lkb_timeout_cs = args->timeout;
1979 rv = 0; 1979 rv = 0;
1980 out: 1980 out:
1981 return rv; 1981 return rv;
@@ -2423,7 +2423,7 @@ int dlm_lock(dlm_lockspace_t *lockspace,
2423 if (error) 2423 if (error)
2424 goto out; 2424 goto out;
2425 2425
2426 error = set_lock_args(mode, lksb, flags, namelen, parent_lkid, ast, 2426 error = set_lock_args(mode, lksb, flags, namelen, 0, ast,
2427 astarg, bast, &args); 2427 astarg, bast, &args);
2428 if (error) 2428 if (error)
2429 goto out_put; 2429 goto out_put;
@@ -4175,7 +4175,7 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
4175 4175
4176int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, 4176int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4177 int mode, uint32_t flags, void *name, unsigned int namelen, 4177 int mode, uint32_t flags, void *name, unsigned int namelen,
4178 uint32_t parent_lkid) 4178 unsigned long timeout_cs)
4179{ 4179{
4180 struct dlm_lkb *lkb; 4180 struct dlm_lkb *lkb;
4181 struct dlm_args args; 4181 struct dlm_args args;
@@ -4203,7 +4203,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4203 When DLM_IFL_USER is set, the dlm knows that this is a userspace 4203 When DLM_IFL_USER is set, the dlm knows that this is a userspace
4204 lock and that lkb_astparam is the dlm_user_args structure. */ 4204 lock and that lkb_astparam is the dlm_user_args structure. */
4205 4205
4206 error = set_lock_args(mode, &ua->lksb, flags, namelen, parent_lkid, 4206 error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
4207 DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); 4207 DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
4208 lkb->lkb_flags |= DLM_IFL_USER; 4208 lkb->lkb_flags |= DLM_IFL_USER;
4209 ua->old_mode = DLM_LOCK_IV; 4209 ua->old_mode = DLM_LOCK_IV;
@@ -4240,7 +4240,8 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4240} 4240}
4241 4241
4242int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 4242int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4243 int mode, uint32_t flags, uint32_t lkid, char *lvb_in) 4243 int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
4244 unsigned long timeout_cs)
4244{ 4245{
4245 struct dlm_lkb *lkb; 4246 struct dlm_lkb *lkb;
4246 struct dlm_args args; 4247 struct dlm_args args;
@@ -4268,6 +4269,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4268 if (lvb_in && ua->lksb.sb_lvbptr) 4269 if (lvb_in && ua->lksb.sb_lvbptr)
4269 memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); 4270 memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
4270 4271
4272 ua->xid = ua_tmp->xid;
4271 ua->castparam = ua_tmp->castparam; 4273 ua->castparam = ua_tmp->castparam;
4272 ua->castaddr = ua_tmp->castaddr; 4274 ua->castaddr = ua_tmp->castaddr;
4273 ua->bastparam = ua_tmp->bastparam; 4275 ua->bastparam = ua_tmp->bastparam;
@@ -4275,8 +4277,8 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4275 ua->user_lksb = ua_tmp->user_lksb; 4277 ua->user_lksb = ua_tmp->user_lksb;
4276 ua->old_mode = lkb->lkb_grmode; 4278 ua->old_mode = lkb->lkb_grmode;
4277 4279
4278 error = set_lock_args(mode, &ua->lksb, flags, 0, 0, DLM_FAKE_USER_AST, 4280 error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs,
4279 ua, DLM_FAKE_USER_AST, &args); 4281 DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
4280 if (error) 4282 if (error)
4281 goto out_put; 4283 goto out_put;
4282 4284
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index 6b5b71f0e9dd..99ab4635074e 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -38,9 +38,11 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc);
38int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc); 38int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc);
39 39
40int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, 40int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode,
41 uint32_t flags, void *name, unsigned int namelen, uint32_t parent_lkid); 41 uint32_t flags, void *name, unsigned int namelen,
42 unsigned long timeout_cs);
42int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 43int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
43 int mode, uint32_t flags, uint32_t lkid, char *lvb_in); 44 int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
45 unsigned long timeout_cs);
44int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 46int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
45 uint32_t flags, uint32_t lkid, char *lvb_in); 47 uint32_t flags, uint32_t lkid, char *lvb_in);
46int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 48int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index c7612da5b617..37aad3fe8949 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -33,16 +33,17 @@ static const struct file_operations device_fops;
33struct dlm_lock_params32 { 33struct dlm_lock_params32 {
34 __u8 mode; 34 __u8 mode;
35 __u8 namelen; 35 __u8 namelen;
36 __u16 flags; 36 __u16 unused;
37 __u32 flags;
37 __u32 lkid; 38 __u32 lkid;
38 __u32 parent; 39 __u32 parent;
39 40 __u64 xid;
41 __u64 timeout;
40 __u32 castparam; 42 __u32 castparam;
41 __u32 castaddr; 43 __u32 castaddr;
42 __u32 bastparam; 44 __u32 bastparam;
43 __u32 bastaddr; 45 __u32 bastaddr;
44 __u32 lksb; 46 __u32 lksb;
45
46 char lvb[DLM_USER_LVB_LEN]; 47 char lvb[DLM_USER_LVB_LEN];
47 char name[0]; 48 char name[0];
48}; 49};
@@ -68,6 +69,7 @@ struct dlm_lksb32 {
68}; 69};
69 70
70struct dlm_lock_result32 { 71struct dlm_lock_result32 {
72 __u32 version[3];
71 __u32 length; 73 __u32 length;
72 __u32 user_astaddr; 74 __u32 user_astaddr;
73 __u32 user_astparam; 75 __u32 user_astparam;
@@ -102,6 +104,8 @@ static void compat_input(struct dlm_write_request *kb,
102 kb->i.lock.flags = kb32->i.lock.flags; 104 kb->i.lock.flags = kb32->i.lock.flags;
103 kb->i.lock.lkid = kb32->i.lock.lkid; 105 kb->i.lock.lkid = kb32->i.lock.lkid;
104 kb->i.lock.parent = kb32->i.lock.parent; 106 kb->i.lock.parent = kb32->i.lock.parent;
107 kb->i.lock.xid = kb32->i.lock.xid;
108 kb->i.lock.timeout = kb32->i.lock.timeout;
105 kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam; 109 kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam;
106 kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr; 110 kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr;
107 kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam; 111 kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam;
@@ -115,6 +119,10 @@ static void compat_input(struct dlm_write_request *kb,
115static void compat_output(struct dlm_lock_result *res, 119static void compat_output(struct dlm_lock_result *res,
116 struct dlm_lock_result32 *res32) 120 struct dlm_lock_result32 *res32)
117{ 121{
122 res32->version[0] = res->version[0];
123 res32->version[1] = res->version[1];
124 res32->version[2] = res->version[2];
125
118 res32->user_astaddr = (__u32)(long)res->user_astaddr; 126 res32->user_astaddr = (__u32)(long)res->user_astaddr;
119 res32->user_astparam = (__u32)(long)res->user_astparam; 127 res32->user_astparam = (__u32)(long)res->user_astparam;
120 res32->user_lksb = (__u32)(long)res->user_lksb; 128 res32->user_lksb = (__u32)(long)res->user_lksb;
@@ -252,16 +260,18 @@ static int device_user_lock(struct dlm_user_proc *proc,
252 ua->castaddr = params->castaddr; 260 ua->castaddr = params->castaddr;
253 ua->bastparam = params->bastparam; 261 ua->bastparam = params->bastparam;
254 ua->bastaddr = params->bastaddr; 262 ua->bastaddr = params->bastaddr;
263 ua->xid = params->xid;
255 264
256 if (params->flags & DLM_LKF_CONVERT) 265 if (params->flags & DLM_LKF_CONVERT)
257 error = dlm_user_convert(ls, ua, 266 error = dlm_user_convert(ls, ua,
258 params->mode, params->flags, 267 params->mode, params->flags,
259 params->lkid, params->lvb); 268 params->lkid, params->lvb,
269 (unsigned long) params->timeout);
260 else { 270 else {
261 error = dlm_user_request(ls, ua, 271 error = dlm_user_request(ls, ua,
262 params->mode, params->flags, 272 params->mode, params->flags,
263 params->name, params->namelen, 273 params->name, params->namelen,
264 params->parent); 274 (unsigned long) params->timeout);
265 if (!error) 275 if (!error)
266 error = ua->lksb.sb_lkid; 276 error = ua->lksb.sb_lkid;
267 } 277 }
@@ -641,6 +651,9 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
641 int struct_len; 651 int struct_len;
642 652
643 memset(&result, 0, sizeof(struct dlm_lock_result)); 653 memset(&result, 0, sizeof(struct dlm_lock_result));
654 result.version[0] = DLM_DEVICE_VERSION_MAJOR;
655 result.version[1] = DLM_DEVICE_VERSION_MINOR;
656 result.version[2] = DLM_DEVICE_VERSION_PATCH;
644 memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb)); 657 memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb));
645 result.user_lksb = ua->user_lksb; 658 result.user_lksb = ua->user_lksb;
646 659
@@ -699,6 +712,20 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
699 return error; 712 return error;
700} 713}
701 714
715static int copy_version_to_user(char __user *buf, size_t count)
716{
717 struct dlm_device_version ver;
718
719 memset(&ver, 0, sizeof(struct dlm_device_version));
720 ver.version[0] = DLM_DEVICE_VERSION_MAJOR;
721 ver.version[1] = DLM_DEVICE_VERSION_MINOR;
722 ver.version[2] = DLM_DEVICE_VERSION_PATCH;
723
724 if (copy_to_user(buf, &ver, sizeof(struct dlm_device_version)))
725 return -EFAULT;
726 return sizeof(struct dlm_device_version);
727}
728
702/* a read returns a single ast described in a struct dlm_lock_result */ 729/* a read returns a single ast described in a struct dlm_lock_result */
703 730
704static ssize_t device_read(struct file *file, char __user *buf, size_t count, 731static ssize_t device_read(struct file *file, char __user *buf, size_t count,
@@ -710,6 +737,16 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
710 DECLARE_WAITQUEUE(wait, current); 737 DECLARE_WAITQUEUE(wait, current);
711 int error, type=0, bmode=0, removed = 0; 738 int error, type=0, bmode=0, removed = 0;
712 739
740 if (count == sizeof(struct dlm_device_version)) {
741 error = copy_version_to_user(buf, count);
742 return error;
743 }
744
745 if (!proc) {
746 log_print("non-version read from control device %zu", count);
747 return -EINVAL;
748 }
749
713#ifdef CONFIG_COMPAT 750#ifdef CONFIG_COMPAT
714 if (count < sizeof(struct dlm_lock_result32)) 751 if (count < sizeof(struct dlm_lock_result32))
715#else 752#else
@@ -747,11 +784,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
747 } 784 }
748 } 785 }
749 786
750 if (list_empty(&proc->asts)) {
751 spin_unlock(&proc->asts_spin);
752 return -EAGAIN;
753 }
754
755 /* there may be both completion and blocking asts to return for 787 /* there may be both completion and blocking asts to return for
756 the lkb, don't remove lkb from asts list unless no asts remain */ 788 the lkb, don't remove lkb from asts list unless no asts remain */
757 789
@@ -823,6 +855,7 @@ static const struct file_operations device_fops = {
823static const struct file_operations ctl_device_fops = { 855static const struct file_operations ctl_device_fops = {
824 .open = ctl_device_open, 856 .open = ctl_device_open,
825 .release = ctl_device_close, 857 .release = ctl_device_close,
858 .read = device_read,
826 .write = device_write, 859 .write = device_write,
827 .owner = THIS_MODULE, 860 .owner = THIS_MODULE,
828}; 861};