blob: c010ecfc0d295525de2455b02bf8a94dd8dbedea [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 Teigland0f8e0d92008-08-06 13:30:24 -05005** Copyright (C) 2004-2008 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"
18#include "ast.h"
19#include "dir.h"
20#include "lowcomms.h"
21#include "config.h"
22#include "memory.h"
23#include "lock.h"
David Teiglandc56b39c2006-04-28 10:51:53 -040024#include "recover.h"
David Teigland2896ee32006-11-27 11:31:22 -060025#include "requestqueue.h"
David Teigland0f8e0d92008-08-06 13:30:24 -050026#include "user.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 Teiglandc56b39c2006-04-28 10:51:53 -040077static ssize_t dlm_recover_status_show(struct dlm_ls *ls, char *buf)
78{
79 uint32_t status = dlm_recover_status(ls);
David Teiglanda1d144c2006-09-06 17:01:40 -050080 return snprintf(buf, PAGE_SIZE, "%x\n", status);
David Teiglandc56b39c2006-04-28 10:51:53 -040081}
82
David Teiglandfaa0f262006-08-08 17:08:42 -050083static ssize_t dlm_recover_nodeid_show(struct dlm_ls *ls, char *buf)
84{
David Teiglanda1d144c2006-09-06 17:01:40 -050085 return snprintf(buf, PAGE_SIZE, "%d\n", ls->ls_recover_nodeid);
David Teiglandfaa0f262006-08-08 17:08:42 -050086}
87
David Teiglande7fd4172006-01-18 09:30:29 +000088struct dlm_attr {
89 struct attribute attr;
90 ssize_t (*show)(struct dlm_ls *, char *);
91 ssize_t (*store)(struct dlm_ls *, const char *, size_t);
92};
93
94static struct dlm_attr dlm_attr_control = {
95 .attr = {.name = "control", .mode = S_IWUSR},
96 .store = dlm_control_store
97};
98
99static struct dlm_attr dlm_attr_event = {
100 .attr = {.name = "event_done", .mode = S_IWUSR},
101 .store = dlm_event_store
102};
103
104static struct dlm_attr dlm_attr_id = {
105 .attr = {.name = "id", .mode = S_IRUGO | S_IWUSR},
106 .show = dlm_id_show,
107 .store = dlm_id_store
108};
109
David Teiglandc56b39c2006-04-28 10:51:53 -0400110static struct dlm_attr dlm_attr_recover_status = {
111 .attr = {.name = "recover_status", .mode = S_IRUGO},
112 .show = dlm_recover_status_show
113};
114
David Teiglandfaa0f262006-08-08 17:08:42 -0500115static struct dlm_attr dlm_attr_recover_nodeid = {
116 .attr = {.name = "recover_nodeid", .mode = S_IRUGO},
117 .show = dlm_recover_nodeid_show
118};
119
David Teiglande7fd4172006-01-18 09:30:29 +0000120static struct attribute *dlm_attrs[] = {
121 &dlm_attr_control.attr,
122 &dlm_attr_event.attr,
123 &dlm_attr_id.attr,
David Teiglandc56b39c2006-04-28 10:51:53 -0400124 &dlm_attr_recover_status.attr,
David Teiglandfaa0f262006-08-08 17:08:42 -0500125 &dlm_attr_recover_nodeid.attr,
David Teiglande7fd4172006-01-18 09:30:29 +0000126 NULL,
127};
128
129static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr,
130 char *buf)
131{
132 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
133 struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);
134 return a->show ? a->show(ls, buf) : 0;
135}
136
137static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr,
138 const char *buf, size_t len)
139{
140 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
141 struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);
142 return a->store ? a->store(ls, buf, len) : len;
143}
144
Patrick Caulfieldba542e32006-11-02 14:41:23 +0000145static void lockspace_kobj_release(struct kobject *k)
146{
147 struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj);
148 kfree(ls);
149}
150
David Teiglande7fd4172006-01-18 09:30:29 +0000151static struct sysfs_ops dlm_attr_ops = {
152 .show = dlm_attr_show,
153 .store = dlm_attr_store,
154};
155
156static struct kobj_type dlm_ktype = {
157 .default_attrs = dlm_attrs,
158 .sysfs_ops = &dlm_attr_ops,
Patrick Caulfieldba542e32006-11-02 14:41:23 +0000159 .release = lockspace_kobj_release,
David Teiglande7fd4172006-01-18 09:30:29 +0000160};
161
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100162static struct kset *dlm_kset;
David Teiglande7fd4172006-01-18 09:30:29 +0000163
David Teiglande7fd4172006-01-18 09:30:29 +0000164static int do_uevent(struct dlm_ls *ls, int in)
165{
166 int error;
167
168 if (in)
169 kobject_uevent(&ls->ls_kobj, KOBJ_ONLINE);
170 else
171 kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);
172
David Teigland8b0e7b22007-05-18 09:03:35 -0500173 log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");
174
175 /* dlm_controld will see the uevent, do the necessary group management
176 and then write to sysfs to wake us */
177
David Teiglande7fd4172006-01-18 09:30:29 +0000178 error = wait_event_interruptible(ls->ls_uevent_wait,
179 test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
David Teigland8b0e7b22007-05-18 09:03:35 -0500180
181 log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);
182
David Teiglande7fd4172006-01-18 09:30:29 +0000183 if (error)
184 goto out;
185
186 error = ls->ls_uevent_result;
187 out:
David Teigland8b0e7b22007-05-18 09:03:35 -0500188 if (error)
189 log_error(ls, "group %s failed %d %d", in ? "join" : "leave",
190 error, ls->ls_uevent_result);
David Teiglande7fd4172006-01-18 09:30:29 +0000191 return error;
192}
193
194
Denis Cheng30727172008-02-02 01:53:46 +0800195int __init dlm_lockspace_init(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000196{
David Teiglande7fd4172006-01-18 09:30:29 +0000197 ls_count = 0;
David Teigland90135922006-01-20 08:47:07 +0000198 mutex_init(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000199 INIT_LIST_HEAD(&lslist);
200 spin_lock_init(&lslist_lock);
201
Greg Kroah-Hartman0ff21e42007-11-06 10:36:58 -0800202 dlm_kset = kset_create_and_add("dlm", NULL, kernel_kobj);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100203 if (!dlm_kset) {
Harvey Harrison8e24eea2008-04-30 00:55:09 -0700204 printk(KERN_WARNING "%s: can not create kset\n", __func__);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100205 return -ENOMEM;
206 }
207 return 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000208}
209
210void dlm_lockspace_exit(void)
211{
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100212 kset_unregister(dlm_kset);
David Teiglande7fd4172006-01-18 09:30:29 +0000213}
214
David Teiglandc1dcf652008-08-18 14:03:25 -0500215static struct dlm_ls *find_ls_to_scan(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000216{
217 struct dlm_ls *ls;
218
David Teiglandc1dcf652008-08-18 14:03:25 -0500219 spin_lock(&lslist_lock);
220 list_for_each_entry(ls, &lslist, ls_list) {
221 if (time_after_eq(jiffies, ls->ls_scan_time +
222 dlm_config.ci_scan_secs * HZ)) {
223 spin_unlock(&lslist_lock);
224 return ls;
225 }
226 }
227 spin_unlock(&lslist_lock);
228 return NULL;
229}
230
231static int dlm_scand(void *data)
232{
233 struct dlm_ls *ls;
234 int timeout_jiffies = dlm_config.ci_scan_secs * HZ;
235
David Teiglande7fd4172006-01-18 09:30:29 +0000236 while (!kthread_should_stop()) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500237 ls = find_ls_to_scan();
238 if (ls) {
David Teigland85e86ed2007-05-18 08:58:15 -0500239 if (dlm_lock_recovery_try(ls)) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500240 ls->ls_scan_time = jiffies;
David Teigland85e86ed2007-05-18 08:58:15 -0500241 dlm_scan_rsbs(ls);
David Teigland3ae1acf2007-05-18 08:59:31 -0500242 dlm_scan_timeout(ls);
David Teigland85e86ed2007-05-18 08:58:15 -0500243 dlm_unlock_recovery(ls);
David Teiglandc1dcf652008-08-18 14:03:25 -0500244 } else {
245 ls->ls_scan_time += HZ;
David Teigland85e86ed2007-05-18 08:58:15 -0500246 }
David Teiglandc1dcf652008-08-18 14:03:25 -0500247 } else {
248 schedule_timeout_interruptible(timeout_jiffies);
David Teigland85e86ed2007-05-18 08:58:15 -0500249 }
David Teiglande7fd4172006-01-18 09:30:29 +0000250 }
251 return 0;
252}
253
254static int dlm_scand_start(void)
255{
256 struct task_struct *p;
257 int error = 0;
258
259 p = kthread_run(dlm_scand, NULL, "dlm_scand");
260 if (IS_ERR(p))
261 error = PTR_ERR(p);
262 else
263 scand_task = p;
264 return error;
265}
266
267static void dlm_scand_stop(void)
268{
269 kthread_stop(scand_task);
270}
271
David Teiglande7fd4172006-01-18 09:30:29 +0000272struct dlm_ls *dlm_find_lockspace_global(uint32_t id)
273{
274 struct dlm_ls *ls;
275
276 spin_lock(&lslist_lock);
277
278 list_for_each_entry(ls, &lslist, ls_list) {
279 if (ls->ls_global_id == id) {
280 ls->ls_count++;
281 goto out;
282 }
283 }
284 ls = NULL;
285 out:
286 spin_unlock(&lslist_lock);
287 return ls;
288}
289
David Teigland597d0ca2006-07-12 16:44:04 -0500290struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000291{
David Teigland597d0ca2006-07-12 16:44:04 -0500292 struct dlm_ls *ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000293
294 spin_lock(&lslist_lock);
David Teigland597d0ca2006-07-12 16:44:04 -0500295 list_for_each_entry(ls, &lslist, ls_list) {
296 if (ls->ls_local_handle == lockspace) {
297 ls->ls_count++;
298 goto out;
299 }
300 }
301 ls = NULL;
302 out:
303 spin_unlock(&lslist_lock);
304 return ls;
305}
306
307struct dlm_ls *dlm_find_lockspace_device(int minor)
308{
309 struct dlm_ls *ls;
310
311 spin_lock(&lslist_lock);
312 list_for_each_entry(ls, &lslist, ls_list) {
313 if (ls->ls_device.minor == minor) {
314 ls->ls_count++;
315 goto out;
316 }
317 }
318 ls = NULL;
319 out:
David Teiglande7fd4172006-01-18 09:30:29 +0000320 spin_unlock(&lslist_lock);
321 return ls;
322}
323
324void dlm_put_lockspace(struct dlm_ls *ls)
325{
326 spin_lock(&lslist_lock);
327 ls->ls_count--;
328 spin_unlock(&lslist_lock);
329}
330
331static void remove_lockspace(struct dlm_ls *ls)
332{
333 for (;;) {
334 spin_lock(&lslist_lock);
335 if (ls->ls_count == 0) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500336 WARN_ON(ls->ls_create_count != 0);
David Teiglande7fd4172006-01-18 09:30:29 +0000337 list_del(&ls->ls_list);
338 spin_unlock(&lslist_lock);
339 return;
340 }
341 spin_unlock(&lslist_lock);
342 ssleep(1);
343 }
344}
345
346static int threads_start(void)
347{
348 int error;
349
350 /* Thread which process lock requests for all lockspace's */
351 error = dlm_astd_start();
352 if (error) {
353 log_print("cannot start dlm_astd thread %d", error);
354 goto fail;
355 }
356
357 error = dlm_scand_start();
358 if (error) {
359 log_print("cannot start dlm_scand thread %d", error);
360 goto astd_fail;
361 }
362
363 /* Thread for sending/receiving messages for all lockspace's */
364 error = dlm_lowcomms_start();
365 if (error) {
366 log_print("cannot start dlm lowcomms %d", error);
367 goto scand_fail;
368 }
369
370 return 0;
371
372 scand_fail:
373 dlm_scand_stop();
374 astd_fail:
375 dlm_astd_stop();
376 fail:
377 return error;
378}
379
380static void threads_stop(void)
381{
382 dlm_scand_stop();
383 dlm_lowcomms_stop();
384 dlm_astd_stop();
385}
386
Geert Uytterhoeven08ce4c92009-04-07 23:40:39 +0200387static int new_lockspace(const char *name, int namelen, void **lockspace,
David Teiglande7fd4172006-01-18 09:30:29 +0000388 uint32_t flags, int lvblen)
389{
390 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500391 int i, size, error;
David Teigland79d72b52007-05-18 09:02:20 -0500392 int do_unreg = 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000393
394 if (namelen > DLM_LOCKSPACE_LEN)
395 return -EINVAL;
396
397 if (!lvblen || (lvblen % 8))
398 return -EINVAL;
399
400 if (!try_module_get(THIS_MODULE))
401 return -EINVAL;
402
David Teiglanddc68c7e2008-08-18 11:43:30 -0500403 if (!dlm_user_daemon_available()) {
404 module_put(THIS_MODULE);
405 return -EUNATCH;
406 }
407
David Teigland0f8e0d92008-08-06 13:30:24 -0500408 error = 0;
409
410 spin_lock(&lslist_lock);
411 list_for_each_entry(ls, &lslist, ls_list) {
412 WARN_ON(ls->ls_create_count <= 0);
413 if (ls->ls_namelen != namelen)
414 continue;
415 if (memcmp(ls->ls_name, name, namelen))
416 continue;
417 if (flags & DLM_LSFL_NEWEXCL) {
418 error = -EEXIST;
419 break;
420 }
421 ls->ls_create_count++;
David Teigland8511a272009-04-08 15:38:43 -0500422 *lockspace = ls;
423 error = 1;
David Teigland0f8e0d92008-08-06 13:30:24 -0500424 break;
David Teiglande7fd4172006-01-18 09:30:29 +0000425 }
David Teigland0f8e0d92008-08-06 13:30:24 -0500426 spin_unlock(&lslist_lock);
427
David Teigland0f8e0d92008-08-06 13:30:24 -0500428 if (error)
David Teigland8511a272009-04-08 15:38:43 -0500429 goto out;
David Teigland0f8e0d92008-08-06 13:30:24 -0500430
431 error = -ENOMEM;
David Teiglande7fd4172006-01-18 09:30:29 +0000432
David Teigland573c24c2009-11-30 16:34:43 -0600433 ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000434 if (!ls)
435 goto out;
David Teiglande7fd4172006-01-18 09:30:29 +0000436 memcpy(ls->ls_name, name, namelen);
437 ls->ls_namelen = namelen;
David Teiglande7fd4172006-01-18 09:30:29 +0000438 ls->ls_lvblen = lvblen;
439 ls->ls_count = 0;
440 ls->ls_flags = 0;
David Teiglandc1dcf652008-08-18 14:03:25 -0500441 ls->ls_scan_time = jiffies;
David Teiglande7fd4172006-01-18 09:30:29 +0000442
David Teigland3ae1acf2007-05-18 08:59:31 -0500443 if (flags & DLM_LSFL_TIMEWARN)
444 set_bit(LSFL_TIMEWARN, &ls->ls_flags);
David Teigland3ae1acf2007-05-18 08:59:31 -0500445
David Teiglandfad59c12007-06-11 10:47:18 -0500446 /* ls_exflags are forced to match among nodes, and we don't
David Teigland0f8e0d92008-08-06 13:30:24 -0500447 need to require all nodes to have some flags set */
448 ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
449 DLM_LSFL_NEWEXCL));
David Teiglandfad59c12007-06-11 10:47:18 -0500450
David Teigland68c817a2007-01-09 09:41:48 -0600451 size = dlm_config.ci_rsbtbl_size;
David Teiglande7fd4172006-01-18 09:30:29 +0000452 ls->ls_rsbtbl_size = size;
453
David Teigland573c24c2009-11-30 16:34:43 -0600454 ls->ls_rsbtbl = kmalloc(sizeof(struct dlm_rsbtable) * size, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000455 if (!ls->ls_rsbtbl)
456 goto out_lsfree;
457 for (i = 0; i < size; i++) {
458 INIT_LIST_HEAD(&ls->ls_rsbtbl[i].list);
459 INIT_LIST_HEAD(&ls->ls_rsbtbl[i].toss);
David Teiglandc7be7612009-01-07 16:50:41 -0600460 spin_lock_init(&ls->ls_rsbtbl[i].lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000461 }
462
David Teigland68c817a2007-01-09 09:41:48 -0600463 size = dlm_config.ci_lkbtbl_size;
David Teiglande7fd4172006-01-18 09:30:29 +0000464 ls->ls_lkbtbl_size = size;
465
David Teigland573c24c2009-11-30 16:34:43 -0600466 ls->ls_lkbtbl = kmalloc(sizeof(struct dlm_lkbtable) * size, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000467 if (!ls->ls_lkbtbl)
468 goto out_rsbfree;
469 for (i = 0; i < size; i++) {
470 INIT_LIST_HEAD(&ls->ls_lkbtbl[i].list);
471 rwlock_init(&ls->ls_lkbtbl[i].lock);
472 ls->ls_lkbtbl[i].counter = 1;
473 }
474
David Teigland68c817a2007-01-09 09:41:48 -0600475 size = dlm_config.ci_dirtbl_size;
David Teiglande7fd4172006-01-18 09:30:29 +0000476 ls->ls_dirtbl_size = size;
477
David Teigland573c24c2009-11-30 16:34:43 -0600478 ls->ls_dirtbl = kmalloc(sizeof(struct dlm_dirtable) * size, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000479 if (!ls->ls_dirtbl)
480 goto out_lkbfree;
481 for (i = 0; i < size; i++) {
482 INIT_LIST_HEAD(&ls->ls_dirtbl[i].list);
Steven Whitehouse305a47b2009-01-16 16:21:12 +0000483 spin_lock_init(&ls->ls_dirtbl[i].lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000484 }
485
486 INIT_LIST_HEAD(&ls->ls_waiters);
David Teigland90135922006-01-20 08:47:07 +0000487 mutex_init(&ls->ls_waiters_mutex);
David Teiglandef0c2bb2007-03-28 09:56:46 -0500488 INIT_LIST_HEAD(&ls->ls_orphans);
489 mutex_init(&ls->ls_orphans_mutex);
David Teigland3ae1acf2007-05-18 08:59:31 -0500490 INIT_LIST_HEAD(&ls->ls_timeout);
491 mutex_init(&ls->ls_timeout_mutex);
David Teiglande7fd4172006-01-18 09:30:29 +0000492
493 INIT_LIST_HEAD(&ls->ls_nodes);
494 INIT_LIST_HEAD(&ls->ls_nodes_gone);
495 ls->ls_num_nodes = 0;
496 ls->ls_low_nodeid = 0;
497 ls->ls_total_weight = 0;
498 ls->ls_node_array = NULL;
499
500 memset(&ls->ls_stub_rsb, 0, sizeof(struct dlm_rsb));
501 ls->ls_stub_rsb.res_ls = ls;
502
David Teigland5de63192006-07-25 13:44:31 -0500503 ls->ls_debug_rsb_dentry = NULL;
504 ls->ls_debug_waiters_dentry = NULL;
David Teiglande7fd4172006-01-18 09:30:29 +0000505
506 init_waitqueue_head(&ls->ls_uevent_wait);
507 ls->ls_uevent_result = 0;
David Teigland8b0e7b22007-05-18 09:03:35 -0500508 init_completion(&ls->ls_members_done);
509 ls->ls_members_result = -1;
David Teiglande7fd4172006-01-18 09:30:29 +0000510
511 ls->ls_recoverd_task = NULL;
David Teigland90135922006-01-20 08:47:07 +0000512 mutex_init(&ls->ls_recoverd_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000513 spin_lock_init(&ls->ls_recover_lock);
David Teigland98f176f2006-11-27 13:19:28 -0600514 spin_lock_init(&ls->ls_rcom_spin);
515 get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t));
David Teiglande7fd4172006-01-18 09:30:29 +0000516 ls->ls_recover_status = 0;
517 ls->ls_recover_seq = 0;
518 ls->ls_recover_args = NULL;
519 init_rwsem(&ls->ls_in_recovery);
David Teiglandc36258b2007-09-27 15:53:38 -0500520 init_rwsem(&ls->ls_recv_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000521 INIT_LIST_HEAD(&ls->ls_requestqueue);
David Teigland90135922006-01-20 08:47:07 +0000522 mutex_init(&ls->ls_requestqueue_mutex);
David Teigland597d0ca2006-07-12 16:44:04 -0500523 mutex_init(&ls->ls_clear_proc_locks);
David Teiglande7fd4172006-01-18 09:30:29 +0000524
David Teigland573c24c2009-11-30 16:34:43 -0600525 ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000526 if (!ls->ls_recover_buf)
527 goto out_dirfree;
528
529 INIT_LIST_HEAD(&ls->ls_recover_list);
530 spin_lock_init(&ls->ls_recover_list_lock);
531 ls->ls_recover_list_count = 0;
David Teigland597d0ca2006-07-12 16:44:04 -0500532 ls->ls_local_handle = ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000533 init_waitqueue_head(&ls->ls_wait_general);
534 INIT_LIST_HEAD(&ls->ls_root_list);
535 init_rwsem(&ls->ls_root_sem);
536
537 down_write(&ls->ls_in_recovery);
538
David Teigland5f88f1e2006-08-24 14:47:20 -0500539 spin_lock(&lslist_lock);
David Teigland0f8e0d92008-08-06 13:30:24 -0500540 ls->ls_create_count = 1;
David Teigland5f88f1e2006-08-24 14:47:20 -0500541 list_add(&ls->ls_list, &lslist);
542 spin_unlock(&lslist_lock);
543
544 /* needs to find ls in lslist */
David Teiglande7fd4172006-01-18 09:30:29 +0000545 error = dlm_recoverd_start(ls);
546 if (error) {
547 log_error(ls, "can't start dlm_recoverd %d", error);
David Teigland79d72b52007-05-18 09:02:20 -0500548 goto out_delist;
David Teiglande7fd4172006-01-18 09:30:29 +0000549 }
550
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400551 ls->ls_kobj.kset = dlm_kset;
552 error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
553 "%s", ls->ls_name);
David Teiglande7fd4172006-01-18 09:30:29 +0000554 if (error)
David Teigland79d72b52007-05-18 09:02:20 -0500555 goto out_stop;
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400556 kobject_uevent(&ls->ls_kobj, KOBJ_ADD);
David Teigland79d72b52007-05-18 09:02:20 -0500557
558 /* let kobject handle freeing of ls if there's an error */
559 do_unreg = 1;
David Teiglande7fd4172006-01-18 09:30:29 +0000560
David Teigland8b0e7b22007-05-18 09:03:35 -0500561 /* This uevent triggers dlm_controld in userspace to add us to the
562 group of nodes that are members of this lockspace (managed by the
563 cluster infrastructure.) Once it's done that, it tells us who the
564 current lockspace members are (via configfs) and then tells the
565 lockspace to start running (via sysfs) in dlm_ls_start(). */
566
David Teiglande7fd4172006-01-18 09:30:29 +0000567 error = do_uevent(ls, 1);
568 if (error)
David Teigland79d72b52007-05-18 09:02:20 -0500569 goto out_stop;
570
David Teigland8b0e7b22007-05-18 09:03:35 -0500571 wait_for_completion(&ls->ls_members_done);
572 error = ls->ls_members_result;
573 if (error)
574 goto out_members;
575
David Teigland79d72b52007-05-18 09:02:20 -0500576 dlm_create_debug_file(ls);
577
578 log_debug(ls, "join complete");
David Teiglande7fd4172006-01-18 09:30:29 +0000579 *lockspace = ls;
580 return 0;
581
David Teigland8b0e7b22007-05-18 09:03:35 -0500582 out_members:
583 do_uevent(ls, 0);
584 dlm_clear_members(ls);
585 kfree(ls->ls_node_array);
David Teigland79d72b52007-05-18 09:02:20 -0500586 out_stop:
David Teigland5f88f1e2006-08-24 14:47:20 -0500587 dlm_recoverd_stop(ls);
David Teigland79d72b52007-05-18 09:02:20 -0500588 out_delist:
David Teiglande7fd4172006-01-18 09:30:29 +0000589 spin_lock(&lslist_lock);
590 list_del(&ls->ls_list);
591 spin_unlock(&lslist_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000592 kfree(ls->ls_recover_buf);
593 out_dirfree:
594 kfree(ls->ls_dirtbl);
595 out_lkbfree:
596 kfree(ls->ls_lkbtbl);
597 out_rsbfree:
598 kfree(ls->ls_rsbtbl);
599 out_lsfree:
David Teigland79d72b52007-05-18 09:02:20 -0500600 if (do_unreg)
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800601 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500602 else
603 kfree(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000604 out:
605 module_put(THIS_MODULE);
606 return error;
607}
608
Geert Uytterhoeven08ce4c92009-04-07 23:40:39 +0200609int dlm_new_lockspace(const char *name, int namelen, void **lockspace,
David Teiglande7fd4172006-01-18 09:30:29 +0000610 uint32_t flags, int lvblen)
611{
612 int error = 0;
613
David Teigland90135922006-01-20 08:47:07 +0000614 mutex_lock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000615 if (!ls_count)
616 error = threads_start();
617 if (error)
618 goto out;
619
620 error = new_lockspace(name, namelen, lockspace, flags, lvblen);
621 if (!error)
622 ls_count++;
David Teigland8511a272009-04-08 15:38:43 -0500623 if (error > 0)
624 error = 0;
625 if (!ls_count)
David Teigland8b0e7b22007-05-18 09:03:35 -0500626 threads_stop();
David Teiglande7fd4172006-01-18 09:30:29 +0000627 out:
David Teigland90135922006-01-20 08:47:07 +0000628 mutex_unlock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000629 return error;
630}
631
632/* Return 1 if the lockspace still has active remote locks,
633 * 2 if the lockspace still has active local locks.
634 */
635static int lockspace_busy(struct dlm_ls *ls)
636{
637 int i, lkb_found = 0;
638 struct dlm_lkb *lkb;
639
640 /* NOTE: We check the lockidtbl here rather than the resource table.
641 This is because there may be LKBs queued as ASTs that have been
642 unlinked from their RSBs and are pending deletion once the AST has
643 been delivered */
644
645 for (i = 0; i < ls->ls_lkbtbl_size; i++) {
646 read_lock(&ls->ls_lkbtbl[i].lock);
647 if (!list_empty(&ls->ls_lkbtbl[i].list)) {
648 lkb_found = 1;
649 list_for_each_entry(lkb, &ls->ls_lkbtbl[i].list,
650 lkb_idtbl_list) {
651 if (!lkb->lkb_nodeid) {
652 read_unlock(&ls->ls_lkbtbl[i].lock);
653 return 2;
654 }
655 }
656 }
657 read_unlock(&ls->ls_lkbtbl[i].lock);
658 }
659 return lkb_found;
660}
661
662static int release_lockspace(struct dlm_ls *ls, int force)
663{
664 struct dlm_lkb *lkb;
665 struct dlm_rsb *rsb;
666 struct list_head *head;
David Teigland0f8e0d92008-08-06 13:30:24 -0500667 int i, busy, rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000668
David Teigland0f8e0d92008-08-06 13:30:24 -0500669 busy = lockspace_busy(ls);
670
671 spin_lock(&lslist_lock);
672 if (ls->ls_create_count == 1) {
673 if (busy > force)
674 rv = -EBUSY;
675 else {
676 /* remove_lockspace takes ls off lslist */
677 ls->ls_create_count = 0;
678 rv = 0;
679 }
680 } else if (ls->ls_create_count > 1) {
681 rv = --ls->ls_create_count;
682 } else {
683 rv = -EINVAL;
684 }
685 spin_unlock(&lslist_lock);
686
687 if (rv) {
688 log_debug(ls, "release_lockspace no remove %d", rv);
689 return rv;
690 }
691
692 dlm_device_deregister(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000693
David Teiglanddc68c7e2008-08-18 11:43:30 -0500694 if (force < 3 && dlm_user_daemon_available())
David Teiglande7fd4172006-01-18 09:30:29 +0000695 do_uevent(ls, 0);
696
697 dlm_recoverd_stop(ls);
698
699 remove_lockspace(ls);
700
701 dlm_delete_debug_file(ls);
702
703 dlm_astd_suspend();
704
705 kfree(ls->ls_recover_buf);
706
707 /*
708 * Free direntry structs.
709 */
710
711 dlm_dir_clear(ls);
712 kfree(ls->ls_dirtbl);
713
714 /*
715 * Free all lkb's on lkbtbl[] lists.
716 */
717
718 for (i = 0; i < ls->ls_lkbtbl_size; i++) {
719 head = &ls->ls_lkbtbl[i].list;
720 while (!list_empty(head)) {
721 lkb = list_entry(head->next, struct dlm_lkb,
722 lkb_idtbl_list);
723
724 list_del(&lkb->lkb_idtbl_list);
725
726 dlm_del_ast(lkb);
727
728 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
David Teigland52bda2b2007-11-07 09:06:49 -0600729 dlm_free_lvb(lkb->lkb_lvbptr);
David Teiglande7fd4172006-01-18 09:30:29 +0000730
David Teigland52bda2b2007-11-07 09:06:49 -0600731 dlm_free_lkb(lkb);
David Teiglande7fd4172006-01-18 09:30:29 +0000732 }
733 }
734 dlm_astd_resume();
735
736 kfree(ls->ls_lkbtbl);
737
738 /*
739 * Free all rsb's on rsbtbl[] lists
740 */
741
742 for (i = 0; i < ls->ls_rsbtbl_size; i++) {
743 head = &ls->ls_rsbtbl[i].list;
744 while (!list_empty(head)) {
745 rsb = list_entry(head->next, struct dlm_rsb,
746 res_hashchain);
747
748 list_del(&rsb->res_hashchain);
David Teigland52bda2b2007-11-07 09:06:49 -0600749 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000750 }
751
752 head = &ls->ls_rsbtbl[i].toss;
753 while (!list_empty(head)) {
754 rsb = list_entry(head->next, struct dlm_rsb,
755 res_hashchain);
756 list_del(&rsb->res_hashchain);
David Teigland52bda2b2007-11-07 09:06:49 -0600757 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000758 }
759 }
760
761 kfree(ls->ls_rsbtbl);
762
763 /*
764 * Free structures on any other lists
765 */
766
David Teigland2896ee32006-11-27 11:31:22 -0600767 dlm_purge_requestqueue(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000768 kfree(ls->ls_recover_args);
769 dlm_clear_free_entries(ls);
770 dlm_clear_members(ls);
771 dlm_clear_members_gone(ls);
772 kfree(ls->ls_node_array);
David Teigland0f8e0d92008-08-06 13:30:24 -0500773 log_debug(ls, "release_lockspace final free");
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800774 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500775 /* The ls structure will be freed when the kobject is done with */
David Teiglande7fd4172006-01-18 09:30:29 +0000776
David Teiglande7fd4172006-01-18 09:30:29 +0000777 module_put(THIS_MODULE);
778 return 0;
779}
780
781/*
782 * Called when a system has released all its locks and is not going to use the
783 * lockspace any longer. We free everything we're managing for this lockspace.
784 * Remaining nodes will go through the recovery process as if we'd died. The
785 * lockspace must continue to function as usual, participating in recoveries,
786 * until this returns.
787 *
788 * Force has 4 possible values:
789 * 0 - don't destroy locksapce if it has any LKBs
790 * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs
791 * 2 - destroy lockspace regardless of LKBs
792 * 3 - destroy lockspace as part of a forced shutdown
793 */
794
795int dlm_release_lockspace(void *lockspace, int force)
796{
797 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500798 int error;
David Teiglande7fd4172006-01-18 09:30:29 +0000799
800 ls = dlm_find_lockspace_local(lockspace);
801 if (!ls)
802 return -EINVAL;
803 dlm_put_lockspace(ls);
David Teigland0f8e0d92008-08-06 13:30:24 -0500804
805 mutex_lock(&ls_lock);
806 error = release_lockspace(ls, force);
807 if (!error)
808 ls_count--;
David Teigland278afcb2008-11-13 13:22:34 -0600809 if (!ls_count)
David Teigland0f8e0d92008-08-06 13:30:24 -0500810 threads_stop();
811 mutex_unlock(&ls_lock);
812
813 return error;
David Teiglande7fd4172006-01-18 09:30:29 +0000814}
815
David Teiglanddc68c7e2008-08-18 11:43:30 -0500816void dlm_stop_lockspaces(void)
817{
818 struct dlm_ls *ls;
819
820 restart:
821 spin_lock(&lslist_lock);
822 list_for_each_entry(ls, &lslist, ls_list) {
823 if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
824 continue;
825 spin_unlock(&lslist_lock);
826 log_error(ls, "no userland control daemon, stopping lockspace");
827 dlm_ls_stop(ls);
828 goto restart;
829 }
830 spin_unlock(&lslist_lock);
831}
832