aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/locking/dlm/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/locking/dlm/mount.c')
-rw-r--r--fs/gfs2/locking/dlm/mount.c189
1 files changed, 98 insertions, 91 deletions
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c
index 92b1789deb89..bfb224638f2d 100644
--- a/fs/gfs2/locking/dlm/mount.c
+++ b/fs/gfs2/locking/dlm/mount.c
@@ -1,15 +1,11 @@
1/****************************************************************************** 1/*
2******************************************************************************* 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3** 3 * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4 *
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5 * This copyrighted material is made available to anyone wishing to use,
6** 6 * modify, copy, or redistribute it subject to the terms and conditions
7** This copyrighted material is made available to anyone wishing to use, 7 * of the GNU General Public License v.2.
8** modify, copy, or redistribute it subject to the terms and conditions 8 */
9** of the GNU General Public License v.2.
10**
11*******************************************************************************
12******************************************************************************/
13 9
14#include "lock_dlm.h" 10#include "lock_dlm.h"
15 11
@@ -24,27 +20,21 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata,
24 struct gdlm_ls *ls; 20 struct gdlm_ls *ls;
25 char buf[256], *p; 21 char buf[256], *p;
26 22
27 ls = kmalloc(sizeof(struct gdlm_ls), GFP_KERNEL); 23 ls = kzalloc(sizeof(struct gdlm_ls), GFP_KERNEL);
28 if (!ls) 24 if (!ls)
29 return NULL; 25 return NULL;
30 26
31 memset(ls, 0, sizeof(struct gdlm_ls));
32
33 ls->drop_locks_count = gdlm_drop_count; 27 ls->drop_locks_count = gdlm_drop_count;
34 ls->drop_locks_period = gdlm_drop_period; 28 ls->drop_locks_period = gdlm_drop_period;
35
36 ls->fscb = cb; 29 ls->fscb = cb;
37 ls->fsdata = fsdata; 30 ls->fsdata = fsdata;
38 ls->fsflags = flags; 31 ls->fsflags = flags;
39
40 spin_lock_init(&ls->async_lock); 32 spin_lock_init(&ls->async_lock);
41
42 INIT_LIST_HEAD(&ls->complete); 33 INIT_LIST_HEAD(&ls->complete);
43 INIT_LIST_HEAD(&ls->blocking); 34 INIT_LIST_HEAD(&ls->blocking);
44 INIT_LIST_HEAD(&ls->delayed); 35 INIT_LIST_HEAD(&ls->delayed);
45 INIT_LIST_HEAD(&ls->submit); 36 INIT_LIST_HEAD(&ls->submit);
46 INIT_LIST_HEAD(&ls->all_locks); 37 INIT_LIST_HEAD(&ls->all_locks);
47
48 init_waitqueue_head(&ls->thread_wait); 38 init_waitqueue_head(&ls->thread_wait);
49 init_waitqueue_head(&ls->wait_control); 39 init_waitqueue_head(&ls->wait_control);
50 ls->thread1 = NULL; 40 ls->thread1 = NULL;
@@ -57,23 +47,75 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata,
57 47
58 p = strstr(buf, ":"); 48 p = strstr(buf, ":");
59 if (!p) { 49 if (!p) {
60 printk("lock_dlm: invalid table_name \"%s\"\n", table_name); 50 log_info("invalid table_name \"%s\"", table_name);
61 kfree(ls); 51 kfree(ls);
62 return NULL; 52 return NULL;
63 } 53 }
64 *p = '\0'; 54 *p = '\0';
65 p++; 55 p++;
66 56
67 strncpy(ls->clustername, buf, 128); 57 strncpy(ls->clustername, buf, GDLM_NAME_LEN);
68 strncpy(ls->fsname, p, 128); 58 strncpy(ls->fsname, p, GDLM_NAME_LEN);
69 59
70 return ls; 60 return ls;
71} 61}
72 62
63static int make_args(struct gdlm_ls *ls, char *data_arg)
64{
65 char data[256];
66 char *options, *x, *y;
67 int error = 0;
68
69 memset(data, 0, 256);
70 strncpy(data, data_arg, 255);
71
72 for (options = data; (x = strsep(&options, ":")); ) {
73 if (!*x)
74 continue;
75
76 y = strchr(x, '=');
77 if (y)
78 *y++ = 0;
79
80 if (!strcmp(x, "jid")) {
81 if (!y) {
82 log_error("need argument to jid");
83 error = -EINVAL;
84 break;
85 }
86 sscanf(y, "%u", &ls->jid);
87
88 } else if (!strcmp(x, "first")) {
89 if (!y) {
90 log_error("need argument to first");
91 error = -EINVAL;
92 break;
93 }
94 sscanf(y, "%u", &ls->first);
95
96 } else if (!strcmp(x, "id")) {
97 if (!y) {
98 log_error("need argument to id");
99 error = -EINVAL;
100 break;
101 }
102 sscanf(y, "%u", &ls->id);
103
104 } else {
105 log_error("unkonwn option: %s", x);
106 error = -EINVAL;
107 break;
108 }
109 }
110
111 return error;
112}
113
73static int gdlm_mount(char *table_name, char *host_data, 114static int gdlm_mount(char *table_name, char *host_data,
74 lm_callback_t cb, lm_fsdata_t *fsdata, 115 lm_callback_t cb, lm_fsdata_t *fsdata,
75 unsigned int min_lvb_size, int flags, 116 unsigned int min_lvb_size, int flags,
76 struct lm_lockstruct *lockstruct) 117 struct lm_lockstruct *lockstruct,
118 struct kobject *fskobj)
77{ 119{
78 struct gdlm_ls *ls; 120 struct gdlm_ls *ls;
79 int error = -ENOMEM; 121 int error = -ENOMEM;
@@ -92,30 +134,18 @@ static int gdlm_mount(char *table_name, char *host_data,
92 error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), 134 error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
93 &ls->dlm_lockspace, 0, GDLM_LVB_SIZE); 135 &ls->dlm_lockspace, 0, GDLM_LVB_SIZE);
94 if (error) { 136 if (error) {
95 printk("lock_dlm: dlm_new_lockspace error %d\n", error); 137 log_error("dlm_new_lockspace error %d", error);
96 goto out_thread; 138 goto out_thread;
97 } 139 }
98 140
99 error = gdlm_kobject_setup(ls); 141 error = gdlm_kobject_setup(ls, fskobj);
100 if (error) 142 if (error)
101 goto out_dlm; 143 goto out_dlm;
102 kobject_uevent(&ls->kobj, KOBJ_MOUNT, NULL);
103 144
104 /* Now we depend on userspace to notice the new mount, 145 error = make_args(ls, host_data);
105 join the appropriate group, and do a write to our sysfs
106 "mounted" or "terminate" file. Before the start, userspace
107 must set "jid" and "first". */
108
109 error = wait_event_interruptible(ls->wait_control,
110 test_bit(DFL_JOIN_DONE, &ls->flags));
111 if (error) 146 if (error)
112 goto out_sysfs; 147 goto out_sysfs;
113 148
114 if (test_bit(DFL_TERMINATE, &ls->flags)) {
115 error = -ERESTARTSYS;
116 goto out_sysfs;
117 }
118
119 lockstruct->ls_jid = ls->jid; 149 lockstruct->ls_jid = ls->jid;
120 lockstruct->ls_first = ls->first; 150 lockstruct->ls_first = ls->first;
121 lockstruct->ls_lockspace = ls; 151 lockstruct->ls_lockspace = ls;
@@ -143,22 +173,19 @@ static void gdlm_unmount(lm_lockspace_t *lockspace)
143 173
144 log_debug("unmount flags %lx", ls->flags); 174 log_debug("unmount flags %lx", ls->flags);
145 175
146 if (test_bit(DFL_WITHDRAW, &ls->flags)) { 176 /* FIXME: serialize unmount and withdraw in case they
147 gdlm_kobject_release(ls); 177 happen at once. Also, if unmount follows withdraw,
148 goto out; 178 wait for withdraw to finish. */
149 }
150
151 kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL);
152 179
153 wait_event_interruptible(ls->wait_control, 180 if (test_bit(DFL_WITHDRAW, &ls->flags))
154 test_bit(DFL_LEAVE_DONE, &ls->flags)); 181 goto out;
155 182
156 gdlm_kobject_release(ls); 183 gdlm_kobject_release(ls);
157 dlm_release_lockspace(ls->dlm_lockspace, 2); 184 dlm_release_lockspace(ls->dlm_lockspace, 2);
158 gdlm_release_threads(ls); 185 gdlm_release_threads(ls);
159 rv = gdlm_release_all_locks(ls); 186 rv = gdlm_release_all_locks(ls);
160 if (rv) 187 if (rv)
161 log_all("lm_dlm_unmount: %d stray locks freed", rv); 188 log_info("gdlm_unmount: %d stray locks freed", rv);
162 out: 189 out:
163 kfree(ls); 190 kfree(ls);
164} 191}
@@ -167,7 +194,7 @@ static void gdlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid,
167 unsigned int message) 194 unsigned int message)
168{ 195{
169 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; 196 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
170 ls->recover_done = jid; 197 ls->recover_jid_done = jid;
171 kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL); 198 kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL);
172} 199}
173 200
@@ -178,12 +205,14 @@ static void gdlm_others_may_mount(lm_lockspace_t *lockspace)
178 kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL); 205 kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL);
179} 206}
180 207
208/* Userspace gets the offline uevent, blocks new gfs locks on
209 other mounters, and lets us know (sets WITHDRAW flag). Then,
210 userspace leaves the mount group while we leave the lockspace. */
211
181static void gdlm_withdraw(lm_lockspace_t *lockspace) 212static void gdlm_withdraw(lm_lockspace_t *lockspace)
182{ 213{
183 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; 214 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
184 215
185 /* userspace suspends locking on all other members */
186
187 kobject_uevent(&ls->kobj, KOBJ_OFFLINE, NULL); 216 kobject_uevent(&ls->kobj, KOBJ_OFFLINE, NULL);
188 217
189 wait_event_interruptible(ls->wait_control, 218 wait_event_interruptible(ls->wait_control,
@@ -192,49 +221,27 @@ static void gdlm_withdraw(lm_lockspace_t *lockspace)
192 dlm_release_lockspace(ls->dlm_lockspace, 2); 221 dlm_release_lockspace(ls->dlm_lockspace, 2);
193 gdlm_release_threads(ls); 222 gdlm_release_threads(ls);
194 gdlm_release_all_locks(ls); 223 gdlm_release_all_locks(ls);
195 224 gdlm_kobject_release(ls);
196 kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL);
197
198 /* userspace leaves the mount group, we don't need to wait for
199 that to complete */
200}
201
202int gdlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name,
203 struct file *file, struct file_lock *fl)
204{
205 return -ENOSYS;
206}
207
208int gdlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name,
209 struct file *file, struct file_lock *fl)
210{
211 return -ENOSYS;
212}
213
214int gdlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name,
215 struct file *file, int cmd, struct file_lock *fl)
216{
217 return -ENOSYS;
218} 225}
219 226
220struct lm_lockops gdlm_ops = { 227struct lm_lockops gdlm_ops = {
221 lm_proto_name:"lock_dlm", 228 .lm_proto_name = "lock_dlm",
222 lm_mount:gdlm_mount, 229 .lm_mount = gdlm_mount,
223 lm_others_may_mount:gdlm_others_may_mount, 230 .lm_others_may_mount = gdlm_others_may_mount,
224 lm_unmount:gdlm_unmount, 231 .lm_unmount = gdlm_unmount,
225 lm_withdraw:gdlm_withdraw, 232 .lm_withdraw = gdlm_withdraw,
226 lm_get_lock:gdlm_get_lock, 233 .lm_get_lock = gdlm_get_lock,
227 lm_put_lock:gdlm_put_lock, 234 .lm_put_lock = gdlm_put_lock,
228 lm_lock:gdlm_lock, 235 .lm_lock = gdlm_lock,
229 lm_unlock:gdlm_unlock, 236 .lm_unlock = gdlm_unlock,
230 lm_plock:gdlm_plock, 237 .lm_plock = gdlm_plock,
231 lm_punlock:gdlm_punlock, 238 .lm_punlock = gdlm_punlock,
232 lm_plock_get:gdlm_plock_get, 239 .lm_plock_get = gdlm_plock_get,
233 lm_cancel:gdlm_cancel, 240 .lm_cancel = gdlm_cancel,
234 lm_hold_lvb:gdlm_hold_lvb, 241 .lm_hold_lvb = gdlm_hold_lvb,
235 lm_unhold_lvb:gdlm_unhold_lvb, 242 .lm_unhold_lvb = gdlm_unhold_lvb,
236 lm_sync_lvb:gdlm_sync_lvb, 243 .lm_sync_lvb = gdlm_sync_lvb,
237 lm_recovery_done:gdlm_recovery_done, 244 .lm_recovery_done = gdlm_recovery_done,
238 lm_owner:THIS_MODULE, 245 .lm_owner = THIS_MODULE,
239}; 246};
240 247