blob: 0d3833a124a393c5dc987d1d383a9b97d9579ef2 [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) {
Alexander Aring3cb59772021-11-02 15:17:18 -0400316 atomic_inc(&ls->ls_count);
David Teiglande7fd4172006-01-18 09:30:29 +0000317 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) {
Alexander Aring3cb59772021-11-02 15:17:18 -0400333 atomic_inc(&ls->ls_count);
David Teigland597d0ca2006-07-12 16:44:04 -0500334 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) {
Alexander Aring3cb59772021-11-02 15:17:18 -0400350 atomic_inc(&ls->ls_count);
David Teigland597d0ca2006-07-12 16:44:04 -0500351 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{
Alexander Aring3cb59772021-11-02 15:17:18 -0400362 if (atomic_dec_and_test(&ls->ls_count))
363 wake_up(&ls->ls_count_wait);
David Teiglande7fd4172006-01-18 09:30:29 +0000364}
365
366static void remove_lockspace(struct dlm_ls *ls)
367{
Alexander Aring3cb59772021-11-02 15:17:18 -0400368retry:
369 wait_event(ls->ls_count_wait, atomic_read(&ls->ls_count) == 0);
370
371 spin_lock(&lslist_lock);
372 if (atomic_read(&ls->ls_count) != 0) {
David Teiglande7fd4172006-01-18 09:30:29 +0000373 spin_unlock(&lslist_lock);
Alexander Aring3cb59772021-11-02 15:17:18 -0400374 goto retry;
David Teiglande7fd4172006-01-18 09:30:29 +0000375 }
Alexander Aring3cb59772021-11-02 15:17:18 -0400376
377 WARN_ON(ls->ls_create_count != 0);
378 list_del(&ls->ls_list);
379 spin_unlock(&lslist_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000380}
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;
Alexander Aring3cb59772021-11-02 15:17:18 -0400483 atomic_set(&ls->ls_count, 0);
484 init_waitqueue_head(&ls->ls_count_wait);
David Teiglande7fd4172006-01-18 09:30:29 +0000485 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);
Alexander Aring21d9ac1a2021-11-30 14:47:16 -0500514 init_waitqueue_head(&ls->ls_remove_wait);
David Teigland05c32f42012-06-14 12:17:32 -0500515
516 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
517 ls->ls_remove_names[i] = kzalloc(DLM_RESNAME_MAXLEN+1,
518 GFP_KERNEL);
519 if (!ls->ls_remove_names[i])
520 goto out_rsbtbl;
521 }
522
David Teigland3d6aa672011-07-06 17:00:54 -0500523 idr_init(&ls->ls_lkbidr);
524 spin_lock_init(&ls->ls_lkbidr_spin);
David Teiglande7fd4172006-01-18 09:30:29 +0000525
David Teiglande7fd4172006-01-18 09:30:29 +0000526 INIT_LIST_HEAD(&ls->ls_waiters);
David Teigland90135922006-01-20 08:47:07 +0000527 mutex_init(&ls->ls_waiters_mutex);
David Teiglandef0c2bb2007-03-28 09:56:46 -0500528 INIT_LIST_HEAD(&ls->ls_orphans);
529 mutex_init(&ls->ls_orphans_mutex);
David Teigland3ae1acf2007-05-18 08:59:31 -0500530 INIT_LIST_HEAD(&ls->ls_timeout);
531 mutex_init(&ls->ls_timeout_mutex);
David Teiglande7fd4172006-01-18 09:30:29 +0000532
David Teigland3881ac02011-07-07 14:05:03 -0500533 INIT_LIST_HEAD(&ls->ls_new_rsb);
534 spin_lock_init(&ls->ls_new_rsb_spin);
535
David Teiglande7fd4172006-01-18 09:30:29 +0000536 INIT_LIST_HEAD(&ls->ls_nodes);
537 INIT_LIST_HEAD(&ls->ls_nodes_gone);
538 ls->ls_num_nodes = 0;
539 ls->ls_low_nodeid = 0;
540 ls->ls_total_weight = 0;
541 ls->ls_node_array = NULL;
542
543 memset(&ls->ls_stub_rsb, 0, sizeof(struct dlm_rsb));
544 ls->ls_stub_rsb.res_ls = ls;
545
David Teigland5de63192006-07-25 13:44:31 -0500546 ls->ls_debug_rsb_dentry = NULL;
547 ls->ls_debug_waiters_dentry = NULL;
David Teiglande7fd4172006-01-18 09:30:29 +0000548
549 init_waitqueue_head(&ls->ls_uevent_wait);
550 ls->ls_uevent_result = 0;
David Teigland8b0e7b22007-05-18 09:03:35 -0500551 init_completion(&ls->ls_members_done);
552 ls->ls_members_result = -1;
David Teiglande7fd4172006-01-18 09:30:29 +0000553
David Teigland23e8e1a2011-04-05 13:16:24 -0500554 mutex_init(&ls->ls_cb_mutex);
555 INIT_LIST_HEAD(&ls->ls_cb_delay);
556
David Teiglande7fd4172006-01-18 09:30:29 +0000557 ls->ls_recoverd_task = NULL;
David Teigland90135922006-01-20 08:47:07 +0000558 mutex_init(&ls->ls_recoverd_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000559 spin_lock_init(&ls->ls_recover_lock);
David Teigland98f176f2006-11-27 13:19:28 -0600560 spin_lock_init(&ls->ls_rcom_spin);
561 get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t));
David Teiglande7fd4172006-01-18 09:30:29 +0000562 ls->ls_recover_status = 0;
563 ls->ls_recover_seq = 0;
564 ls->ls_recover_args = NULL;
565 init_rwsem(&ls->ls_in_recovery);
David Teiglandc36258b2007-09-27 15:53:38 -0500566 init_rwsem(&ls->ls_recv_active);
David Teiglande7fd4172006-01-18 09:30:29 +0000567 INIT_LIST_HEAD(&ls->ls_requestqueue);
Alexander Aring164d88a2021-11-02 15:17:17 -0400568 atomic_set(&ls->ls_requestqueue_cnt, 0);
569 init_waitqueue_head(&ls->ls_requestqueue_wait);
David Teigland90135922006-01-20 08:47:07 +0000570 mutex_init(&ls->ls_requestqueue_mutex);
David Teigland597d0ca2006-07-12 16:44:04 -0500571 mutex_init(&ls->ls_clear_proc_locks);
David Teiglande7fd4172006-01-18 09:30:29 +0000572
Alexander Aring489d8e52021-05-21 15:08:46 -0400573 /* Due backwards compatibility with 3.1 we need to use maximum
574 * possible dlm message size to be sure the message will fit and
575 * not having out of bounds issues. However on sending side 3.2
576 * might send less.
577 */
Alexander Aringd10a0b82021-06-02 09:45:20 -0400578 ls->ls_recover_buf = kmalloc(DLM_MAX_SOCKET_BUFSIZE, GFP_NOFS);
David Teiglande7fd4172006-01-18 09:30:29 +0000579 if (!ls->ls_recover_buf)
David Teigland05c32f42012-06-14 12:17:32 -0500580 goto out_lkbidr;
David Teiglande7fd4172006-01-18 09:30:29 +0000581
David Teigland757a4272011-10-20 13:26:28 -0500582 ls->ls_slot = 0;
583 ls->ls_num_slots = 0;
584 ls->ls_slots_size = 0;
585 ls->ls_slots = NULL;
586
David Teiglande7fd4172006-01-18 09:30:29 +0000587 INIT_LIST_HEAD(&ls->ls_recover_list);
588 spin_lock_init(&ls->ls_recover_list_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500589 idr_init(&ls->ls_recover_idr);
590 spin_lock_init(&ls->ls_recover_idr_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000591 ls->ls_recover_list_count = 0;
David Teigland597d0ca2006-07-12 16:44:04 -0500592 ls->ls_local_handle = ls;
David Teiglande7fd4172006-01-18 09:30:29 +0000593 init_waitqueue_head(&ls->ls_wait_general);
594 INIT_LIST_HEAD(&ls->ls_root_list);
595 init_rwsem(&ls->ls_root_sem);
596
David Teigland5f88f1e2006-08-24 14:47:20 -0500597 spin_lock(&lslist_lock);
David Teigland0f8e0d92008-08-06 13:30:24 -0500598 ls->ls_create_count = 1;
David Teigland5f88f1e2006-08-24 14:47:20 -0500599 list_add(&ls->ls_list, &lslist);
600 spin_unlock(&lslist_lock);
601
David Teigland23e8e1a2011-04-05 13:16:24 -0500602 if (flags & DLM_LSFL_FS) {
603 error = dlm_callback_start(ls);
604 if (error) {
605 log_error(ls, "can't start dlm_callback %d", error);
606 goto out_delist;
607 }
608 }
609
David Teigland475f2302012-08-02 11:08:21 -0500610 init_waitqueue_head(&ls->ls_recover_lock_wait);
611
612 /*
613 * Once started, dlm_recoverd first looks for ls in lslist, then
614 * initializes ls_in_recovery as locked in "down" mode. We need
615 * to wait for the wakeup from dlm_recoverd because in_recovery
616 * has to start out in down mode.
617 */
618
David Teiglande7fd4172006-01-18 09:30:29 +0000619 error = dlm_recoverd_start(ls);
620 if (error) {
621 log_error(ls, "can't start dlm_recoverd %d", error);
David Teigland23e8e1a2011-04-05 13:16:24 -0500622 goto out_callback;
David Teiglande7fd4172006-01-18 09:30:29 +0000623 }
624
David Teigland475f2302012-08-02 11:08:21 -0500625 wait_event(ls->ls_recover_lock_wait,
626 test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
627
Wang Hai0ffddaf2020-06-15 11:25:33 +0800628 /* let kobject handle freeing of ls if there's an error */
629 do_unreg = 1;
630
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400631 ls->ls_kobj.kset = dlm_kset;
632 error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
633 "%s", ls->ls_name);
David Teiglande7fd4172006-01-18 09:30:29 +0000634 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500635 goto out_recoverd;
Greg Kroah-Hartman901195e2007-12-17 15:54:39 -0400636 kobject_uevent(&ls->ls_kobj, KOBJ_ADD);
David Teigland79d72b52007-05-18 09:02:20 -0500637
David Teigland8b0e7b22007-05-18 09:03:35 -0500638 /* This uevent triggers dlm_controld in userspace to add us to the
639 group of nodes that are members of this lockspace (managed by the
640 cluster infrastructure.) Once it's done that, it tells us who the
641 current lockspace members are (via configfs) and then tells the
642 lockspace to start running (via sysfs) in dlm_ls_start(). */
643
David Teiglande7fd4172006-01-18 09:30:29 +0000644 error = do_uevent(ls, 1);
645 if (error)
David Teigland23e8e1a2011-04-05 13:16:24 -0500646 goto out_recoverd;
David Teigland79d72b52007-05-18 09:02:20 -0500647
David Teigland8b0e7b22007-05-18 09:03:35 -0500648 wait_for_completion(&ls->ls_members_done);
649 error = ls->ls_members_result;
650 if (error)
651 goto out_members;
652
David Teigland79d72b52007-05-18 09:02:20 -0500653 dlm_create_debug_file(ls);
654
David Teigland075f0172014-02-14 11:54:44 -0600655 log_rinfo(ls, "join complete");
David Teiglande7fd4172006-01-18 09:30:29 +0000656 *lockspace = ls;
657 return 0;
658
David Teigland8b0e7b22007-05-18 09:03:35 -0500659 out_members:
660 do_uevent(ls, 0);
661 dlm_clear_members(ls);
662 kfree(ls->ls_node_array);
David Teigland23e8e1a2011-04-05 13:16:24 -0500663 out_recoverd:
David Teigland5f88f1e2006-08-24 14:47:20 -0500664 dlm_recoverd_stop(ls);
David Teigland23e8e1a2011-04-05 13:16:24 -0500665 out_callback:
666 dlm_callback_stop(ls);
David Teigland79d72b52007-05-18 09:02:20 -0500667 out_delist:
David Teiglande7fd4172006-01-18 09:30:29 +0000668 spin_lock(&lslist_lock);
669 list_del(&ls->ls_list);
670 spin_unlock(&lslist_lock);
David Teigland1d7c4842012-05-15 16:07:49 -0500671 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000672 kfree(ls->ls_recover_buf);
David Teigland05c32f42012-06-14 12:17:32 -0500673 out_lkbidr:
David Teigland3d6aa672011-07-06 17:00:54 -0500674 idr_destroy(&ls->ls_lkbidr);
Vasily Averinb9828962018-11-15 13:15:05 +0300675 out_rsbtbl:
Thomas Meyer34568802018-12-03 10:02:01 -0600676 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
677 kfree(ls->ls_remove_names[i]);
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500678 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000679 out_lsfree:
David Teigland79d72b52007-05-18 09:02:20 -0500680 if (do_unreg)
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800681 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500682 else
683 kfree(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000684 out:
685 module_put(THIS_MODULE);
686 return error;
687}
688
David Teigland60f98d12011-11-02 14:30:58 -0500689int dlm_new_lockspace(const char *name, const char *cluster,
690 uint32_t flags, int lvblen,
691 const struct dlm_lockspace_ops *ops, void *ops_arg,
692 int *ops_result, dlm_lockspace_t **lockspace)
David Teiglande7fd4172006-01-18 09:30:29 +0000693{
694 int error = 0;
695
David Teigland90135922006-01-20 08:47:07 +0000696 mutex_lock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000697 if (!ls_count)
698 error = threads_start();
699 if (error)
700 goto out;
701
David Teigland60f98d12011-11-02 14:30:58 -0500702 error = new_lockspace(name, cluster, flags, lvblen, ops, ops_arg,
703 ops_result, lockspace);
David Teiglande7fd4172006-01-18 09:30:29 +0000704 if (!error)
705 ls_count++;
David Teigland8511a272009-04-08 15:38:43 -0500706 if (error > 0)
707 error = 0;
Alexander Aring9d232462021-03-01 17:05:20 -0500708 if (!ls_count) {
709 dlm_scand_stop();
Alexander Aringa070a912021-05-21 15:08:41 -0400710 dlm_midcomms_shutdown();
Alexander Aring9d232462021-03-01 17:05:20 -0500711 dlm_lowcomms_stop();
712 }
David Teiglande7fd4172006-01-18 09:30:29 +0000713 out:
David Teigland90135922006-01-20 08:47:07 +0000714 mutex_unlock(&ls_lock);
David Teiglande7fd4172006-01-18 09:30:29 +0000715 return error;
716}
717
David Teigland3d6aa672011-07-06 17:00:54 -0500718static int lkb_idr_is_local(int id, void *p, void *data)
David Teiglande7fd4172006-01-18 09:30:29 +0000719{
David Teigland3d6aa672011-07-06 17:00:54 -0500720 struct dlm_lkb *lkb = p;
David Teiglande7fd4172006-01-18 09:30:29 +0000721
Bart Van Asschea97f4a62013-10-16 14:20:25 +0200722 return lkb->lkb_nodeid == 0 && lkb->lkb_grmode != DLM_LOCK_IV;
David Teigland3d6aa672011-07-06 17:00:54 -0500723}
David Teiglande7fd4172006-01-18 09:30:29 +0000724
David Teigland3d6aa672011-07-06 17:00:54 -0500725static int lkb_idr_is_any(int id, void *p, void *data)
726{
727 return 1;
728}
729
730static int lkb_idr_free(int id, void *p, void *data)
731{
732 struct dlm_lkb *lkb = p;
733
David Teigland3d6aa672011-07-06 17:00:54 -0500734 if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY)
735 dlm_free_lvb(lkb->lkb_lvbptr);
736
737 dlm_free_lkb(lkb);
738 return 0;
739}
740
741/* NOTE: We check the lkbidr here rather than the resource table.
742 This is because there may be LKBs queued as ASTs that have been unlinked
743 from their RSBs and are pending deletion once the AST has been delivered */
744
745static int lockspace_busy(struct dlm_ls *ls, int force)
746{
747 int rv;
748
749 spin_lock(&ls->ls_lkbidr_spin);
750 if (force == 0) {
751 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls);
752 } else if (force == 1) {
753 rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_local, ls);
754 } else {
755 rv = 0;
David Teiglande7fd4172006-01-18 09:30:29 +0000756 }
David Teigland3d6aa672011-07-06 17:00:54 -0500757 spin_unlock(&ls->ls_lkbidr_spin);
758 return rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000759}
760
761static int release_lockspace(struct dlm_ls *ls, int force)
762{
David Teiglande7fd4172006-01-18 09:30:29 +0000763 struct dlm_rsb *rsb;
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500764 struct rb_node *n;
David Teigland0f8e0d92008-08-06 13:30:24 -0500765 int i, busy, rv;
David Teiglande7fd4172006-01-18 09:30:29 +0000766
David Teigland3d6aa672011-07-06 17:00:54 -0500767 busy = lockspace_busy(ls, force);
David Teigland0f8e0d92008-08-06 13:30:24 -0500768
769 spin_lock(&lslist_lock);
770 if (ls->ls_create_count == 1) {
David Teigland3d6aa672011-07-06 17:00:54 -0500771 if (busy) {
David Teigland0f8e0d92008-08-06 13:30:24 -0500772 rv = -EBUSY;
David Teigland3d6aa672011-07-06 17:00:54 -0500773 } else {
David Teigland0f8e0d92008-08-06 13:30:24 -0500774 /* remove_lockspace takes ls off lslist */
775 ls->ls_create_count = 0;
776 rv = 0;
777 }
778 } else if (ls->ls_create_count > 1) {
779 rv = --ls->ls_create_count;
780 } else {
781 rv = -EINVAL;
782 }
783 spin_unlock(&lslist_lock);
784
785 if (rv) {
786 log_debug(ls, "release_lockspace no remove %d", rv);
787 return rv;
788 }
789
790 dlm_device_deregister(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000791
David Teiglanddc68c7e2008-08-18 11:43:30 -0500792 if (force < 3 && dlm_user_daemon_available())
David Teiglande7fd4172006-01-18 09:30:29 +0000793 do_uevent(ls, 0);
794
795 dlm_recoverd_stop(ls);
796
Alexander Aring9d232462021-03-01 17:05:20 -0500797 if (ls_count == 1) {
798 dlm_scand_stop();
Alexander Aringecd95672021-08-26 10:06:31 -0400799 dlm_clear_members(ls);
Alexander Aringa070a912021-05-21 15:08:41 -0400800 dlm_midcomms_shutdown();
Alexander Aring9d232462021-03-01 17:05:20 -0500801 }
802
David Teigland23e8e1a2011-04-05 13:16:24 -0500803 dlm_callback_stop(ls);
804
David Teiglande7fd4172006-01-18 09:30:29 +0000805 remove_lockspace(ls);
806
807 dlm_delete_debug_file(ls);
808
David Teigland8fc6ed92018-11-15 11:17:40 -0600809 idr_destroy(&ls->ls_recover_idr);
David Teiglande7fd4172006-01-18 09:30:29 +0000810 kfree(ls->ls_recover_buf);
811
812 /*
David Teigland3d6aa672011-07-06 17:00:54 -0500813 * Free all lkb's in idr
David Teiglande7fd4172006-01-18 09:30:29 +0000814 */
815
David Teigland3d6aa672011-07-06 17:00:54 -0500816 idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls);
David Teigland3d6aa672011-07-06 17:00:54 -0500817 idr_destroy(&ls->ls_lkbidr);
David Teiglande7fd4172006-01-18 09:30:29 +0000818
David Teiglande7fd4172006-01-18 09:30:29 +0000819 /*
820 * Free all rsb's on rsbtbl[] lists
821 */
822
823 for (i = 0; i < ls->ls_rsbtbl_size; i++) {
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500824 while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) {
825 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
826 rb_erase(n, &ls->ls_rsbtbl[i].keep);
David Teigland52bda2b2007-11-07 09:06:49 -0600827 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000828 }
829
Bob Peterson9beb3bf2011-10-26 15:24:55 -0500830 while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) {
831 rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
832 rb_erase(n, &ls->ls_rsbtbl[i].toss);
David Teigland52bda2b2007-11-07 09:06:49 -0600833 dlm_free_rsb(rsb);
David Teiglande7fd4172006-01-18 09:30:29 +0000834 }
835 }
836
Bryn M. Reevesc282af42011-07-01 15:49:23 -0500837 vfree(ls->ls_rsbtbl);
David Teiglande7fd4172006-01-18 09:30:29 +0000838
David Teigland05c32f42012-06-14 12:17:32 -0500839 for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
840 kfree(ls->ls_remove_names[i]);
841
David Teigland3881ac02011-07-07 14:05:03 -0500842 while (!list_empty(&ls->ls_new_rsb)) {
843 rsb = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb,
844 res_hashchain);
845 list_del(&rsb->res_hashchain);
846 dlm_free_rsb(rsb);
847 }
848
David Teiglande7fd4172006-01-18 09:30:29 +0000849 /*
850 * Free structures on any other lists
851 */
852
David Teigland2896ee32006-11-27 11:31:22 -0600853 dlm_purge_requestqueue(ls);
David Teiglande7fd4172006-01-18 09:30:29 +0000854 kfree(ls->ls_recover_args);
David Teiglande7fd4172006-01-18 09:30:29 +0000855 dlm_clear_members(ls);
856 dlm_clear_members_gone(ls);
857 kfree(ls->ls_node_array);
David Teigland075f0172014-02-14 11:54:44 -0600858 log_rinfo(ls, "release_lockspace final free");
Greg Kroah-Hartman197b12d2007-12-20 08:13:05 -0800859 kobject_put(&ls->ls_kobj);
David Teigland79d72b52007-05-18 09:02:20 -0500860 /* The ls structure will be freed when the kobject is done with */
David Teiglande7fd4172006-01-18 09:30:29 +0000861
David Teiglande7fd4172006-01-18 09:30:29 +0000862 module_put(THIS_MODULE);
863 return 0;
864}
865
866/*
867 * Called when a system has released all its locks and is not going to use the
868 * lockspace any longer. We free everything we're managing for this lockspace.
869 * Remaining nodes will go through the recovery process as if we'd died. The
870 * lockspace must continue to function as usual, participating in recoveries,
871 * until this returns.
872 *
873 * Force has 4 possible values:
Alexander Aringbb6866a2021-11-02 15:17:08 -0400874 * 0 - don't destroy lockspace if it has any LKBs
David Teiglande7fd4172006-01-18 09:30:29 +0000875 * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs
876 * 2 - destroy lockspace regardless of LKBs
877 * 3 - destroy lockspace as part of a forced shutdown
878 */
879
880int dlm_release_lockspace(void *lockspace, int force)
881{
882 struct dlm_ls *ls;
David Teigland0f8e0d92008-08-06 13:30:24 -0500883 int error;
David Teiglande7fd4172006-01-18 09:30:29 +0000884
885 ls = dlm_find_lockspace_local(lockspace);
886 if (!ls)
887 return -EINVAL;
888 dlm_put_lockspace(ls);
David Teigland0f8e0d92008-08-06 13:30:24 -0500889
890 mutex_lock(&ls_lock);
891 error = release_lockspace(ls, force);
892 if (!error)
893 ls_count--;
David Teigland278afcb2008-11-13 13:22:34 -0600894 if (!ls_count)
Alexander Aring9d232462021-03-01 17:05:20 -0500895 dlm_lowcomms_stop();
David Teigland0f8e0d92008-08-06 13:30:24 -0500896 mutex_unlock(&ls_lock);
897
898 return error;
David Teiglande7fd4172006-01-18 09:30:29 +0000899}
900
David Teiglanddc68c7e2008-08-18 11:43:30 -0500901void dlm_stop_lockspaces(void)
902{
903 struct dlm_ls *ls;
David Teigland696b3d82013-06-25 12:48:01 -0500904 int count;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500905
906 restart:
David Teigland696b3d82013-06-25 12:48:01 -0500907 count = 0;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500908 spin_lock(&lslist_lock);
909 list_for_each_entry(ls, &lslist, ls_list) {
David Teigland696b3d82013-06-25 12:48:01 -0500910 if (!test_bit(LSFL_RUNNING, &ls->ls_flags)) {
911 count++;
David Teiglanddc68c7e2008-08-18 11:43:30 -0500912 continue;
David Teigland696b3d82013-06-25 12:48:01 -0500913 }
David Teiglanddc68c7e2008-08-18 11:43:30 -0500914 spin_unlock(&lslist_lock);
915 log_error(ls, "no userland control daemon, stopping lockspace");
916 dlm_ls_stop(ls);
917 goto restart;
918 }
919 spin_unlock(&lslist_lock);
David Teigland696b3d82013-06-25 12:48:01 -0500920
921 if (count)
922 log_print("dlm user daemon left %d lockspaces", count);
David Teiglanddc68c7e2008-08-18 11:43:30 -0500923}
924