blob: 10eddfa6c3d7bab0a4c164ed4b2bb99be4d5a5c2 [file] [log] [blame]
Thomas Gleixner2522fe42019-05-28 09:57:20 -07001// SPDX-License-Identifier: GPL-2.0-only
David Teiglande7fd4172006-01-18 09:30:29 +00002/******************************************************************************
3*******************************************************************************
4**
5** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
David Teigland60f98d12011-11-02 14:30:58 -05006** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
David Teiglande7fd4172006-01-18 09:30:29 +00007**
David Teiglande7fd4172006-01-18 09:30:29 +00008**
9*******************************************************************************
10******************************************************************************/
11
Paul Gortmaker7963b8a2016-09-19 16:44:50 -040012#include <linux/module.h>
13
David Teiglande7fd4172006-01-18 09:30:29 +000014#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"
Alexander Aringa070a912021-05-21 15:08:41 -040019#include "midcomms.h"
David Teiglande7fd4172006-01-18 09:30:29 +000020#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 Teigland23e8e1a2011-04-05 13:16:24 -050027#include "ast.h"
David Teiglande7fd4172006-01-18 09:30:29 +000028
David Teiglande7fd4172006-01-18 09:30:29 +000029static int ls_count;
David Teigland90135922006-01-20 08:47:07 +000030static struct mutex ls_lock;
David Teiglande7fd4172006-01-18 09:30:29 +000031static struct list_head lslist;
32static spinlock_t lslist_lock;
33static struct task_struct * scand_task;
34
35
36static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len)
37{
38 ssize_t ret = len;
Fabian Frederick6edb5682014-06-06 14:38:25 -070039 int n;
40 int rc = kstrtoint(buf, 0, &n);
David Teiglande7fd4172006-01-18 09:30:29 +000041
Fabian Frederick6edb5682014-06-06 14:38:25 -070042 if (rc)
43 return rc;
Patrick Caulfielde2de7f52006-11-06 08:53:28 +000044 ls = dlm_find_lockspace_local(ls->ls_local_handle);
45 if (!ls)
46 return -EINVAL;
47
David Teiglande7fd4172006-01-18 09:30:29 +000048 switch (n) {
49 case 0:
50 dlm_ls_stop(ls);
51 break;
52 case 1:
53 dlm_ls_start(ls);
54 break;
55 default:
56 ret = -EINVAL;
57 }
Patrick Caulfielde2de7f52006-11-06 08:53:28 +000058 dlm_put_lockspace(ls);
David Teiglande7fd4172006-01-18 09:30:29 +000059 return ret;
60}
61
62static ssize_t dlm_event_store(struct dlm_ls *ls, const char *buf, size_t len)
63{
Fabian Frederick6edb5682014-06-06 14:38:25 -070064 int rc = kstrtoint(buf, 0, &ls->ls_uevent_result);
65
66 if (rc)
67 return rc;
David Teiglande7fd4172006-01-18 09:30:29 +000068 set_bit(LSFL_UEVENT_WAIT, &ls->ls_flags);
69 wake_up(&ls->ls_uevent_wait);
70 return len;
71}
72
73static ssize_t dlm_id_show(struct dlm_ls *ls, char *buf)
74{
David Teiglanda1d144c2006-09-06 17:01:40 -050075 return snprintf(buf, PAGE_SIZE, "%u\n", ls->ls_global_id);
David Teiglande7fd4172006-01-18 09:30:29 +000076}
77
78static ssize_t dlm_id_store(struct dlm_ls *ls, const char *buf, size_t len)
79{
Fabian Frederick6edb5682014-06-06 14:38:25 -070080 int rc = kstrtouint(buf, 0, &ls->ls_global_id);
81
82 if (rc)
83 return rc;
David Teiglande7fd4172006-01-18 09:30:29 +000084 return len;
85}
86
David Teigland48756472012-04-26 15:54:29 -050087static ssize_t dlm_nodir_show(struct dlm_ls *ls, char *buf)
88{
89 return snprintf(buf, PAGE_SIZE, "%u\n", dlm_no_directory(ls));
90}
91
92static ssize_t dlm_nodir_store(struct dlm_ls *ls, const char *buf, size_t len)
93{
Fabian Frederick6edb5682014-06-06 14:38:25 -070094 int val;
95 int rc = kstrtoint(buf, 0, &val);
96
97 if (rc)
98 return rc;
David Teigland48756472012-04-26 15:54:29 -050099 if (val == 1)
100 set_bit(LSFL_NODIR, &ls->ls_flags);
101 return len;
102}
103
David Teiglandc56b39c2006-04-28 10:51:53 -0400104static ssize_t dlm_recover_status_show(struct dlm_ls *ls, char *buf)
105{
106 uint32_t status = dlm_recover_status(ls);
David Teiglanda1d144c2006-09-06 17:01:40 -0500107 return snprintf(buf, PAGE_SIZE, "%x\n", status);
David Teiglandc56b39c2006-04-28 10:51:53 -0400108}
109
David Teiglandfaa0f262006-08-08 17:08:42 -0500110static ssize_t dlm_recover_nodeid_show(struct dlm_ls *ls, char *buf)
111{
David Teiglanda1d144c2006-09-06 17:01:40 -0500112 return snprintf(buf, PAGE_SIZE, "%d\n", ls->ls_recover_nodeid);
David Teiglandfaa0f262006-08-08 17:08:42 -0500113}
114
David Teiglande7fd4172006-01-18 09:30:29 +0000115struct dlm_attr {
116 struct attribute attr;
117 ssize_t (*show)(struct dlm_ls *, char *);
118 ssize_t (*store)(struct dlm_ls *, const char *, size_t);
119};
120
121static struct dlm_attr dlm_attr_control = {
122 .attr = {.name = "control", .mode = S_IWUSR},
123 .store = dlm_control_store
124};
125
126static struct dlm_attr dlm_attr_event = {
127 .attr = {.name = "event_done", .mode = S_IWUSR},
128 .store = dlm_event_store
129};
130
131static struct dlm_attr dlm_attr_id = {
132 .attr = {.name = "id", .mode = S_IRUGO | S_IWUSR},
133 .show = dlm_id_show,
134 .store = dlm_id_store
135};
136
David Teigland48756472012-04-26 15:54:29 -0500137static struct dlm_attr dlm_attr_nodir = {
138 .attr = {.name = "nodir", .mode = S_IRUGO | S_IWUSR},
139 .show = dlm_nodir_show,
140 .store = dlm_nodir_store
141};
142
David Teiglandc56b39c2006-04-28 10:51:53 -0400143static struct dlm_attr dlm_attr_recover_status = {
144 .attr = {.name = "recover_status", .mode = S_IRUGO},
145 .show = dlm_recover_status_show
146};
147
David Teiglandfaa0f262006-08-08 17:08:42 -0500148static struct dlm_attr dlm_attr_recover_nodeid = {
149 .attr = {.name = "recover_nodeid", .mode = S_IRUGO},
150 .show = dlm_recover_nodeid_show
151};
152
David Teiglande7fd4172006-01-18 09:30:29 +0000153static struct attribute *dlm_attrs[] = {
154 &dlm_attr_control.attr,
155 &dlm_attr_event.attr,
156 &dlm_attr_id.attr,
David Teigland48756472012-04-26 15:54:29 -0500157 &dlm_attr_nodir.attr,
David Teiglandc56b39c2006-04-28 10:51:53 -0400158 &dlm_attr_recover_status.attr,
David Teiglandfaa0f262006-08-08 17:08:42 -0500159 &dlm_attr_recover_nodeid.attr,
David Teiglande7fd4172006-01-18 09:30:29 +0000160 NULL,
161};
Kimberly Brownc9c5b5e2019-05-07 21:48:05 -0400162ATTRIBUTE_GROUPS(dlm);
David Teiglande7fd4172006-01-18 09:30:29 +0000163
164static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr,
165 char *buf)
166{
167 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
168 struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);
169 return a->show ? a->show(ls, buf) : 0;
170}
171
172static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr,
173 const char *buf, size_t len)
174{
175 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
176 struct dlm_attr *a = container_of(attr, struct dlm_attr, attr);
177 return a->store ? a->store(ls, buf, len) : len;
178}
179
Patrick Caulfieldba542e32006-11-02 14:41:23 +0000180static void lockspace_kobj_release(struct kobject *k)
181{
182 struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj);
183 kfree(ls);
184}
185
Emese Revfy52cf25d2010-01-19 02:58:23 +0100186static const struct sysfs_ops dlm_attr_ops = {
David Teiglande7fd4172006-01-18 09:30:29 +0000187 .show = dlm_attr_show,
188 .store = dlm_attr_store,
189};
190
191static struct kobj_type dlm_ktype = {
Kimberly Brownc9c5b5e2019-05-07 21:48:05 -0400192 .default_groups = dlm_groups,
David Teiglande7fd4172006-01-18 09:30:29 +0000193 .sysfs_ops = &dlm_attr_ops,
Patrick Caulfieldba542e32006-11-02 14:41:23 +0000194 .release = lockspace_kobj_release,
David Teiglande7fd4172006-01-18 09:30:29 +0000195};
196
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100197static struct kset *dlm_kset;
David Teiglande7fd4172006-01-18 09:30:29 +0000198
David Teiglande7fd4172006-01-18 09:30:29 +0000199static int do_uevent(struct dlm_ls *ls, int in)
200{
David Teiglande7fd4172006-01-18 09:30:29 +0000201 if (in)
202 kobject_uevent(&ls->ls_kobj, KOBJ_ONLINE);
203 else
204 kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);
205
David Teigland075f0172014-02-14 11:54:44 -0600206 log_rinfo(ls, "%s the lockspace group...", in ? "joining" : "leaving");
David Teigland8b0e7b22007-05-18 09:03:35 -0500207
208 /* dlm_controld will see the uevent, do the necessary group management
209 and then write to sysfs to wake us */
210
Ross Lagerwallf084a4f2020-04-29 13:15:41 +0100211 wait_event(ls->ls_uevent_wait,
212 test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
David Teigland8b0e7b22007-05-18 09:03:35 -0500213
Ross Lagerwallf084a4f2020-04-29 13:15:41 +0100214 log_rinfo(ls, "group event done %d", ls->ls_uevent_result);
David Teigland8b0e7b22007-05-18 09:03:35 -0500215
Ross Lagerwallf084a4f2020-04-29 13:15:41 +0100216 return ls->ls_uevent_result;
David Teiglande7fd4172006-01-18 09:30:29 +0000217}
218
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000219static int dlm_uevent(struct kset *kset, struct kobject *kobj,
220 struct kobj_uevent_env *env)
221{
222 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
223
224 add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name);
225 return 0;
226}
227
Bhumika Goyal417f7c52017-07-28 18:49:17 +0530228static const struct kset_uevent_ops dlm_uevent_ops = {
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000229 .uevent = dlm_uevent,
230};
David Teiglande7fd4172006-01-18 09:30:29 +0000231
Denis Cheng30727172008-02-02 01:53:46 +0800232int __init dlm_lockspace_init(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000233{
David Teiglande7fd4172006-01-18 09:30:29 +0000234 ls_count = 0;
David Teigland90135922006-01-20 08:47:07 +0000235 mutex_init(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000236 INIT_LIST_HEAD(&lslist);
237 spin_lock_init(&lslist_lock);
238
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000239 dlm_kset = kset_create_and_add("dlm", &dlm_uevent_ops, kernel_kobj);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100240 if (!dlm_kset) {
Harvey Harrison8e24eea2008-04-30 00:55:09 -0700241 printk(KERN_WARNING "%s: can not create kset\n", __func__);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100242 return -ENOMEM;
243 }
244 return 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000245}
246
247void dlm_lockspace_exit(void)
248{
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100249 kset_unregister(dlm_kset);
David Teiglande7fd4172006-01-18 09:30:29 +0000250}
251
David Teiglandc1dcf652008-08-18 14:03:25 -0500252static struct dlm_ls *find_ls_to_scan(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000253{
254 struct dlm_ls *ls;
255
David Teiglandc1dcf652008-08-18 14:03:25 -0500256 spin_lock(&lslist_lock);
257 list_for_each_entry(ls, &lslist, ls_list) {
258 if (time_after_eq(jiffies, ls->ls_scan_time +
259 dlm_config.ci_scan_secs * HZ)) {
260 spin_unlock(&lslist_lock);
261 return ls;
262 }
263 }
264 spin_unlock(&lslist_lock);
265 return NULL;
266}
267
268static int dlm_scand(void *data)
269{
270 struct dlm_ls *ls;
David Teiglandc1dcf652008-08-18 14:03:25 -0500271
David Teiglande7fd4172006-01-18 09:30:29 +0000272 while (!kthread_should_stop()) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500273 ls = find_ls_to_scan();
274 if (ls) {
David Teigland85e86ed2007-05-18 08:58:15 -0500275 if (dlm_lock_recovery_try(ls)) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500276 ls->ls_scan_time = jiffies;
David Teigland85e86ed2007-05-18 08:58:15 -0500277 dlm_scan_rsbs(ls);
David Teigland3ae1acf2007-05-18 08:59:31 -0500278 dlm_scan_timeout(ls);
David Teiglandc6ff6692011-03-28 14:17:26 -0500279 dlm_scan_waiters(ls);
David Teigland85e86ed2007-05-18 08:58:15 -0500280 dlm_unlock_recovery(ls);
David Teiglandc1dcf652008-08-18 14:03:25 -0500281 } else {
282 ls->ls_scan_time += HZ;
David Teigland85e86ed2007-05-18 08:58:15 -0500283 }
David Teiglandc6ff6692011-03-28 14:17:26 -0500284 continue;
David Teigland85e86ed2007-05-18 08:58:15 -0500285 }
David Teiglandc6ff6692011-03-28 14:17:26 -0500286 schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
David Teiglande7fd4172006-01-18 09:30:29 +0000287 }
288 return 0;
289}
290
291static int dlm_scand_start(void)
292{
293 struct task_struct *p;
294 int error = 0;
295
296 p = kthread_run(dlm_scand, NULL, "dlm_scand");
297 if (IS_ERR(p))
298 error = PTR_ERR(p);
299 else
300 scand_task = p;
301 return error;
302}
303
304static void dlm_scand_stop(void)
305{
306 kthread_stop(scand_task);
307}
308
David Teiglande7fd4172006-01-18 09:30:29 +0000309struct dlm_ls *dlm_find_lockspace_global(uint32_t id)
310{
311 struct dlm_ls *ls;
312
313 spin_lock(&lslist_lock);
314
315 list_for_each_entry(ls, &lslist, ls_list) {
316 if (ls->ls_global_id == id) {
317 ls->ls_count++;
318 goto out;
319 }
320 }
321 ls = NULL;
322 out:
323 spin_unlock(&lslist_lock);
324 return ls;
325}
326
David Teigland597d0ca2006-07-12 16:44:04 -0500327struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000328{
David Teigland597d0ca2006-07-12 16:44:04 -0500329 struct dlm_ls *ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000330
331 spin_lock(&lslist_lock);
David Teigland597d0ca2006-07-12 16:44:04 -0500332 list_for_each_entry(ls, &lslist, ls_list) {
333 if (ls->ls_local_handle == lockspace) {
334 ls->ls_count++;
335 goto out;
336 }
337 }
338 ls = NULL;
339 out:
340 spin_unlock(&lslist_lock);
341 return ls;
342}
343
344struct dlm_ls *dlm_find_lockspace_device(int minor)
345{
346 struct dlm_ls *ls;
347
348 spin_lock(&lslist_lock);
349 list_for_each_entry(ls, &lslist, ls_list) {
350 if (ls->ls_device.minor == minor) {
351 ls->ls_count++;
352 goto out;
353 }
354 }
355 ls = NULL;
356 out:
David Teiglande7fd4172006-01-18 09:30:29 +0000357 spin_unlock(&lslist_lock);
358 return ls;
359}
360
361void dlm_put_lockspace(struct dlm_ls *ls)
362{
363 spin_lock(&lslist_lock);
364 ls->ls_count--;
365 spin_unlock(&lslist_lock);
366}
367
368static void remove_lockspace(struct dlm_ls *ls)
369{
370 for (;;) {
371 spin_lock(&lslist_lock);
372 if (ls->ls_count == 0) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500373 WARN_ON(ls->ls_create_count != 0);
David Teiglande7fd4172006-01-18 09:30:29 +0000374 list_del(&ls->ls_list);
375 spin_unlock(&lslist_lock);
376 return;
377 }
378 spin_unlock(&lslist_lock);
379 ssleep(1);
380 }
381}
382
383static int threads_start(void)
384{
385 int error;
386
David Teiglande7fd4172006-01-18 09:30:29 +0000387 error = dlm_scand_start();
388 if (error) {
389 log_print("cannot start dlm_scand thread %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500390 goto fail;
David Teiglande7fd4172006-01-18 09:30:29 +0000391 }
392
393 /* Thread for sending/receiving messages for all lockspace's */
Alexander Aringa070a912021-05-21 15:08:41 -0400394 error = dlm_midcomms_start();
David Teiglande7fd4172006-01-18 09:30:29 +0000395 if (error) {
396 log_print("cannot start dlm lowcomms %d", error);
397 goto scand_fail;
398 }
399
400 return 0;
401
402 scand_fail:
403 dlm_scand_stop();
David Teiglande7fd4172006-01-18 09:30:29 +0000404 fail:
405 return error;
406}
407
David Teigland60f98d12011-11-02 14:30:58 -0500408static int new_lockspace(const char *name, const char *cluster,
409 uint32_t flags, int lvblen,
410 const struct dlm_lockspace_ops *ops, void *ops_arg,
411 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000412{
413 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500414 int i, size, error;
David Teigland79d72b52007-05-18 09:02:20 -0500415 int do_unreg = 0;
David Teigland60f98d12011-11-02 14:30:58 -0500416 int namelen = strlen(name);
David Teiglande7fd4172006-01-18 09:30:29 +0000417
Tycho Andersen3f0806d2018-11-02 14:18:21 -0600418 if (namelen > DLM_LOCKSPACE_LEN || namelen == 0)
David Teiglande7fd4172006-01-18 09:30:29 +0000419 return -EINVAL;
420
421 if (!lvblen || (lvblen % 8))
422 return -EINVAL;
423
424 if (!try_module_get(THIS_MODULE))
425 return -EINVAL;
426
David Teiglanddc68c7e2008-08-18 11:43:30 -0500427 if (!dlm_user_daemon_available()) {
David Teigland60f98d12011-11-02 14:30:58 -0500428 log_print("dlm user daemon not available");
429 error = -EUNATCH;
430 goto out;
431 }
432
433 if (ops && ops_result) {
434 if (!dlm_config.ci_recover_callbacks)
435 *ops_result = -EOPNOTSUPP;
436 else
437 *ops_result = 0;
438 }
439
Zhu Lingshan3b0e7612017-07-11 09:26:55 -0500440 if (!cluster)
441 log_print("dlm cluster name '%s' is being used without an application provided cluster name",
442 dlm_config.ci_cluster_name);
443
David Teigland60f98d12011-11-02 14:30:58 -0500444 if (dlm_config.ci_recover_callbacks && cluster &&
445 strncmp(cluster, dlm_config.ci_cluster_name, DLM_LOCKSPACE_LEN)) {
Gang He8e174372017-05-18 10:42:12 +0800446 log_print("dlm cluster name '%s' does not match "
447 "the application cluster name '%s'",
David Teigland60f98d12011-11-02 14:30:58 -0500448 dlm_config.ci_cluster_name, cluster);
449 error = -EBADR;
450 goto out;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500451 }
452
David Teigland0f8e0d92008-08-06 13:30:24 -0500453 error = 0;
454
455 spin_lock(&lslist_lock);
456 list_for_each_entry(ls, &lslist, ls_list) {
457 WARN_ON(ls->ls_create_count <= 0);
458 if (ls->ls_namelen != namelen)
459 continue;
460 if (memcmp(ls->ls_name, name, namelen))
461 continue;
462 if (flags & DLM_LSFL_NEWEXCL) {
463 error = -EEXIST;
464 break;
465 }
466 ls->ls_create_count++;
David Teigland8511a272009-04-08 15:38:43 -0500467 *lockspace = ls;
468 error = 1;
David Teigland0f8e0d92008-08-06 13:30:24 -0500469 break;
David Teiglande7fd4172006-01-18 09:30:29 +0000470 }
David Teigland0f8e0d92008-08-06 13:30:24 -0500471 spin_unlock(&lslist_lock);
472
David Teigland0f8e0d92008-08-06 13:30:24 -0500473 if (error)
David Teigland8511a272009-04-08 15:38:43 -0500474 goto out;
David Teigland0f8e0d92008-08-06 13:30:24 -0500475
476 error = -ENOMEM;
David Teiglande7fd4172006-01-18 09:30:29 +0000477
David Teigland573c24c2009-11-30 16:34:43 -0600478 ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000479 if (!ls)
480 goto out;
David Teiglande7fd4172006-01-18 09:30:29 +0000481 memcpy(ls->ls_name, name, namelen);
482 ls->ls_namelen = namelen;
David Teiglande7fd4172006-01-18 09:30:29 +0000483 ls->ls_lvblen = lvblen;
484 ls->ls_count = 0;
485 ls->ls_flags = 0;
David Teiglandc1dcf652008-08-18 14:03:25 -0500486 ls->ls_scan_time = jiffies;
David Teiglande7fd4172006-01-18 09:30:29 +0000487
David Teigland60f98d12011-11-02 14:30:58 -0500488 if (ops && dlm_config.ci_recover_callbacks) {
489 ls->ls_ops = ops;
490 ls->ls_ops_arg = ops_arg;
491 }
492
David Teigland3ae1acf2007-05-18 08:59:31 -0500493 if (flags & DLM_LSFL_TIMEWARN)
494 set_bit(LSFL_TIMEWARN, &ls->ls_flags);
David Teigland3ae1acf2007-05-18 08:59:31 -0500495
David Teiglandfad59c12007-06-11 10:47:18 -0500496 /* ls_exflags are forced to match among nodes, and we don't
David Teigland0f8e0d92008-08-06 13:30:24 -0500497 need to require all nodes to have some flags set */
498 ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
499 DLM_LSFL_NEWEXCL));
David Teiglandfad59c12007-06-11 10:47:18 -0500500
Alexander Aringd921a232021-07-16 16:22:35 -0400501 size = READ_ONCE(dlm_config.ci_rsbtbl_size);
David Teiglande7fd4172006-01-18 09:30:29 +0000502 ls->ls_rsbtbl_size = size;
503
Kees Cook42bc47b2018-06-12 14:27:11 -0700504 ls->ls_rsbtbl = vmalloc(array_size(size, sizeof(struct dlm_rsbtable)));
David Teiglande7fd4172006-01-18 09:30:29 +0000505 if (!ls->ls_rsbtbl)
506 goto out_lsfree;
507 for (i = 0; i < size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500508 ls->ls_rsbtbl[i].keep.rb_node = NULL;
509 ls->ls_rsbtbl[i].toss.rb_node = NULL;
David Teiglandc7be7612009-01-07 16:50:41 -0600510 spin_lock_init(&ls->ls_rsbtbl[i].lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000511 }
512
David Teigland05c32f42012-06-14 12:17:32 -0500513 spin_lock_init(&ls->ls_remove_spin);
514
515 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
516 ls->ls_remove_names[i] = kzalloc(DLM_RESNAME_MAXLEN+1,
517 GFP_KERNEL);
518 if (!ls->ls_remove_names[i])
519 goto out_rsbtbl;
520 }
521
David Teigland3d6aa672011-07-06 17:00:54 -0500522 idr_init(&ls->ls_lkbidr);
523 spin_lock_init(&ls->ls_lkbidr_spin);
David Teiglande7fd4172006-01-18 09:30:29 +0000524
David Teiglande7fd4172006-01-18 09:30:29 +0000525 INIT_LIST_HEAD(&ls->ls_waiters);
David Teigland90135922006-01-20 08:47:07 +0000526 mutex_init(&ls->ls_waiters_mutex);
David Teiglandef0c2bb2007-03-28 09:56:46 -0500527 INIT_LIST_HEAD(&ls->ls_orphans);
528 mutex_init(&ls->ls_orphans_mutex);
David Teigland3ae1acf2007-05-18 08:59:31 -0500529 INIT_LIST_HEAD(&ls->ls_timeout);
530 mutex_init(&ls->ls_timeout_mutex);
David Teiglande7fd4172006-01-18 09:30:29 +0000531
David Teigland3881ac02011-07-07 14:05:03 -0500532 INIT_LIST_HEAD(&ls->ls_new_rsb);
533 spin_lock_init(&ls->ls_new_rsb_spin);
534
David Teiglande7fd4172006-01-18 09:30:29 +0000535 INIT_LIST_HEAD(&ls->ls_nodes);
536 INIT_LIST_HEAD(&ls->ls_nodes_gone);
537 ls->ls_num_nodes = 0;
538 ls->ls_low_nodeid = 0;
539 ls->ls_total_weight = 0;
540 ls->ls_node_array = NULL;
541
542 memset(&ls->ls_stub_rsb, 0, sizeof(struct dlm_rsb));
543 ls->ls_stub_rsb.res_ls = ls;
544
David Teigland5de63192006-07-25 13:44:31 -0500545 ls->ls_debug_rsb_dentry = NULL;
546 ls->ls_debug_waiters_dentry = NULL;
David Teiglande7fd4172006-01-18 09:30:29 +0000547
548 init_waitqueue_head(&ls->ls_uevent_wait);
549 ls->ls_uevent_result = 0;
David Teigland8b0e7b22007-05-18 09:03:35 -0500550 init_completion(&ls->ls_members_done);
551 ls->ls_members_result = -1;
David Teiglande7fd4172006-01-18 09:30:29 +0000552
David Teigland23e8e1a2011-04-05 13:16:24 -0500553 mutex_init(&ls->ls_cb_mutex);
554 INIT_LIST_HEAD(&ls->ls_cb_delay);
555
David Teiglande7fd4172006-01-18 09:30:29 +0000556 ls->ls_recoverd_task = NULL;
David Teigland90135922006-01-20 08:47:07 +0000557 mutex_init(&ls->ls_recoverd_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000558 spin_lock_init(&ls->ls_recover_lock);
David Teigland98f176f2006-11-27 13:19:28 -0600559 spin_lock_init(&ls->ls_rcom_spin);
560 get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t));
David Teiglande7fd4172006-01-18 09:30:29 +0000561 ls->ls_recover_status = 0;
562 ls->ls_recover_seq = 0;
563 ls->ls_recover_args = NULL;
564 init_rwsem(&ls->ls_in_recovery);
David Teiglandc36258b2007-09-27 15:53:38 -0500565 init_rwsem(&ls->ls_recv_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000566 INIT_LIST_HEAD(&ls->ls_requestqueue);
David Teigland90135922006-01-20 08:47:07 +0000567 mutex_init(&ls->ls_requestqueue_mutex);
David Teigland597d0ca2006-07-12 16:44:04 -0500568 mutex_init(&ls->ls_clear_proc_locks);
David Teiglande7fd4172006-01-18 09:30:29 +0000569
Alexander Aring489d8e52021-05-21 15:08:46 -0400570 /* Due backwards compatibility with 3.1 we need to use maximum
571 * possible dlm message size to be sure the message will fit and
572 * not having out of bounds issues. However on sending side 3.2
573 * might send less.
574 */
Alexander Aringd10a0b82021-06-02 09:45:20 -0400575 ls->ls_recover_buf = kmalloc(DLM_MAX_SOCKET_BUFSIZE, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000576 if (!ls->ls_recover_buf)
David Teigland05c32f42012-06-14 12:17:32 -0500577 goto out_lkbidr;
David Teiglande7fd4172006-01-18 09:30:29 +0000578
David Teigland757a4272011-10-20 13:26:28 -0500579 ls->ls_slot = 0;
580 ls->ls_num_slots = 0;
581 ls->ls_slots_size = 0;
582 ls->ls_slots = NULL;
583
David Teiglande7fd4172006-01-18 09:30:29 +0000584 INIT_LIST_HEAD(&ls->ls_recover_list);
585 spin_lock_init(&ls->ls_recover_list_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500586 idr_init(&ls->ls_recover_idr);
587 spin_lock_init(&ls->ls_recover_idr_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000588 ls->ls_recover_list_count = 0;
David Teigland597d0ca2006-07-12 16:44:04 -0500589 ls->ls_local_handle = ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000590 init_waitqueue_head(&ls->ls_wait_general);
591 INIT_LIST_HEAD(&ls->ls_root_list);
592 init_rwsem(&ls->ls_root_sem);
593
David Teigland5f88f1e2006-08-24 14:47:20 -0500594 spin_lock(&lslist_lock);
David Teigland0f8e0d92008-08-06 13:30:24 -0500595 ls->ls_create_count = 1;
David Teigland5f88f1e2006-08-24 14:47:20 -0500596 list_add(&ls->ls_list, &lslist);
597 spin_unlock(&lslist_lock);
598
David Teigland23e8e1a2011-04-05 13:16:24 -0500599 if (flags & DLM_LSFL_FS) {
600 error = dlm_callback_start(ls);
601 if (error) {
602 log_error(ls, "can't start dlm_callback %d", error);
603 goto out_delist;
604 }
605 }
606
David Teigland475f2302012-08-02 11:08:21 -0500607 init_waitqueue_head(&ls->ls_recover_lock_wait);
608
609 /*
610 * Once started, dlm_recoverd first looks for ls in lslist, then
611 * initializes ls_in_recovery as locked in "down" mode. We need
612 * to wait for the wakeup from dlm_recoverd because in_recovery
613 * has to start out in down mode.
614 */
615
David Teiglande7fd4172006-01-18 09:30:29 +0000616 error = dlm_recoverd_start(ls);
617 if (error) {
618 log_error(ls, "can't start dlm_recoverd %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500619 goto out_callback;
David Teiglande7fd4172006-01-18 09:30:29 +0000620 }
621
David Teigland475f2302012-08-02 11:08:21 -0500622 wait_event(ls->ls_recover_lock_wait,
623 test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
624
Wang Hai0ffddaf2020-06-15 11:25:33 +0800625 /* let kobject handle freeing of ls if there's an error */
626 do_unreg = 1;
627
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400628 ls->ls_kobj.kset = dlm_kset;
629 error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
630 "%s", ls->ls_name);
David Teiglande7fd4172006-01-18 09:30:29 +0000631 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500632 goto out_recoverd;
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400633 kobject_uevent(&ls->ls_kobj, KOBJ_ADD);
David Teigland79d72b52007-05-18 09:02:20 -0500634
David Teigland8b0e7b22007-05-18 09:03:35 -0500635 /* This uevent triggers dlm_controld in userspace to add us to the
636 group of nodes that are members of this lockspace (managed by the
637 cluster infrastructure.) Once it's done that, it tells us who the
638 current lockspace members are (via configfs) and then tells the
639 lockspace to start running (via sysfs) in dlm_ls_start(). */
640
David Teiglande7fd4172006-01-18 09:30:29 +0000641 error = do_uevent(ls, 1);
642 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500643 goto out_recoverd;
David Teigland79d72b52007-05-18 09:02:20 -0500644
David Teigland8b0e7b22007-05-18 09:03:35 -0500645 wait_for_completion(&ls->ls_members_done);
646 error = ls->ls_members_result;
647 if (error)
648 goto out_members;
649
David Teigland79d72b52007-05-18 09:02:20 -0500650 dlm_create_debug_file(ls);
651
David Teigland075f0172014-02-14 11:54:44 -0600652 log_rinfo(ls, "join complete");
David Teiglande7fd4172006-01-18 09:30:29 +0000653 *lockspace = ls;
654 return 0;
655
David Teigland8b0e7b22007-05-18 09:03:35 -0500656 out_members:
657 do_uevent(ls, 0);
658 dlm_clear_members(ls);
659 kfree(ls->ls_node_array);
David Teigland23e8e1a2011-04-05 13:16:24 -0500660 out_recoverd:
David Teigland5f88f1e2006-08-24 14:47:20 -0500661 dlm_recoverd_stop(ls);
David Teigland23e8e1a2011-04-05 13:16:24 -0500662 out_callback:
663 dlm_callback_stop(ls);
David Teigland79d72b52007-05-18 09:02:20 -0500664 out_delist:
David Teiglande7fd4172006-01-18 09:30:29 +0000665 spin_lock(&lslist_lock);
666 list_del(&ls->ls_list);
667 spin_unlock(&lslist_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500668 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000669 kfree(ls->ls_recover_buf);
David Teigland05c32f42012-06-14 12:17:32 -0500670 out_lkbidr:
David Teigland3d6aa672011-07-06 17:00:54 -0500671 idr_destroy(&ls->ls_lkbidr);
Vasily Averinb9828962018-11-15 13:15:05 +0300672 out_rsbtbl:
Thomas Meyer34568802018-12-03 10:02:01 -0600673 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
674 kfree(ls->ls_remove_names[i]);
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500675 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000676 out_lsfree:
David Teigland79d72b52007-05-18 09:02:20 -0500677 if (do_unreg)
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800678 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500679 else
680 kfree(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000681 out:
682 module_put(THIS_MODULE);
683 return error;
684}
685
David Teigland60f98d12011-11-02 14:30:58 -0500686int dlm_new_lockspace(const char *name, const char *cluster,
687 uint32_t flags, int lvblen,
688 const struct dlm_lockspace_ops *ops, void *ops_arg,
689 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000690{
691 int error = 0;
692
David Teigland90135922006-01-20 08:47:07 +0000693 mutex_lock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000694 if (!ls_count)
695 error = threads_start();
696 if (error)
697 goto out;
698
David Teigland60f98d12011-11-02 14:30:58 -0500699 error = new_lockspace(name, cluster, flags, lvblen, ops, ops_arg,
700 ops_result, lockspace);
David Teiglande7fd4172006-01-18 09:30:29 +0000701 if (!error)
702 ls_count++;
David Teigland8511a272009-04-08 15:38:43 -0500703 if (error > 0)
704 error = 0;
Alexander Aring9d232462021-03-01 17:05:20 -0500705 if (!ls_count) {
706 dlm_scand_stop();
Alexander Aringa070a912021-05-21 15:08:41 -0400707 dlm_midcomms_shutdown();
Alexander Aring9d232462021-03-01 17:05:20 -0500708 dlm_lowcomms_stop();
709 }
David Teiglande7fd4172006-01-18 09:30:29 +0000710 out:
David Teigland90135922006-01-20 08:47:07 +0000711 mutex_unlock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000712 return error;
713}
714
David Teigland3d6aa672011-07-06 17:00:54 -0500715static int lkb_idr_is_local(int id, void *p, void *data)
David Teiglande7fd4172006-01-18 09:30:29 +0000716{
David Teigland3d6aa672011-07-06 17:00:54 -0500717 struct dlm_lkb *lkb = p;
David Teiglande7fd4172006-01-18 09:30:29 +0000718
Bart Van Asschea97f4a62013-10-16 14:20:25 +0200719 return lkb->lkb_nodeid == 0 && lkb->lkb_grmode != DLM_LOCK_IV;
David Teigland3d6aa672011-07-06 17:00:54 -0500720}
David Teiglande7fd4172006-01-18 09:30:29 +0000721
David Teigland3d6aa672011-07-06 17:00:54 -0500722static int lkb_idr_is_any(int id, void *p, void *data)
723{
724 return 1;
725}
726
727static int lkb_idr_free(int id, void *p, void *data)
728{
729 struct dlm_lkb *lkb = p;
730
David Teigland3d6aa672011-07-06 17:00:54 -0500731 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
732 dlm_free_lvb(lkb->lkb_lvbptr);
733
734 dlm_free_lkb(lkb);
735 return 0;
736}
737
738/* NOTE: We check the lkbidr here rather than the resource table.
739 This is because there may be LKBs queued as ASTs that have been unlinked
740 from their RSBs and are pending deletion once the AST has been delivered */
741
742static int lockspace_busy(struct dlm_ls *ls, int force)
743{
744 int rv;
745
746 spin_lock(&ls->ls_lkbidr_spin);
747 if (force == 0) {
748 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls);
749 } else if (force == 1) {
750 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_local, ls);
751 } else {
752 rv = 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000753 }
David Teigland3d6aa672011-07-06 17:00:54 -0500754 spin_unlock(&ls->ls_lkbidr_spin);
755 return rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000756}
757
758static int release_lockspace(struct dlm_ls *ls, int force)
759{
David Teiglande7fd4172006-01-18 09:30:29 +0000760 struct dlm_rsb *rsb;
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500761 struct rb_node *n;
David Teigland0f8e0d92008-08-06 13:30:24 -0500762 int i, busy, rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000763
David Teigland3d6aa672011-07-06 17:00:54 -0500764 busy = lockspace_busy(ls, force);
David Teigland0f8e0d92008-08-06 13:30:24 -0500765
766 spin_lock(&lslist_lock);
767 if (ls->ls_create_count == 1) {
David Teigland3d6aa672011-07-06 17:00:54 -0500768 if (busy) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500769 rv = -EBUSY;
David Teigland3d6aa672011-07-06 17:00:54 -0500770 } else {
David Teigland0f8e0d92008-08-06 13:30:24 -0500771 /* remove_lockspace takes ls off lslist */
772 ls->ls_create_count = 0;
773 rv = 0;
774 }
775 } else if (ls->ls_create_count > 1) {
776 rv = --ls->ls_create_count;
777 } else {
778 rv = -EINVAL;
779 }
780 spin_unlock(&lslist_lock);
781
782 if (rv) {
783 log_debug(ls, "release_lockspace no remove %d", rv);
784 return rv;
785 }
786
787 dlm_device_deregister(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000788
David Teiglanddc68c7e2008-08-18 11:43:30 -0500789 if (force < 3 && dlm_user_daemon_available())
David Teiglande7fd4172006-01-18 09:30:29 +0000790 do_uevent(ls, 0);
791
792 dlm_recoverd_stop(ls);
793
Alexander Aring9d232462021-03-01 17:05:20 -0500794 if (ls_count == 1) {
795 dlm_scand_stop();
Alexander Aringecd95672021-08-26 10:06:31 -0400796 dlm_clear_members(ls);
Alexander Aringa070a912021-05-21 15:08:41 -0400797 dlm_midcomms_shutdown();
Alexander Aring9d232462021-03-01 17:05:20 -0500798 }
799
David Teigland23e8e1a2011-04-05 13:16:24 -0500800 dlm_callback_stop(ls);
801
David Teiglande7fd4172006-01-18 09:30:29 +0000802 remove_lockspace(ls);
803
804 dlm_delete_debug_file(ls);
805
David Teigland8fc6ed92018-11-15 11:17:40 -0600806 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000807 kfree(ls->ls_recover_buf);
808
809 /*
David Teigland3d6aa672011-07-06 17:00:54 -0500810 * Free all lkb's in idr
David Teiglande7fd4172006-01-18 09:30:29 +0000811 */
812
David Teigland3d6aa672011-07-06 17:00:54 -0500813 idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls);
David Teigland3d6aa672011-07-06 17:00:54 -0500814 idr_destroy(&ls->ls_lkbidr);
David Teiglande7fd4172006-01-18 09:30:29 +0000815
David Teiglande7fd4172006-01-18 09:30:29 +0000816 /*
817 * Free all rsb's on rsbtbl[] lists
818 */
819
820 for (i = 0; i < ls->ls_rsbtbl_size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500821 while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) {
822 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
823 rb_erase(n, &ls->ls_rsbtbl[i].keep);
David Teigland52bda2b2007-11-07 09:06:49 -0600824 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000825 }
826
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500827 while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) {
828 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
829 rb_erase(n, &ls->ls_rsbtbl[i].toss);
David Teigland52bda2b2007-11-07 09:06:49 -0600830 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000831 }
832 }
833
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500834 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000835
David Teigland05c32f42012-06-14 12:17:32 -0500836 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
837 kfree(ls->ls_remove_names[i]);
838
David Teigland3881ac02011-07-07 14:05:03 -0500839 while (!list_empty(&ls->ls_new_rsb)) {
840 rsb = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb,
841 res_hashchain);
842 list_del(&rsb->res_hashchain);
843 dlm_free_rsb(rsb);
844 }
845
David Teiglande7fd4172006-01-18 09:30:29 +0000846 /*
847 * Free structures on any other lists
848 */
849
David Teigland2896ee32006-11-27 11:31:22 -0600850 dlm_purge_requestqueue(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000851 kfree(ls->ls_recover_args);
David Teiglande7fd4172006-01-18 09:30:29 +0000852 dlm_clear_members(ls);
853 dlm_clear_members_gone(ls);
854 kfree(ls->ls_node_array);
David Teigland075f0172014-02-14 11:54:44 -0600855 log_rinfo(ls, "release_lockspace final free");
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800856 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500857 /* The ls structure will be freed when the kobject is done with */
David Teiglande7fd4172006-01-18 09:30:29 +0000858
David Teiglande7fd4172006-01-18 09:30:29 +0000859 module_put(THIS_MODULE);
860 return 0;
861}
862
863/*
864 * Called when a system has released all its locks and is not going to use the
865 * lockspace any longer. We free everything we're managing for this lockspace.
866 * Remaining nodes will go through the recovery process as if we'd died. The
867 * lockspace must continue to function as usual, participating in recoveries,
868 * until this returns.
869 *
870 * Force has 4 possible values:
871 * 0 - don't destroy locksapce if it has any LKBs
872 * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs
873 * 2 - destroy lockspace regardless of LKBs
874 * 3 - destroy lockspace as part of a forced shutdown
875 */
876
877int dlm_release_lockspace(void *lockspace, int force)
878{
879 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500880 int error;
David Teiglande7fd4172006-01-18 09:30:29 +0000881
882 ls = dlm_find_lockspace_local(lockspace);
883 if (!ls)
884 return -EINVAL;
885 dlm_put_lockspace(ls);
David Teigland0f8e0d92008-08-06 13:30:24 -0500886
887 mutex_lock(&ls_lock);
888 error = release_lockspace(ls, force);
889 if (!error)
890 ls_count--;
David Teigland278afcb2008-11-13 13:22:34 -0600891 if (!ls_count)
Alexander Aring9d232462021-03-01 17:05:20 -0500892 dlm_lowcomms_stop();
David Teigland0f8e0d92008-08-06 13:30:24 -0500893 mutex_unlock(&ls_lock);
894
895 return error;
David Teiglande7fd4172006-01-18 09:30:29 +0000896}
897
David Teiglanddc68c7e2008-08-18 11:43:30 -0500898void dlm_stop_lockspaces(void)
899{
900 struct dlm_ls *ls;
David Teigland696b3d82013-06-25 12:48:01 -0500901 int count;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500902
903 restart:
David Teigland696b3d82013-06-25 12:48:01 -0500904 count = 0;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500905 spin_lock(&lslist_lock);
906 list_for_each_entry(ls, &lslist, ls_list) {
David Teigland696b3d82013-06-25 12:48:01 -0500907 if (!test_bit(LSFL_RUNNING, &ls->ls_flags)) {
908 count++;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500909 continue;
David Teigland696b3d82013-06-25 12:48:01 -0500910 }
David Teiglanddc68c7e2008-08-18 11:43:30 -0500911 spin_unlock(&lslist_lock);
912 log_error(ls, "no userland control daemon, stopping lockspace");
913 dlm_ls_stop(ls);
914 goto restart;
915 }
916 spin_unlock(&lslist_lock);
David Teigland696b3d82013-06-25 12:48:01 -0500917
918 if (count)
919 log_print("dlm user daemon left %d lockspaces", count);
David Teiglanddc68c7e2008-08-18 11:43:30 -0500920}
921