blob: 3ca79d3253b9b195e698084f76cc23e686b5a0a7 [file] [log] [blame]
David Teiglande7fd4172006-01-18 09:30:29 +00001/******************************************************************************
2*******************************************************************************
3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
David Teigland60f98d12011-11-02 14:30:58 -05005** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
David Teiglande7fd4172006-01-18 09:30:29 +00006**
7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions
9** of the GNU General Public License v.2.
10**
11*******************************************************************************
12******************************************************************************/
13
14#include "dlm_internal.h"
15#include "lockspace.h"
16#include "member.h"
17#include "recoverd.h"
David Teiglande7fd4172006-01-18 09:30:29 +000018#include "dir.h"
19#include "lowcomms.h"
20#include "config.h"
21#include "memory.h"
22#include "lock.h"
David Teiglandc56b39c2006-04-28 10:51:53 -040023#include "recover.h"
David Teigland2896ee32006-11-27 11:31:22 -060024#include "requestqueue.h"
David Teigland0f8e0d92008-08-06 13:30:24 -050025#include "user.h"
David Teigland23e8e1a2011-04-05 13:16:24 -050026#include "ast.h"
David Teiglande7fd4172006-01-18 09:30:29 +000027
David Teiglande7fd4172006-01-18 09:30:29 +000028static int ls_count;
David Teigland90135922006-01-20 08:47:07 +000029static struct mutex ls_lock;
David Teiglande7fd4172006-01-18 09:30:29 +000030static struct list_head lslist;
31static spinlock_t lslist_lock;
32static struct task_struct * scand_task;
33
34
35static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len)
36{
37 ssize_t ret = len;
38 int n = simple_strtol(buf, NULL, 0);
39
Patrick Caulfielde2de7f52006-11-06 08:53:28 +000040 ls = dlm_find_lockspace_local(ls->ls_local_handle);
41 if (!ls)
42 return -EINVAL;
43
David Teiglande7fd4172006-01-18 09:30:29 +000044 switch (n) {
45 case 0:
46 dlm_ls_stop(ls);
47 break;
48 case 1:
49 dlm_ls_start(ls);
50 break;
51 default:
52 ret = -EINVAL;
53 }
Patrick Caulfielde2de7f52006-11-06 08:53:28 +000054 dlm_put_lockspace(ls);
David Teiglande7fd4172006-01-18 09:30:29 +000055 return ret;
56}
57
58static ssize_t dlm_event_store(struct dlm_ls *ls, const char *buf, size_t len)
59{
60 ls->ls_uevent_result = simple_strtol(buf, NULL, 0);
61 set_bit(LSFL_UEVENT_WAIT, &ls->ls_flags);
62 wake_up(&ls->ls_uevent_wait);
63 return len;
64}
65
66static ssize_t dlm_id_show(struct dlm_ls *ls, char *buf)
67{
David Teiglanda1d144c2006-09-06 17:01:40 -050068 return snprintf(buf, PAGE_SIZE, "%u\n", ls->ls_global_id);
David Teiglande7fd4172006-01-18 09:30:29 +000069}
70
71static ssize_t dlm_id_store(struct dlm_ls *ls, const char *buf, size_t len)
72{
73 ls->ls_global_id = simple_strtoul(buf, NULL, 0);
74 return len;
75}
76
David Teigland48756472012-04-26 15:54:29 -050077static ssize_t dlm_nodir_show(struct dlm_ls *ls, char *buf)
78{
79 return snprintf(buf, PAGE_SIZE, "%u\n", dlm_no_directory(ls));
80}
81
82static ssize_t dlm_nodir_store(struct dlm_ls *ls, const char *buf, size_t len)
83{
84 int val = simple_strtoul(buf, NULL, 0);
85 if (val == 1)
86 set_bit(LSFL_NODIR, &ls->ls_flags);
87 return len;
88}
89
David Teiglandc56b39c2006-04-28 10:51:53 -040090static ssize_t dlm_recover_status_show(struct dlm_ls *ls, char *buf)
91{
92 uint32_t status = dlm_recover_status(ls);
David Teiglanda1d144c2006-09-06 17:01:40 -050093 return snprintf(buf, PAGE_SIZE, "%x\n", status);
David Teiglandc56b39c2006-04-28 10:51:53 -040094}
95
David Teiglandfaa0f262006-08-08 17:08:42 -050096static ssize_t dlm_recover_nodeid_show(struct dlm_ls *ls, char *buf)
97{
David Teiglanda1d144c2006-09-06 17:01:40 -050098 return snprintf(buf, PAGE_SIZE, "%d\n", ls->ls_recover_nodeid);
David Teiglandfaa0f262006-08-08 17:08:42 -050099}
100
David Teiglande7fd4172006-01-18 09:30:29 +0000101struct dlm_attr {
102 struct attribute attr;
103 ssize_t (*show)(struct dlm_ls *, char *);
104 ssize_t (*store)(struct dlm_ls *, const char *, size_t);
105};
106
107static struct dlm_attr dlm_attr_control = {
108 .attr = {.name = "control", .mode = S_IWUSR},
109 .store = dlm_control_store
110};
111
112static struct dlm_attr dlm_attr_event = {
113 .attr = {.name = "event_done", .mode = S_IWUSR},
114 .store = dlm_event_store
115};
116
117static struct dlm_attr dlm_attr_id = {
118 .attr = {.name = "id", .mode = S_IRUGO | S_IWUSR},
119 .show = dlm_id_show,
120 .store = dlm_id_store
121};
122
David Teigland48756472012-04-26 15:54:29 -0500123static struct dlm_attr dlm_attr_nodir = {
124 .attr = {.name = "nodir", .mode = S_IRUGO | S_IWUSR},
125 .show = dlm_nodir_show,
126 .store = dlm_nodir_store
127};
128
David Teiglandc56b39c2006-04-28 10:51:53 -0400129static struct dlm_attr dlm_attr_recover_status = {
130 .attr = {.name = "recover_status", .mode = S_IRUGO},
131 .show = dlm_recover_status_show
132};
133
David Teiglandfaa0f262006-08-08 17:08:42 -0500134static struct dlm_attr dlm_attr_recover_nodeid = {
135 .attr = {.name = "recover_nodeid", .mode = S_IRUGO},
136 .show = dlm_recover_nodeid_show
137};
138
David Teiglande7fd4172006-01-18 09:30:29 +0000139static struct attribute *dlm_attrs[] = {
140 &dlm_attr_control.attr,
141 &dlm_attr_event.attr,
142 &dlm_attr_id.attr,
David Teigland48756472012-04-26 15:54:29 -0500143 &dlm_attr_nodir.attr,
David Teiglandc56b39c2006-04-28 10:51:53 -0400144 &dlm_attr_recover_status.attr,
David Teiglandfaa0f262006-08-08 17:08:42 -0500145 &dlm_attr_recover_nodeid.attr,
David Teiglande7fd4172006-01-18 09:30:29 +0000146 NULL,
147};
148
149static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr,
150 char *buf)
151{
152 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
153 struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);
154 return a->show ? a->show(ls, buf) : 0;
155}
156
157static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr,
158 const char *buf, size_t len)
159{
160 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
161 struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);
162 return a->store ? a->store(ls, buf, len) : len;
163}
164
Patrick Caulfieldba542e32006-11-02 14:41:23 +0000165static void lockspace_kobj_release(struct kobject *k)
166{
167 struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj);
168 kfree(ls);
169}
170
Emese Revfy52cf25d2010-01-19 02:58:23 +0100171static const struct sysfs_ops dlm_attr_ops = {
David Teiglande7fd4172006-01-18 09:30:29 +0000172 .show = dlm_attr_show,
173 .store = dlm_attr_store,
174};
175
176static struct kobj_type dlm_ktype = {
177 .default_attrs = dlm_attrs,
178 .sysfs_ops = &dlm_attr_ops,
Patrick Caulfieldba542e32006-11-02 14:41:23 +0000179 .release = lockspace_kobj_release,
David Teiglande7fd4172006-01-18 09:30:29 +0000180};
181
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100182static struct kset *dlm_kset;
David Teiglande7fd4172006-01-18 09:30:29 +0000183
David Teiglande7fd4172006-01-18 09:30:29 +0000184static int do_uevent(struct dlm_ls *ls, int in)
185{
186 int error;
187
188 if (in)
189 kobject_uevent(&ls->ls_kobj, KOBJ_ONLINE);
190 else
191 kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);
192
David Teigland8b0e7b22007-05-18 09:03:35 -0500193 log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");
194
195 /* dlm_controld will see the uevent, do the necessary group management
196 and then write to sysfs to wake us */
197
David Teiglande7fd4172006-01-18 09:30:29 +0000198 error = wait_event_interruptible(ls->ls_uevent_wait,
199 test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
David Teigland8b0e7b22007-05-18 09:03:35 -0500200
201 log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);
202
David Teiglande7fd4172006-01-18 09:30:29 +0000203 if (error)
204 goto out;
205
206 error = ls->ls_uevent_result;
207 out:
David Teigland8b0e7b22007-05-18 09:03:35 -0500208 if (error)
209 log_error(ls, "group %s failed %d %d", in ? "join" : "leave",
210 error, ls->ls_uevent_result);
David Teiglande7fd4172006-01-18 09:30:29 +0000211 return error;
212}
213
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000214static int dlm_uevent(struct kset *kset, struct kobject *kobj,
215 struct kobj_uevent_env *env)
216{
217 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
218
219 add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name);
220 return 0;
221}
222
223static struct kset_uevent_ops dlm_uevent_ops = {
224 .uevent = dlm_uevent,
225};
David Teiglande7fd4172006-01-18 09:30:29 +0000226
Denis Cheng30727172008-02-02 01:53:46 +0800227int __init dlm_lockspace_init(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000228{
David Teiglande7fd4172006-01-18 09:30:29 +0000229 ls_count = 0;
David Teigland90135922006-01-20 08:47:07 +0000230 mutex_init(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000231 INIT_LIST_HEAD(&lslist);
232 spin_lock_init(&lslist_lock);
233
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000234 dlm_kset = kset_create_and_add("dlm", &dlm_uevent_ops, kernel_kobj);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100235 if (!dlm_kset) {
Harvey Harrison8e24eea2008-04-30 00:55:09 -0700236 printk(KERN_WARNING "%s: can not create kset\n", __func__);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100237 return -ENOMEM;
238 }
239 return 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000240}
241
242void dlm_lockspace_exit(void)
243{
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100244 kset_unregister(dlm_kset);
David Teiglande7fd4172006-01-18 09:30:29 +0000245}
246
David Teiglandc1dcf652008-08-18 14:03:25 -0500247static struct dlm_ls *find_ls_to_scan(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000248{
249 struct dlm_ls *ls;
250
David Teiglandc1dcf652008-08-18 14:03:25 -0500251 spin_lock(&lslist_lock);
252 list_for_each_entry(ls, &lslist, ls_list) {
253 if (time_after_eq(jiffies, ls->ls_scan_time +
254 dlm_config.ci_scan_secs * HZ)) {
255 spin_unlock(&lslist_lock);
256 return ls;
257 }
258 }
259 spin_unlock(&lslist_lock);
260 return NULL;
261}
262
263static int dlm_scand(void *data)
264{
265 struct dlm_ls *ls;
David Teiglandc1dcf652008-08-18 14:03:25 -0500266
David Teiglande7fd4172006-01-18 09:30:29 +0000267 while (!kthread_should_stop()) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500268 ls = find_ls_to_scan();
269 if (ls) {
David Teigland85e86ed2007-05-18 08:58:15 -0500270 if (dlm_lock_recovery_try(ls)) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500271 ls->ls_scan_time = jiffies;
David Teigland85e86ed2007-05-18 08:58:15 -0500272 dlm_scan_rsbs(ls);
David Teigland3ae1acf2007-05-18 08:59:31 -0500273 dlm_scan_timeout(ls);
David Teiglandc6ff6692011-03-28 14:17:26 -0500274 dlm_scan_waiters(ls);
David Teigland85e86ed2007-05-18 08:58:15 -0500275 dlm_unlock_recovery(ls);
David Teiglandc1dcf652008-08-18 14:03:25 -0500276 } else {
277 ls->ls_scan_time += HZ;
David Teigland85e86ed2007-05-18 08:58:15 -0500278 }
David Teiglandc6ff6692011-03-28 14:17:26 -0500279 continue;
David Teigland85e86ed2007-05-18 08:58:15 -0500280 }
David Teiglandc6ff6692011-03-28 14:17:26 -0500281 schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
David Teiglande7fd4172006-01-18 09:30:29 +0000282 }
283 return 0;
284}
285
286static int dlm_scand_start(void)
287{
288 struct task_struct *p;
289 int error = 0;
290
291 p = kthread_run(dlm_scand, NULL, "dlm_scand");
292 if (IS_ERR(p))
293 error = PTR_ERR(p);
294 else
295 scand_task = p;
296 return error;
297}
298
299static void dlm_scand_stop(void)
300{
301 kthread_stop(scand_task);
302}
303
David Teiglande7fd4172006-01-18 09:30:29 +0000304struct dlm_ls *dlm_find_lockspace_global(uint32_t id)
305{
306 struct dlm_ls *ls;
307
308 spin_lock(&lslist_lock);
309
310 list_for_each_entry(ls, &lslist, ls_list) {
311 if (ls->ls_global_id == id) {
312 ls->ls_count++;
313 goto out;
314 }
315 }
316 ls = NULL;
317 out:
318 spin_unlock(&lslist_lock);
319 return ls;
320}
321
David Teigland597d0ca2006-07-12 16:44:04 -0500322struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000323{
David Teigland597d0ca2006-07-12 16:44:04 -0500324 struct dlm_ls *ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000325
326 spin_lock(&lslist_lock);
David Teigland597d0ca2006-07-12 16:44:04 -0500327 list_for_each_entry(ls, &lslist, ls_list) {
328 if (ls->ls_local_handle == lockspace) {
329 ls->ls_count++;
330 goto out;
331 }
332 }
333 ls = NULL;
334 out:
335 spin_unlock(&lslist_lock);
336 return ls;
337}
338
339struct dlm_ls *dlm_find_lockspace_device(int minor)
340{
341 struct dlm_ls *ls;
342
343 spin_lock(&lslist_lock);
344 list_for_each_entry(ls, &lslist, ls_list) {
345 if (ls->ls_device.minor == minor) {
346 ls->ls_count++;
347 goto out;
348 }
349 }
350 ls = NULL;
351 out:
David Teiglande7fd4172006-01-18 09:30:29 +0000352 spin_unlock(&lslist_lock);
353 return ls;
354}
355
356void dlm_put_lockspace(struct dlm_ls *ls)
357{
358 spin_lock(&lslist_lock);
359 ls->ls_count--;
360 spin_unlock(&lslist_lock);
361}
362
363static void remove_lockspace(struct dlm_ls *ls)
364{
365 for (;;) {
366 spin_lock(&lslist_lock);
367 if (ls->ls_count == 0) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500368 WARN_ON(ls->ls_create_count != 0);
David Teiglande7fd4172006-01-18 09:30:29 +0000369 list_del(&ls->ls_list);
370 spin_unlock(&lslist_lock);
371 return;
372 }
373 spin_unlock(&lslist_lock);
374 ssleep(1);
375 }
376}
377
378static int threads_start(void)
379{
380 int error;
381
David Teiglande7fd4172006-01-18 09:30:29 +0000382 error = dlm_scand_start();
383 if (error) {
384 log_print("cannot start dlm_scand thread %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500385 goto fail;
David Teiglande7fd4172006-01-18 09:30:29 +0000386 }
387
388 /* Thread for sending/receiving messages for all lockspace's */
389 error = dlm_lowcomms_start();
390 if (error) {
391 log_print("cannot start dlm lowcomms %d", error);
392 goto scand_fail;
393 }
394
395 return 0;
396
397 scand_fail:
398 dlm_scand_stop();
David Teiglande7fd4172006-01-18 09:30:29 +0000399 fail:
400 return error;
401}
402
403static void threads_stop(void)
404{
405 dlm_scand_stop();
406 dlm_lowcomms_stop();
David Teiglande7fd4172006-01-18 09:30:29 +0000407}
408
David Teigland60f98d12011-11-02 14:30:58 -0500409static int new_lockspace(const char *name, const char *cluster,
410 uint32_t flags, int lvblen,
411 const struct dlm_lockspace_ops *ops, void *ops_arg,
412 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000413{
414 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500415 int i, size, error;
David Teigland79d72b52007-05-18 09:02:20 -0500416 int do_unreg = 0;
David Teigland60f98d12011-11-02 14:30:58 -0500417 int namelen = strlen(name);
David Teiglande7fd4172006-01-18 09:30:29 +0000418
419 if (namelen > DLM_LOCKSPACE_LEN)
420 return -EINVAL;
421
422 if (!lvblen || (lvblen % 8))
423 return -EINVAL;
424
425 if (!try_module_get(THIS_MODULE))
426 return -EINVAL;
427
David Teiglanddc68c7e2008-08-18 11:43:30 -0500428 if (!dlm_user_daemon_available()) {
David Teigland60f98d12011-11-02 14:30:58 -0500429 log_print("dlm user daemon not available");
430 error = -EUNATCH;
431 goto out;
432 }
433
434 if (ops && ops_result) {
435 if (!dlm_config.ci_recover_callbacks)
436 *ops_result = -EOPNOTSUPP;
437 else
438 *ops_result = 0;
439 }
440
441 if (dlm_config.ci_recover_callbacks && cluster &&
442 strncmp(cluster, dlm_config.ci_cluster_name, DLM_LOCKSPACE_LEN)) {
443 log_print("dlm cluster name %s mismatch %s",
444 dlm_config.ci_cluster_name, cluster);
445 error = -EBADR;
446 goto out;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500447 }
448
David Teigland0f8e0d92008-08-06 13:30:24 -0500449 error = 0;
450
451 spin_lock(&lslist_lock);
452 list_for_each_entry(ls, &lslist, ls_list) {
453 WARN_ON(ls->ls_create_count <= 0);
454 if (ls->ls_namelen != namelen)
455 continue;
456 if (memcmp(ls->ls_name, name, namelen))
457 continue;
458 if (flags & DLM_LSFL_NEWEXCL) {
459 error = -EEXIST;
460 break;
461 }
462 ls->ls_create_count++;
David Teigland8511a272009-04-08 15:38:43 -0500463 *lockspace = ls;
464 error = 1;
David Teigland0f8e0d92008-08-06 13:30:24 -0500465 break;
David Teiglande7fd4172006-01-18 09:30:29 +0000466 }
David Teigland0f8e0d92008-08-06 13:30:24 -0500467 spin_unlock(&lslist_lock);
468
David Teigland0f8e0d92008-08-06 13:30:24 -0500469 if (error)
David Teigland8511a272009-04-08 15:38:43 -0500470 goto out;
David Teigland0f8e0d92008-08-06 13:30:24 -0500471
472 error = -ENOMEM;
David Teiglande7fd4172006-01-18 09:30:29 +0000473
David Teigland573c24c2009-11-30 16:34:43 -0600474 ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000475 if (!ls)
476 goto out;
David Teiglande7fd4172006-01-18 09:30:29 +0000477 memcpy(ls->ls_name, name, namelen);
478 ls->ls_namelen = namelen;
David Teiglande7fd4172006-01-18 09:30:29 +0000479 ls->ls_lvblen = lvblen;
480 ls->ls_count = 0;
481 ls->ls_flags = 0;
David Teiglandc1dcf652008-08-18 14:03:25 -0500482 ls->ls_scan_time = jiffies;
David Teiglande7fd4172006-01-18 09:30:29 +0000483
David Teigland60f98d12011-11-02 14:30:58 -0500484 if (ops && dlm_config.ci_recover_callbacks) {
485 ls->ls_ops = ops;
486 ls->ls_ops_arg = ops_arg;
487 }
488
David Teigland3ae1acf2007-05-18 08:59:31 -0500489 if (flags & DLM_LSFL_TIMEWARN)
490 set_bit(LSFL_TIMEWARN, &ls->ls_flags);
David Teigland3ae1acf2007-05-18 08:59:31 -0500491
David Teiglandfad59c12007-06-11 10:47:18 -0500492 /* ls_exflags are forced to match among nodes, and we don't
David Teigland0f8e0d92008-08-06 13:30:24 -0500493 need to require all nodes to have some flags set */
494 ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
495 DLM_LSFL_NEWEXCL));
David Teiglandfad59c12007-06-11 10:47:18 -0500496
David Teigland68c817a2007-01-09 09:41:48 -0600497 size = dlm_config.ci_rsbtbl_size;
David Teiglande7fd4172006-01-18 09:30:29 +0000498 ls->ls_rsbtbl_size = size;
499
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500500 ls->ls_rsbtbl = vmalloc(sizeof(struct dlm_rsbtable) * size);
David Teiglande7fd4172006-01-18 09:30:29 +0000501 if (!ls->ls_rsbtbl)
502 goto out_lsfree;
503 for (i = 0; i < size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500504 ls->ls_rsbtbl[i].keep.rb_node = NULL;
505 ls->ls_rsbtbl[i].toss.rb_node = NULL;
David Teiglandc7be7612009-01-07 16:50:41 -0600506 spin_lock_init(&ls->ls_rsbtbl[i].lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000507 }
508
David Teigland05c32f42012-06-14 12:17:32 -0500509 spin_lock_init(&ls->ls_remove_spin);
510
511 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
512 ls->ls_remove_names[i] = kzalloc(DLM_RESNAME_MAXLEN+1,
513 GFP_KERNEL);
514 if (!ls->ls_remove_names[i])
515 goto out_rsbtbl;
516 }
517
David Teigland3d6aa672011-07-06 17:00:54 -0500518 idr_init(&ls->ls_lkbidr);
519 spin_lock_init(&ls->ls_lkbidr_spin);
David Teiglande7fd4172006-01-18 09:30:29 +0000520
David Teiglande7fd4172006-01-18 09:30:29 +0000521 INIT_LIST_HEAD(&ls->ls_waiters);
David Teigland90135922006-01-20 08:47:07 +0000522 mutex_init(&ls->ls_waiters_mutex);
David Teiglandef0c2bb2007-03-28 09:56:46 -0500523 INIT_LIST_HEAD(&ls->ls_orphans);
524 mutex_init(&ls->ls_orphans_mutex);
David Teigland3ae1acf2007-05-18 08:59:31 -0500525 INIT_LIST_HEAD(&ls->ls_timeout);
526 mutex_init(&ls->ls_timeout_mutex);
David Teiglande7fd4172006-01-18 09:30:29 +0000527
David Teigland3881ac02011-07-07 14:05:03 -0500528 INIT_LIST_HEAD(&ls->ls_new_rsb);
529 spin_lock_init(&ls->ls_new_rsb_spin);
530
David Teiglande7fd4172006-01-18 09:30:29 +0000531 INIT_LIST_HEAD(&ls->ls_nodes);
532 INIT_LIST_HEAD(&ls->ls_nodes_gone);
533 ls->ls_num_nodes = 0;
534 ls->ls_low_nodeid = 0;
535 ls->ls_total_weight = 0;
536 ls->ls_node_array = NULL;
537
538 memset(&ls->ls_stub_rsb, 0, sizeof(struct dlm_rsb));
539 ls->ls_stub_rsb.res_ls = ls;
540
David Teigland5de63192006-07-25 13:44:31 -0500541 ls->ls_debug_rsb_dentry = NULL;
542 ls->ls_debug_waiters_dentry = NULL;
David Teiglande7fd4172006-01-18 09:30:29 +0000543
544 init_waitqueue_head(&ls->ls_uevent_wait);
545 ls->ls_uevent_result = 0;
David Teigland8b0e7b22007-05-18 09:03:35 -0500546 init_completion(&ls->ls_members_done);
547 ls->ls_members_result = -1;
David Teiglande7fd4172006-01-18 09:30:29 +0000548
David Teigland23e8e1a2011-04-05 13:16:24 -0500549 mutex_init(&ls->ls_cb_mutex);
550 INIT_LIST_HEAD(&ls->ls_cb_delay);
551
David Teiglande7fd4172006-01-18 09:30:29 +0000552 ls->ls_recoverd_task = NULL;
David Teigland90135922006-01-20 08:47:07 +0000553 mutex_init(&ls->ls_recoverd_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000554 spin_lock_init(&ls->ls_recover_lock);
David Teigland98f176f2006-11-27 13:19:28 -0600555 spin_lock_init(&ls->ls_rcom_spin);
556 get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t));
David Teiglande7fd4172006-01-18 09:30:29 +0000557 ls->ls_recover_status = 0;
558 ls->ls_recover_seq = 0;
559 ls->ls_recover_args = NULL;
560 init_rwsem(&ls->ls_in_recovery);
David Teiglandc36258b2007-09-27 15:53:38 -0500561 init_rwsem(&ls->ls_recv_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000562 INIT_LIST_HEAD(&ls->ls_requestqueue);
David Teigland90135922006-01-20 08:47:07 +0000563 mutex_init(&ls->ls_requestqueue_mutex);
David Teigland597d0ca2006-07-12 16:44:04 -0500564 mutex_init(&ls->ls_clear_proc_locks);
David Teiglande7fd4172006-01-18 09:30:29 +0000565
David Teigland573c24c2009-11-30 16:34:43 -0600566 ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000567 if (!ls->ls_recover_buf)
David Teigland05c32f42012-06-14 12:17:32 -0500568 goto out_lkbidr;
David Teiglande7fd4172006-01-18 09:30:29 +0000569
David Teigland757a4272011-10-20 13:26:28 -0500570 ls->ls_slot = 0;
571 ls->ls_num_slots = 0;
572 ls->ls_slots_size = 0;
573 ls->ls_slots = NULL;
574
David Teiglande7fd4172006-01-18 09:30:29 +0000575 INIT_LIST_HEAD(&ls->ls_recover_list);
576 spin_lock_init(&ls->ls_recover_list_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500577 idr_init(&ls->ls_recover_idr);
578 spin_lock_init(&ls->ls_recover_idr_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000579 ls->ls_recover_list_count = 0;
David Teigland597d0ca2006-07-12 16:44:04 -0500580 ls->ls_local_handle = ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000581 init_waitqueue_head(&ls->ls_wait_general);
582 INIT_LIST_HEAD(&ls->ls_root_list);
583 init_rwsem(&ls->ls_root_sem);
584
David Teigland5f88f1e2006-08-24 14:47:20 -0500585 spin_lock(&lslist_lock);
David Teigland0f8e0d92008-08-06 13:30:24 -0500586 ls->ls_create_count = 1;
David Teigland5f88f1e2006-08-24 14:47:20 -0500587 list_add(&ls->ls_list, &lslist);
588 spin_unlock(&lslist_lock);
589
David Teigland23e8e1a2011-04-05 13:16:24 -0500590 if (flags & DLM_LSFL_FS) {
591 error = dlm_callback_start(ls);
592 if (error) {
593 log_error(ls, "can't start dlm_callback %d", error);
594 goto out_delist;
595 }
596 }
597
David Teigland475f2302012-08-02 11:08:21 -0500598 init_waitqueue_head(&ls->ls_recover_lock_wait);
599
600 /*
601 * Once started, dlm_recoverd first looks for ls in lslist, then
602 * initializes ls_in_recovery as locked in "down" mode. We need
603 * to wait for the wakeup from dlm_recoverd because in_recovery
604 * has to start out in down mode.
605 */
606
David Teiglande7fd4172006-01-18 09:30:29 +0000607 error = dlm_recoverd_start(ls);
608 if (error) {
609 log_error(ls, "can't start dlm_recoverd %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500610 goto out_callback;
David Teiglande7fd4172006-01-18 09:30:29 +0000611 }
612
David Teigland475f2302012-08-02 11:08:21 -0500613 wait_event(ls->ls_recover_lock_wait,
614 test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
615
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400616 ls->ls_kobj.kset = dlm_kset;
617 error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
618 "%s", ls->ls_name);
David Teiglande7fd4172006-01-18 09:30:29 +0000619 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500620 goto out_recoverd;
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400621 kobject_uevent(&ls->ls_kobj, KOBJ_ADD);
David Teigland79d72b52007-05-18 09:02:20 -0500622
623 /* let kobject handle freeing of ls if there's an error */
624 do_unreg = 1;
David Teiglande7fd4172006-01-18 09:30:29 +0000625
David Teigland8b0e7b22007-05-18 09:03:35 -0500626 /* This uevent triggers dlm_controld in userspace to add us to the
627 group of nodes that are members of this lockspace (managed by the
628 cluster infrastructure.) Once it's done that, it tells us who the
629 current lockspace members are (via configfs) and then tells the
630 lockspace to start running (via sysfs) in dlm_ls_start(). */
631
David Teiglande7fd4172006-01-18 09:30:29 +0000632 error = do_uevent(ls, 1);
633 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500634 goto out_recoverd;
David Teigland79d72b52007-05-18 09:02:20 -0500635
David Teigland8b0e7b22007-05-18 09:03:35 -0500636 wait_for_completion(&ls->ls_members_done);
637 error = ls->ls_members_result;
638 if (error)
639 goto out_members;
640
David Teigland79d72b52007-05-18 09:02:20 -0500641 dlm_create_debug_file(ls);
642
643 log_debug(ls, "join complete");
David Teiglande7fd4172006-01-18 09:30:29 +0000644 *lockspace = ls;
645 return 0;
646
David Teigland8b0e7b22007-05-18 09:03:35 -0500647 out_members:
648 do_uevent(ls, 0);
649 dlm_clear_members(ls);
650 kfree(ls->ls_node_array);
David Teigland23e8e1a2011-04-05 13:16:24 -0500651 out_recoverd:
David Teigland5f88f1e2006-08-24 14:47:20 -0500652 dlm_recoverd_stop(ls);
David Teigland23e8e1a2011-04-05 13:16:24 -0500653 out_callback:
654 dlm_callback_stop(ls);
David Teigland79d72b52007-05-18 09:02:20 -0500655 out_delist:
David Teiglande7fd4172006-01-18 09:30:29 +0000656 spin_lock(&lslist_lock);
657 list_del(&ls->ls_list);
658 spin_unlock(&lslist_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500659 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000660 kfree(ls->ls_recover_buf);
David Teigland05c32f42012-06-14 12:17:32 -0500661 out_lkbidr:
David Teigland3d6aa672011-07-06 17:00:54 -0500662 idr_destroy(&ls->ls_lkbidr);
David Teigland05c32f42012-06-14 12:17:32 -0500663 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
664 if (ls->ls_remove_names[i])
665 kfree(ls->ls_remove_names[i]);
666 }
667 out_rsbtbl:
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500668 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000669 out_lsfree:
David Teigland79d72b52007-05-18 09:02:20 -0500670 if (do_unreg)
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800671 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500672 else
673 kfree(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000674 out:
675 module_put(THIS_MODULE);
676 return error;
677}
678
David Teigland60f98d12011-11-02 14:30:58 -0500679int dlm_new_lockspace(const char *name, const char *cluster,
680 uint32_t flags, int lvblen,
681 const struct dlm_lockspace_ops *ops, void *ops_arg,
682 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000683{
684 int error = 0;
685
David Teigland90135922006-01-20 08:47:07 +0000686 mutex_lock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000687 if (!ls_count)
688 error = threads_start();
689 if (error)
690 goto out;
691
David Teigland60f98d12011-11-02 14:30:58 -0500692 error = new_lockspace(name, cluster, flags, lvblen, ops, ops_arg,
693 ops_result, lockspace);
David Teiglande7fd4172006-01-18 09:30:29 +0000694 if (!error)
695 ls_count++;
David Teigland8511a272009-04-08 15:38:43 -0500696 if (error > 0)
697 error = 0;
698 if (!ls_count)
David Teigland8b0e7b22007-05-18 09:03:35 -0500699 threads_stop();
David Teiglande7fd4172006-01-18 09:30:29 +0000700 out:
David Teigland90135922006-01-20 08:47:07 +0000701 mutex_unlock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000702 return error;
703}
704
David Teigland3d6aa672011-07-06 17:00:54 -0500705static int lkb_idr_is_local(int id, void *p, void *data)
David Teiglande7fd4172006-01-18 09:30:29 +0000706{
David Teigland3d6aa672011-07-06 17:00:54 -0500707 struct dlm_lkb *lkb = p;
David Teiglande7fd4172006-01-18 09:30:29 +0000708
David Teigland3d6aa672011-07-06 17:00:54 -0500709 if (!lkb->lkb_nodeid)
710 return 1;
711 return 0;
712}
David Teiglande7fd4172006-01-18 09:30:29 +0000713
David Teigland3d6aa672011-07-06 17:00:54 -0500714static int lkb_idr_is_any(int id, void *p, void *data)
715{
716 return 1;
717}
718
719static int lkb_idr_free(int id, void *p, void *data)
720{
721 struct dlm_lkb *lkb = p;
722
David Teigland3d6aa672011-07-06 17:00:54 -0500723 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
724 dlm_free_lvb(lkb->lkb_lvbptr);
725
726 dlm_free_lkb(lkb);
727 return 0;
728}
729
730/* NOTE: We check the lkbidr here rather than the resource table.
731 This is because there may be LKBs queued as ASTs that have been unlinked
732 from their RSBs and are pending deletion once the AST has been delivered */
733
734static int lockspace_busy(struct dlm_ls *ls, int force)
735{
736 int rv;
737
738 spin_lock(&ls->ls_lkbidr_spin);
739 if (force == 0) {
740 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls);
741 } else if (force == 1) {
742 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_local, ls);
743 } else {
744 rv = 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000745 }
David Teigland3d6aa672011-07-06 17:00:54 -0500746 spin_unlock(&ls->ls_lkbidr_spin);
747 return rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000748}
749
750static int release_lockspace(struct dlm_ls *ls, int force)
751{
David Teiglande7fd4172006-01-18 09:30:29 +0000752 struct dlm_rsb *rsb;
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500753 struct rb_node *n;
David Teigland0f8e0d92008-08-06 13:30:24 -0500754 int i, busy, rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000755
David Teigland3d6aa672011-07-06 17:00:54 -0500756 busy = lockspace_busy(ls, force);
David Teigland0f8e0d92008-08-06 13:30:24 -0500757
758 spin_lock(&lslist_lock);
759 if (ls->ls_create_count == 1) {
David Teigland3d6aa672011-07-06 17:00:54 -0500760 if (busy) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500761 rv = -EBUSY;
David Teigland3d6aa672011-07-06 17:00:54 -0500762 } else {
David Teigland0f8e0d92008-08-06 13:30:24 -0500763 /* remove_lockspace takes ls off lslist */
764 ls->ls_create_count = 0;
765 rv = 0;
766 }
767 } else if (ls->ls_create_count > 1) {
768 rv = --ls->ls_create_count;
769 } else {
770 rv = -EINVAL;
771 }
772 spin_unlock(&lslist_lock);
773
774 if (rv) {
775 log_debug(ls, "release_lockspace no remove %d", rv);
776 return rv;
777 }
778
779 dlm_device_deregister(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000780
David Teiglanddc68c7e2008-08-18 11:43:30 -0500781 if (force < 3 && dlm_user_daemon_available())
David Teiglande7fd4172006-01-18 09:30:29 +0000782 do_uevent(ls, 0);
783
784 dlm_recoverd_stop(ls);
785
David Teigland23e8e1a2011-04-05 13:16:24 -0500786 dlm_callback_stop(ls);
787
David Teiglande7fd4172006-01-18 09:30:29 +0000788 remove_lockspace(ls);
789
790 dlm_delete_debug_file(ls);
791
David Teiglande7fd4172006-01-18 09:30:29 +0000792 kfree(ls->ls_recover_buf);
793
794 /*
David Teigland3d6aa672011-07-06 17:00:54 -0500795 * Free all lkb's in idr
David Teiglande7fd4172006-01-18 09:30:29 +0000796 */
797
David Teigland3d6aa672011-07-06 17:00:54 -0500798 idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls);
David Teigland3d6aa672011-07-06 17:00:54 -0500799 idr_destroy(&ls->ls_lkbidr);
David Teiglande7fd4172006-01-18 09:30:29 +0000800
David Teiglande7fd4172006-01-18 09:30:29 +0000801 /*
802 * Free all rsb's on rsbtbl[] lists
803 */
804
805 for (i = 0; i < ls->ls_rsbtbl_size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500806 while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) {
807 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
808 rb_erase(n, &ls->ls_rsbtbl[i].keep);
David Teigland52bda2b2007-11-07 09:06:49 -0600809 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000810 }
811
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500812 while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) {
813 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
814 rb_erase(n, &ls->ls_rsbtbl[i].toss);
David Teigland52bda2b2007-11-07 09:06:49 -0600815 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000816 }
817 }
818
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500819 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000820
David Teigland05c32f42012-06-14 12:17:32 -0500821 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
822 kfree(ls->ls_remove_names[i]);
823
David Teigland3881ac02011-07-07 14:05:03 -0500824 while (!list_empty(&ls->ls_new_rsb)) {
825 rsb = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb,
826 res_hashchain);
827 list_del(&rsb->res_hashchain);
828 dlm_free_rsb(rsb);
829 }
830
David Teiglande7fd4172006-01-18 09:30:29 +0000831 /*
832 * Free structures on any other lists
833 */
834
David Teigland2896ee32006-11-27 11:31:22 -0600835 dlm_purge_requestqueue(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000836 kfree(ls->ls_recover_args);
David Teiglande7fd4172006-01-18 09:30:29 +0000837 dlm_clear_members(ls);
838 dlm_clear_members_gone(ls);
839 kfree(ls->ls_node_array);
David Teigland0f8e0d92008-08-06 13:30:24 -0500840 log_debug(ls, "release_lockspace final free");
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800841 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500842 /* The ls structure will be freed when the kobject is done with */
David Teiglande7fd4172006-01-18 09:30:29 +0000843
David Teiglande7fd4172006-01-18 09:30:29 +0000844 module_put(THIS_MODULE);
845 return 0;
846}
847
848/*
849 * Called when a system has released all its locks and is not going to use the
850 * lockspace any longer. We free everything we're managing for this lockspace.
851 * Remaining nodes will go through the recovery process as if we'd died. The
852 * lockspace must continue to function as usual, participating in recoveries,
853 * until this returns.
854 *
855 * Force has 4 possible values:
856 * 0 - don't destroy locksapce if it has any LKBs
857 * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs
858 * 2 - destroy lockspace regardless of LKBs
859 * 3 - destroy lockspace as part of a forced shutdown
860 */
861
862int dlm_release_lockspace(void *lockspace, int force)
863{
864 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500865 int error;
David Teiglande7fd4172006-01-18 09:30:29 +0000866
867 ls = dlm_find_lockspace_local(lockspace);
868 if (!ls)
869 return -EINVAL;
870 dlm_put_lockspace(ls);
David Teigland0f8e0d92008-08-06 13:30:24 -0500871
872 mutex_lock(&ls_lock);
873 error = release_lockspace(ls, force);
874 if (!error)
875 ls_count--;
David Teigland278afcb2008-11-13 13:22:34 -0600876 if (!ls_count)
David Teigland0f8e0d92008-08-06 13:30:24 -0500877 threads_stop();
878 mutex_unlock(&ls_lock);
879
880 return error;
David Teiglande7fd4172006-01-18 09:30:29 +0000881}
882
David Teiglanddc68c7e2008-08-18 11:43:30 -0500883void dlm_stop_lockspaces(void)
884{
885 struct dlm_ls *ls;
886
887 restart:
888 spin_lock(&lslist_lock);
889 list_for_each_entry(ls, &lslist, ls_list) {
890 if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
891 continue;
892 spin_unlock(&lslist_lock);
893 log_error(ls, "no userland control daemon, stopping lockspace");
894 dlm_ls_stop(ls);
895 goto restart;
896 }
897 spin_unlock(&lslist_lock);
898}
899