blob: 0bbb346cb8924e2dc3d084268e4f0ecd4a751ea1 [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
Greg Kroah-Hartmancf6299b62021-12-27 17:39:24 +0100219static int dlm_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000220{
221 struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
222
223 add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name);
224 return 0;
225}
226
Bhumika Goyal417f7c52017-07-28 18:49:17 +0530227static const struct kset_uevent_ops dlm_uevent_ops = {
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000228 .uevent = dlm_uevent,
229};
David Teiglande7fd4172006-01-18 09:30:29 +0000230
Denis Cheng30727172008-02-02 01:53:46 +0800231int __init dlm_lockspace_init(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000232{
David Teiglande7fd4172006-01-18 09:30:29 +0000233 ls_count = 0;
David Teigland90135922006-01-20 08:47:07 +0000234 mutex_init(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000235 INIT_LIST_HEAD(&lslist);
236 spin_lock_init(&lslist_lock);
237
Steven Whitehouseb4a5d4b2010-02-17 09:41:34 +0000238 dlm_kset = kset_create_and_add("dlm", &dlm_uevent_ops, kernel_kobj);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100239 if (!dlm_kset) {
Harvey Harrison8e24eea2008-04-30 00:55:09 -0700240 printk(KERN_WARNING "%s: can not create kset\n", __func__);
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100241 return -ENOMEM;
242 }
243 return 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000244}
245
246void dlm_lockspace_exit(void)
247{
Greg Kroah-Hartmand4059362007-10-29 20:13:17 +0100248 kset_unregister(dlm_kset);
David Teiglande7fd4172006-01-18 09:30:29 +0000249}
250
David Teiglandc1dcf652008-08-18 14:03:25 -0500251static struct dlm_ls *find_ls_to_scan(void)
David Teiglande7fd4172006-01-18 09:30:29 +0000252{
253 struct dlm_ls *ls;
254
David Teiglandc1dcf652008-08-18 14:03:25 -0500255 spin_lock(&lslist_lock);
256 list_for_each_entry(ls, &lslist, ls_list) {
257 if (time_after_eq(jiffies, ls->ls_scan_time +
258 dlm_config.ci_scan_secs * HZ)) {
259 spin_unlock(&lslist_lock);
260 return ls;
261 }
262 }
263 spin_unlock(&lslist_lock);
264 return NULL;
265}
266
267static int dlm_scand(void *data)
268{
269 struct dlm_ls *ls;
David Teiglandc1dcf652008-08-18 14:03:25 -0500270
David Teiglande7fd4172006-01-18 09:30:29 +0000271 while (!kthread_should_stop()) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500272 ls = find_ls_to_scan();
273 if (ls) {
David Teigland85e86ed2007-05-18 08:58:15 -0500274 if (dlm_lock_recovery_try(ls)) {
David Teiglandc1dcf652008-08-18 14:03:25 -0500275 ls->ls_scan_time = jiffies;
David Teigland85e86ed2007-05-18 08:58:15 -0500276 dlm_scan_rsbs(ls);
David Teigland3ae1acf2007-05-18 08:59:31 -0500277 dlm_scan_timeout(ls);
David Teiglandc6ff6692011-03-28 14:17:26 -0500278 dlm_scan_waiters(ls);
David Teigland85e86ed2007-05-18 08:58:15 -0500279 dlm_unlock_recovery(ls);
David Teiglandc1dcf652008-08-18 14:03:25 -0500280 } else {
281 ls->ls_scan_time += HZ;
David Teigland85e86ed2007-05-18 08:58:15 -0500282 }
David Teiglandc6ff6692011-03-28 14:17:26 -0500283 continue;
David Teigland85e86ed2007-05-18 08:58:15 -0500284 }
David Teiglandc6ff6692011-03-28 14:17:26 -0500285 schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
David Teiglande7fd4172006-01-18 09:30:29 +0000286 }
287 return 0;
288}
289
290static int dlm_scand_start(void)
291{
292 struct task_struct *p;
293 int error = 0;
294
295 p = kthread_run(dlm_scand, NULL, "dlm_scand");
296 if (IS_ERR(p))
297 error = PTR_ERR(p);
298 else
299 scand_task = p;
300 return error;
301}
302
303static void dlm_scand_stop(void)
304{
305 kthread_stop(scand_task);
306}
307
David Teiglande7fd4172006-01-18 09:30:29 +0000308struct dlm_ls *dlm_find_lockspace_global(uint32_t id)
309{
310 struct dlm_ls *ls;
311
312 spin_lock(&lslist_lock);
313
314 list_for_each_entry(ls, &lslist, ls_list) {
315 if (ls->ls_global_id == id) {
316 ls->ls_count++;
317 goto out;
318 }
319 }
320 ls = NULL;
321 out:
322 spin_unlock(&lslist_lock);
323 return ls;
324}
325
David Teigland597d0ca2006-07-12 16:44:04 -0500326struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000327{
David Teigland597d0ca2006-07-12 16:44:04 -0500328 struct dlm_ls *ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000329
330 spin_lock(&lslist_lock);
David Teigland597d0ca2006-07-12 16:44:04 -0500331 list_for_each_entry(ls, &lslist, ls_list) {
332 if (ls->ls_local_handle == lockspace) {
333 ls->ls_count++;
334 goto out;
335 }
336 }
337 ls = NULL;
338 out:
339 spin_unlock(&lslist_lock);
340 return ls;
341}
342
343struct dlm_ls *dlm_find_lockspace_device(int minor)
344{
345 struct dlm_ls *ls;
346
347 spin_lock(&lslist_lock);
348 list_for_each_entry(ls, &lslist, ls_list) {
349 if (ls->ls_device.minor == minor) {
350 ls->ls_count++;
351 goto out;
352 }
353 }
354 ls = NULL;
355 out:
David Teiglande7fd4172006-01-18 09:30:29 +0000356 spin_unlock(&lslist_lock);
357 return ls;
358}
359
360void dlm_put_lockspace(struct dlm_ls *ls)
361{
362 spin_lock(&lslist_lock);
363 ls->ls_count--;
364 spin_unlock(&lslist_lock);
365}
366
367static void remove_lockspace(struct dlm_ls *ls)
368{
369 for (;;) {
370 spin_lock(&lslist_lock);
371 if (ls->ls_count == 0) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500372 WARN_ON(ls->ls_create_count != 0);
David Teiglande7fd4172006-01-18 09:30:29 +0000373 list_del(&ls->ls_list);
374 spin_unlock(&lslist_lock);
375 return;
376 }
377 spin_unlock(&lslist_lock);
378 ssleep(1);
379 }
380}
381
382static int threads_start(void)
383{
384 int error;
385
David Teiglande7fd4172006-01-18 09:30:29 +0000386 error = dlm_scand_start();
387 if (error) {
388 log_print("cannot start dlm_scand thread %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500389 goto fail;
David Teiglande7fd4172006-01-18 09:30:29 +0000390 }
391
392 /* Thread for sending/receiving messages for all lockspace's */
Alexander Aringa070a912021-05-21 15:08:41 -0400393 error = dlm_midcomms_start();
David Teiglande7fd4172006-01-18 09:30:29 +0000394 if (error) {
395 log_print("cannot start dlm lowcomms %d", error);
396 goto scand_fail;
397 }
398
399 return 0;
400
401 scand_fail:
402 dlm_scand_stop();
David Teiglande7fd4172006-01-18 09:30:29 +0000403 fail:
404 return error;
405}
406
David Teigland60f98d12011-11-02 14:30:58 -0500407static int new_lockspace(const char *name, const char *cluster,
408 uint32_t flags, int lvblen,
409 const struct dlm_lockspace_ops *ops, void *ops_arg,
410 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000411{
412 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500413 int i, size, error;
David Teigland79d72b52007-05-18 09:02:20 -0500414 int do_unreg = 0;
David Teigland60f98d12011-11-02 14:30:58 -0500415 int namelen = strlen(name);
David Teiglande7fd4172006-01-18 09:30:29 +0000416
Tycho Andersen3f0806d2018-11-02 14:18:21 -0600417 if (namelen > DLM_LOCKSPACE_LEN || namelen == 0)
David Teiglande7fd4172006-01-18 09:30:29 +0000418 return -EINVAL;
419
420 if (!lvblen || (lvblen % 8))
421 return -EINVAL;
422
423 if (!try_module_get(THIS_MODULE))
424 return -EINVAL;
425
David Teiglanddc68c7e2008-08-18 11:43:30 -0500426 if (!dlm_user_daemon_available()) {
David Teigland60f98d12011-11-02 14:30:58 -0500427 log_print("dlm user daemon not available");
428 error = -EUNATCH;
429 goto out;
430 }
431
432 if (ops && ops_result) {
433 if (!dlm_config.ci_recover_callbacks)
434 *ops_result = -EOPNOTSUPP;
435 else
436 *ops_result = 0;
437 }
438
Zhu Lingshan3b0e7612017-07-11 09:26:55 -0500439 if (!cluster)
440 log_print("dlm cluster name '%s' is being used without an application provided cluster name",
441 dlm_config.ci_cluster_name);
442
David Teigland60f98d12011-11-02 14:30:58 -0500443 if (dlm_config.ci_recover_callbacks && cluster &&
444 strncmp(cluster, dlm_config.ci_cluster_name, DLM_LOCKSPACE_LEN)) {
Gang He8e174372017-05-18 10:42:12 +0800445 log_print("dlm cluster name '%s' does not match "
446 "the application cluster name '%s'",
David Teigland60f98d12011-11-02 14:30:58 -0500447 dlm_config.ci_cluster_name, cluster);
448 error = -EBADR;
449 goto out;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500450 }
451
David Teigland0f8e0d92008-08-06 13:30:24 -0500452 error = 0;
453
454 spin_lock(&lslist_lock);
455 list_for_each_entry(ls, &lslist, ls_list) {
456 WARN_ON(ls->ls_create_count <= 0);
457 if (ls->ls_namelen != namelen)
458 continue;
459 if (memcmp(ls->ls_name, name, namelen))
460 continue;
461 if (flags & DLM_LSFL_NEWEXCL) {
462 error = -EEXIST;
463 break;
464 }
465 ls->ls_create_count++;
David Teigland8511a272009-04-08 15:38:43 -0500466 *lockspace = ls;
467 error = 1;
David Teigland0f8e0d92008-08-06 13:30:24 -0500468 break;
David Teiglande7fd4172006-01-18 09:30:29 +0000469 }
David Teigland0f8e0d92008-08-06 13:30:24 -0500470 spin_unlock(&lslist_lock);
471
David Teigland0f8e0d92008-08-06 13:30:24 -0500472 if (error)
David Teigland8511a272009-04-08 15:38:43 -0500473 goto out;
David Teigland0f8e0d92008-08-06 13:30:24 -0500474
475 error = -ENOMEM;
David Teiglande7fd4172006-01-18 09:30:29 +0000476
David Teigland573c24c2009-11-30 16:34:43 -0600477 ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000478 if (!ls)
479 goto out;
David Teiglande7fd4172006-01-18 09:30:29 +0000480 memcpy(ls->ls_name, name, namelen);
481 ls->ls_namelen = namelen;
David Teiglande7fd4172006-01-18 09:30:29 +0000482 ls->ls_lvblen = lvblen;
483 ls->ls_count = 0;
484 ls->ls_flags = 0;
David Teiglandc1dcf652008-08-18 14:03:25 -0500485 ls->ls_scan_time = jiffies;
David Teiglande7fd4172006-01-18 09:30:29 +0000486
David Teigland60f98d12011-11-02 14:30:58 -0500487 if (ops && dlm_config.ci_recover_callbacks) {
488 ls->ls_ops = ops;
489 ls->ls_ops_arg = ops_arg;
490 }
491
David Teigland3ae1acf2007-05-18 08:59:31 -0500492 if (flags & DLM_LSFL_TIMEWARN)
493 set_bit(LSFL_TIMEWARN, &ls->ls_flags);
David Teigland3ae1acf2007-05-18 08:59:31 -0500494
David Teiglandfad59c12007-06-11 10:47:18 -0500495 /* ls_exflags are forced to match among nodes, and we don't
David Teigland0f8e0d92008-08-06 13:30:24 -0500496 need to require all nodes to have some flags set */
497 ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
498 DLM_LSFL_NEWEXCL));
David Teiglandfad59c12007-06-11 10:47:18 -0500499
Alexander Aringd921a232021-07-16 16:22:35 -0400500 size = READ_ONCE(dlm_config.ci_rsbtbl_size);
David Teiglande7fd4172006-01-18 09:30:29 +0000501 ls->ls_rsbtbl_size = size;
502
Kees Cook42bc47b2018-06-12 14:27:11 -0700503 ls->ls_rsbtbl = vmalloc(array_size(size, sizeof(struct dlm_rsbtable)));
David Teiglande7fd4172006-01-18 09:30:29 +0000504 if (!ls->ls_rsbtbl)
505 goto out_lsfree;
506 for (i = 0; i < size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500507 ls->ls_rsbtbl[i].keep.rb_node = NULL;
508 ls->ls_rsbtbl[i].toss.rb_node = NULL;
David Teiglandc7be7612009-01-07 16:50:41 -0600509 spin_lock_init(&ls->ls_rsbtbl[i].lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000510 }
511
David Teigland05c32f42012-06-14 12:17:32 -0500512 spin_lock_init(&ls->ls_remove_spin);
513
514 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
515 ls->ls_remove_names[i] = kzalloc(DLM_RESNAME_MAXLEN+1,
516 GFP_KERNEL);
517 if (!ls->ls_remove_names[i])
518 goto out_rsbtbl;
519 }
520
David Teigland3d6aa672011-07-06 17:00:54 -0500521 idr_init(&ls->ls_lkbidr);
522 spin_lock_init(&ls->ls_lkbidr_spin);
David Teiglande7fd4172006-01-18 09:30:29 +0000523
David Teiglande7fd4172006-01-18 09:30:29 +0000524 INIT_LIST_HEAD(&ls->ls_waiters);
David Teigland90135922006-01-20 08:47:07 +0000525 mutex_init(&ls->ls_waiters_mutex);
David Teiglandef0c2bb2007-03-28 09:56:46 -0500526 INIT_LIST_HEAD(&ls->ls_orphans);
527 mutex_init(&ls->ls_orphans_mutex);
David Teigland3ae1acf2007-05-18 08:59:31 -0500528 INIT_LIST_HEAD(&ls->ls_timeout);
529 mutex_init(&ls->ls_timeout_mutex);
David Teiglande7fd4172006-01-18 09:30:29 +0000530
David Teigland3881ac02011-07-07 14:05:03 -0500531 INIT_LIST_HEAD(&ls->ls_new_rsb);
532 spin_lock_init(&ls->ls_new_rsb_spin);
533
David Teiglande7fd4172006-01-18 09:30:29 +0000534 INIT_LIST_HEAD(&ls->ls_nodes);
535 INIT_LIST_HEAD(&ls->ls_nodes_gone);
536 ls->ls_num_nodes = 0;
537 ls->ls_low_nodeid = 0;
538 ls->ls_total_weight = 0;
539 ls->ls_node_array = NULL;
540
541 memset(&ls->ls_stub_rsb, 0, sizeof(struct dlm_rsb));
542 ls->ls_stub_rsb.res_ls = ls;
543
David Teigland5de63192006-07-25 13:44:31 -0500544 ls->ls_debug_rsb_dentry = NULL;
545 ls->ls_debug_waiters_dentry = NULL;
David Teiglande7fd4172006-01-18 09:30:29 +0000546
547 init_waitqueue_head(&ls->ls_uevent_wait);
548 ls->ls_uevent_result = 0;
David Teigland8b0e7b22007-05-18 09:03:35 -0500549 init_completion(&ls->ls_members_done);
550 ls->ls_members_result = -1;
David Teiglande7fd4172006-01-18 09:30:29 +0000551
David Teigland23e8e1a2011-04-05 13:16:24 -0500552 mutex_init(&ls->ls_cb_mutex);
553 INIT_LIST_HEAD(&ls->ls_cb_delay);
554
David Teiglande7fd4172006-01-18 09:30:29 +0000555 ls->ls_recoverd_task = NULL;
David Teigland90135922006-01-20 08:47:07 +0000556 mutex_init(&ls->ls_recoverd_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000557 spin_lock_init(&ls->ls_recover_lock);
David Teigland98f176f2006-11-27 13:19:28 -0600558 spin_lock_init(&ls->ls_rcom_spin);
559 get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t));
David Teiglande7fd4172006-01-18 09:30:29 +0000560 ls->ls_recover_status = 0;
561 ls->ls_recover_seq = 0;
562 ls->ls_recover_args = NULL;
563 init_rwsem(&ls->ls_in_recovery);
David Teiglandc36258b2007-09-27 15:53:38 -0500564 init_rwsem(&ls->ls_recv_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000565 INIT_LIST_HEAD(&ls->ls_requestqueue);
David Teigland90135922006-01-20 08:47:07 +0000566 mutex_init(&ls->ls_requestqueue_mutex);
David Teigland597d0ca2006-07-12 16:44:04 -0500567 mutex_init(&ls->ls_clear_proc_locks);
David Teiglande7fd4172006-01-18 09:30:29 +0000568
Alexander Aring489d8e52021-05-21 15:08:46 -0400569 /* Due backwards compatibility with 3.1 we need to use maximum
570 * possible dlm message size to be sure the message will fit and
571 * not having out of bounds issues. However on sending side 3.2
572 * might send less.
573 */
Alexander Aringd10a0b82021-06-02 09:45:20 -0400574 ls->ls_recover_buf = kmalloc(DLM_MAX_SOCKET_BUFSIZE, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000575 if (!ls->ls_recover_buf)
David Teigland05c32f42012-06-14 12:17:32 -0500576 goto out_lkbidr;
David Teiglande7fd4172006-01-18 09:30:29 +0000577
David Teigland757a4272011-10-20 13:26:28 -0500578 ls->ls_slot = 0;
579 ls->ls_num_slots = 0;
580 ls->ls_slots_size = 0;
581 ls->ls_slots = NULL;
582
David Teiglande7fd4172006-01-18 09:30:29 +0000583 INIT_LIST_HEAD(&ls->ls_recover_list);
584 spin_lock_init(&ls->ls_recover_list_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500585 idr_init(&ls->ls_recover_idr);
586 spin_lock_init(&ls->ls_recover_idr_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000587 ls->ls_recover_list_count = 0;
David Teigland597d0ca2006-07-12 16:44:04 -0500588 ls->ls_local_handle = ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000589 init_waitqueue_head(&ls->ls_wait_general);
590 INIT_LIST_HEAD(&ls->ls_root_list);
591 init_rwsem(&ls->ls_root_sem);
592
David Teigland5f88f1e2006-08-24 14:47:20 -0500593 spin_lock(&lslist_lock);
David Teigland0f8e0d92008-08-06 13:30:24 -0500594 ls->ls_create_count = 1;
David Teigland5f88f1e2006-08-24 14:47:20 -0500595 list_add(&ls->ls_list, &lslist);
596 spin_unlock(&lslist_lock);
597
David Teigland23e8e1a2011-04-05 13:16:24 -0500598 if (flags & DLM_LSFL_FS) {
599 error = dlm_callback_start(ls);
600 if (error) {
601 log_error(ls, "can't start dlm_callback %d", error);
602 goto out_delist;
603 }
604 }
605
David Teigland475f2302012-08-02 11:08:21 -0500606 init_waitqueue_head(&ls->ls_recover_lock_wait);
607
608 /*
609 * Once started, dlm_recoverd first looks for ls in lslist, then
610 * initializes ls_in_recovery as locked in "down" mode. We need
611 * to wait for the wakeup from dlm_recoverd because in_recovery
612 * has to start out in down mode.
613 */
614
David Teiglande7fd4172006-01-18 09:30:29 +0000615 error = dlm_recoverd_start(ls);
616 if (error) {
617 log_error(ls, "can't start dlm_recoverd %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500618 goto out_callback;
David Teiglande7fd4172006-01-18 09:30:29 +0000619 }
620
David Teigland475f2302012-08-02 11:08:21 -0500621 wait_event(ls->ls_recover_lock_wait,
622 test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
623
Wang Hai0ffddaf2020-06-15 11:25:33 +0800624 /* let kobject handle freeing of ls if there's an error */
625 do_unreg = 1;
626
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400627 ls->ls_kobj.kset = dlm_kset;
628 error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
629 "%s", ls->ls_name);
David Teiglande7fd4172006-01-18 09:30:29 +0000630 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500631 goto out_recoverd;
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400632 kobject_uevent(&ls->ls_kobj, KOBJ_ADD);
David Teigland79d72b52007-05-18 09:02:20 -0500633
David Teigland8b0e7b22007-05-18 09:03:35 -0500634 /* This uevent triggers dlm_controld in userspace to add us to the
635 group of nodes that are members of this lockspace (managed by the
636 cluster infrastructure.) Once it's done that, it tells us who the
637 current lockspace members are (via configfs) and then tells the
638 lockspace to start running (via sysfs) in dlm_ls_start(). */
639
David Teiglande7fd4172006-01-18 09:30:29 +0000640 error = do_uevent(ls, 1);
641 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500642 goto out_recoverd;
David Teigland79d72b52007-05-18 09:02:20 -0500643
David Teigland8b0e7b22007-05-18 09:03:35 -0500644 wait_for_completion(&ls->ls_members_done);
645 error = ls->ls_members_result;
646 if (error)
647 goto out_members;
648
David Teigland79d72b52007-05-18 09:02:20 -0500649 dlm_create_debug_file(ls);
650
David Teigland075f0172014-02-14 11:54:44 -0600651 log_rinfo(ls, "join complete");
David Teiglande7fd4172006-01-18 09:30:29 +0000652 *lockspace = ls;
653 return 0;
654
David Teigland8b0e7b22007-05-18 09:03:35 -0500655 out_members:
656 do_uevent(ls, 0);
657 dlm_clear_members(ls);
658 kfree(ls->ls_node_array);
David Teigland23e8e1a2011-04-05 13:16:24 -0500659 out_recoverd:
David Teigland5f88f1e2006-08-24 14:47:20 -0500660 dlm_recoverd_stop(ls);
David Teigland23e8e1a2011-04-05 13:16:24 -0500661 out_callback:
662 dlm_callback_stop(ls);
David Teigland79d72b52007-05-18 09:02:20 -0500663 out_delist:
David Teiglande7fd4172006-01-18 09:30:29 +0000664 spin_lock(&lslist_lock);
665 list_del(&ls->ls_list);
666 spin_unlock(&lslist_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500667 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000668 kfree(ls->ls_recover_buf);
David Teigland05c32f42012-06-14 12:17:32 -0500669 out_lkbidr:
David Teigland3d6aa672011-07-06 17:00:54 -0500670 idr_destroy(&ls->ls_lkbidr);
Vasily Averinb9828962018-11-15 13:15:05 +0300671 out_rsbtbl:
Thomas Meyer34568802018-12-03 10:02:01 -0600672 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
673 kfree(ls->ls_remove_names[i]);
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500674 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000675 out_lsfree:
David Teigland79d72b52007-05-18 09:02:20 -0500676 if (do_unreg)
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800677 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500678 else
679 kfree(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000680 out:
681 module_put(THIS_MODULE);
682 return error;
683}
684
David Teigland60f98d12011-11-02 14:30:58 -0500685int dlm_new_lockspace(const char *name, const char *cluster,
686 uint32_t flags, int lvblen,
687 const struct dlm_lockspace_ops *ops, void *ops_arg,
688 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000689{
690 int error = 0;
691
David Teigland90135922006-01-20 08:47:07 +0000692 mutex_lock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000693 if (!ls_count)
694 error = threads_start();
695 if (error)
696 goto out;
697
David Teigland60f98d12011-11-02 14:30:58 -0500698 error = new_lockspace(name, cluster, flags, lvblen, ops, ops_arg,
699 ops_result, lockspace);
David Teiglande7fd4172006-01-18 09:30:29 +0000700 if (!error)
701 ls_count++;
David Teigland8511a272009-04-08 15:38:43 -0500702 if (error > 0)
703 error = 0;
Alexander Aring9d232462021-03-01 17:05:20 -0500704 if (!ls_count) {
705 dlm_scand_stop();
Alexander Aringa070a912021-05-21 15:08:41 -0400706 dlm_midcomms_shutdown();
Alexander Aring9d232462021-03-01 17:05:20 -0500707 dlm_lowcomms_stop();
708 }
David Teiglande7fd4172006-01-18 09:30:29 +0000709 out:
David Teigland90135922006-01-20 08:47:07 +0000710 mutex_unlock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000711 return error;
712}
713
David Teigland3d6aa672011-07-06 17:00:54 -0500714static int lkb_idr_is_local(int id, void *p, void *data)
David Teiglande7fd4172006-01-18 09:30:29 +0000715{
David Teigland3d6aa672011-07-06 17:00:54 -0500716 struct dlm_lkb *lkb = p;
David Teiglande7fd4172006-01-18 09:30:29 +0000717
Bart Van Asschea97f4a62013-10-16 14:20:25 +0200718 return lkb->lkb_nodeid == 0 && lkb->lkb_grmode != DLM_LOCK_IV;
David Teigland3d6aa672011-07-06 17:00:54 -0500719}
David Teiglande7fd4172006-01-18 09:30:29 +0000720
David Teigland3d6aa672011-07-06 17:00:54 -0500721static int lkb_idr_is_any(int id, void *p, void *data)
722{
723 return 1;
724}
725
726static int lkb_idr_free(int id, void *p, void *data)
727{
728 struct dlm_lkb *lkb = p;
729
David Teigland3d6aa672011-07-06 17:00:54 -0500730 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
731 dlm_free_lvb(lkb->lkb_lvbptr);
732
733 dlm_free_lkb(lkb);
734 return 0;
735}
736
737/* NOTE: We check the lkbidr here rather than the resource table.
738 This is because there may be LKBs queued as ASTs that have been unlinked
739 from their RSBs and are pending deletion once the AST has been delivered */
740
741static int lockspace_busy(struct dlm_ls *ls, int force)
742{
743 int rv;
744
745 spin_lock(&ls->ls_lkbidr_spin);
746 if (force == 0) {
747 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls);
748 } else if (force == 1) {
749 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_local, ls);
750 } else {
751 rv = 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000752 }
David Teigland3d6aa672011-07-06 17:00:54 -0500753 spin_unlock(&ls->ls_lkbidr_spin);
754 return rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000755}
756
757static int release_lockspace(struct dlm_ls *ls, int force)
758{
David Teiglande7fd4172006-01-18 09:30:29 +0000759 struct dlm_rsb *rsb;
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500760 struct rb_node *n;
David Teigland0f8e0d92008-08-06 13:30:24 -0500761 int i, busy, rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000762
David Teigland3d6aa672011-07-06 17:00:54 -0500763 busy = lockspace_busy(ls, force);
David Teigland0f8e0d92008-08-06 13:30:24 -0500764
765 spin_lock(&lslist_lock);
766 if (ls->ls_create_count == 1) {
David Teigland3d6aa672011-07-06 17:00:54 -0500767 if (busy) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500768 rv = -EBUSY;
David Teigland3d6aa672011-07-06 17:00:54 -0500769 } else {
David Teigland0f8e0d92008-08-06 13:30:24 -0500770 /* remove_lockspace takes ls off lslist */
771 ls->ls_create_count = 0;
772 rv = 0;
773 }
774 } else if (ls->ls_create_count > 1) {
775 rv = --ls->ls_create_count;
776 } else {
777 rv = -EINVAL;
778 }
779 spin_unlock(&lslist_lock);
780
781 if (rv) {
782 log_debug(ls, "release_lockspace no remove %d", rv);
783 return rv;
784 }
785
786 dlm_device_deregister(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000787
David Teiglanddc68c7e2008-08-18 11:43:30 -0500788 if (force < 3 && dlm_user_daemon_available())
David Teiglande7fd4172006-01-18 09:30:29 +0000789 do_uevent(ls, 0);
790
791 dlm_recoverd_stop(ls);
792
Alexander Aring9d232462021-03-01 17:05:20 -0500793 if (ls_count == 1) {
794 dlm_scand_stop();
Alexander Aringecd95672021-08-26 10:06:31 -0400795 dlm_clear_members(ls);
Alexander Aringa070a912021-05-21 15:08:41 -0400796 dlm_midcomms_shutdown();
Alexander Aring9d232462021-03-01 17:05:20 -0500797 }
798
David Teigland23e8e1a2011-04-05 13:16:24 -0500799 dlm_callback_stop(ls);
800
David Teiglande7fd4172006-01-18 09:30:29 +0000801 remove_lockspace(ls);
802
803 dlm_delete_debug_file(ls);
804
David Teigland8fc6ed92018-11-15 11:17:40 -0600805 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000806 kfree(ls->ls_recover_buf);
807
808 /*
David Teigland3d6aa672011-07-06 17:00:54 -0500809 * Free all lkb's in idr
David Teiglande7fd4172006-01-18 09:30:29 +0000810 */
811
David Teigland3d6aa672011-07-06 17:00:54 -0500812 idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls);
David Teigland3d6aa672011-07-06 17:00:54 -0500813 idr_destroy(&ls->ls_lkbidr);
David Teiglande7fd4172006-01-18 09:30:29 +0000814
David Teiglande7fd4172006-01-18 09:30:29 +0000815 /*
816 * Free all rsb's on rsbtbl[] lists
817 */
818
819 for (i = 0; i < ls->ls_rsbtbl_size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500820 while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) {
821 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
822 rb_erase(n, &ls->ls_rsbtbl[i].keep);
David Teigland52bda2b2007-11-07 09:06:49 -0600823 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000824 }
825
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500826 while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) {
827 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
828 rb_erase(n, &ls->ls_rsbtbl[i].toss);
David Teigland52bda2b2007-11-07 09:06:49 -0600829 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000830 }
831 }
832
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500833 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000834
David Teigland05c32f42012-06-14 12:17:32 -0500835 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
836 kfree(ls->ls_remove_names[i]);
837
David Teigland3881ac02011-07-07 14:05:03 -0500838 while (!list_empty(&ls->ls_new_rsb)) {
839 rsb = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb,
840 res_hashchain);
841 list_del(&rsb->res_hashchain);
842 dlm_free_rsb(rsb);
843 }
844
David Teiglande7fd4172006-01-18 09:30:29 +0000845 /*
846 * Free structures on any other lists
847 */
848
David Teigland2896ee32006-11-27 11:31:22 -0600849 dlm_purge_requestqueue(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000850 kfree(ls->ls_recover_args);
David Teiglande7fd4172006-01-18 09:30:29 +0000851 dlm_clear_members(ls);
852 dlm_clear_members_gone(ls);
853 kfree(ls->ls_node_array);
David Teigland075f0172014-02-14 11:54:44 -0600854 log_rinfo(ls, "release_lockspace final free");
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800855 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500856 /* The ls structure will be freed when the kobject is done with */
David Teiglande7fd4172006-01-18 09:30:29 +0000857
David Teiglande7fd4172006-01-18 09:30:29 +0000858 module_put(THIS_MODULE);
859 return 0;
860}
861
862/*
863 * Called when a system has released all its locks and is not going to use the
864 * lockspace any longer. We free everything we're managing for this lockspace.
865 * Remaining nodes will go through the recovery process as if we'd died. The
866 * lockspace must continue to function as usual, participating in recoveries,
867 * until this returns.
868 *
869 * Force has 4 possible values:
870 * 0 - don't destroy locksapce if it has any LKBs
871 * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs
872 * 2 - destroy lockspace regardless of LKBs
873 * 3 - destroy lockspace as part of a forced shutdown
874 */
875
876int dlm_release_lockspace(void *lockspace, int force)
877{
878 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500879 int error;
David Teiglande7fd4172006-01-18 09:30:29 +0000880
881 ls = dlm_find_lockspace_local(lockspace);
882 if (!ls)
883 return -EINVAL;
884 dlm_put_lockspace(ls);
David Teigland0f8e0d92008-08-06 13:30:24 -0500885
886 mutex_lock(&ls_lock);
887 error = release_lockspace(ls, force);
888 if (!error)
889 ls_count--;
David Teigland278afcb2008-11-13 13:22:34 -0600890 if (!ls_count)
Alexander Aring9d232462021-03-01 17:05:20 -0500891 dlm_lowcomms_stop();
David Teigland0f8e0d92008-08-06 13:30:24 -0500892 mutex_unlock(&ls_lock);
893
894 return error;
David Teiglande7fd4172006-01-18 09:30:29 +0000895}
896
David Teiglanddc68c7e2008-08-18 11:43:30 -0500897void dlm_stop_lockspaces(void)
898{
899 struct dlm_ls *ls;
David Teigland696b3d82013-06-25 12:48:01 -0500900 int count;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500901
902 restart:
David Teigland696b3d82013-06-25 12:48:01 -0500903 count = 0;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500904 spin_lock(&lslist_lock);
905 list_for_each_entry(ls, &lslist, ls_list) {
David Teigland696b3d82013-06-25 12:48:01 -0500906 if (!test_bit(LSFL_RUNNING, &ls->ls_flags)) {
907 count++;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500908 continue;
David Teigland696b3d82013-06-25 12:48:01 -0500909 }
David Teiglanddc68c7e2008-08-18 11:43:30 -0500910 spin_unlock(&lslist_lock);
911 log_error(ls, "no userland control daemon, stopping lockspace");
912 dlm_ls_stop(ls);
913 goto restart;
914 }
915 spin_unlock(&lslist_lock);
David Teigland696b3d82013-06-25 12:48:01 -0500916
917 if (count)
918 log_print("dlm user daemon left %d lockspaces", count);
David Teiglanddc68c7e2008-08-18 11:43:30 -0500919}
920