Blame view
fs/dlm/lockspace.c
19.2 KB
e7fd41792 [DLM] The core of... |
1 2 3 4 |
/****************************************************************************** ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
60f98d183 dlm: add recovery... |
5 |
** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved. |
e7fd41792 [DLM] The core of... |
6 7 8 9 10 11 12 13 14 15 16 17 |
** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions ** of the GNU General Public License v.2. ** ******************************************************************************* ******************************************************************************/ #include "dlm_internal.h" #include "lockspace.h" #include "member.h" #include "recoverd.h" |
e7fd41792 [DLM] The core of... |
18 19 20 21 22 |
#include "dir.h" #include "lowcomms.h" #include "config.h" #include "memory.h" #include "lock.h" |
c56b39cd2 [DLM] PATCH 3/3 d... |
23 |
#include "recover.h" |
2896ee37c [DLM] fix add_req... |
24 |
#include "requestqueue.h" |
0f8e0d9a3 dlm: allow multip... |
25 |
#include "user.h" |
23e8e1aaa dlm: use workqueu... |
26 |
#include "ast.h" |
e7fd41792 [DLM] The core of... |
27 |
|
e7fd41792 [DLM] The core of... |
28 |
static int ls_count; |
901359256 [DLM] Update DLM ... |
29 |
static struct mutex ls_lock; |
e7fd41792 [DLM] The core of... |
30 31 32 33 34 35 36 37 38 |
static struct list_head lslist; static spinlock_t lslist_lock; static struct task_struct * scand_task; static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) { ssize_t ret = len; int n = simple_strtol(buf, NULL, 0); |
e2de7f565 [DLM] fix oops in... |
39 40 41 |
ls = dlm_find_lockspace_local(ls->ls_local_handle); if (!ls) return -EINVAL; |
e7fd41792 [DLM] The core of... |
42 43 44 45 46 47 48 49 50 51 |
switch (n) { case 0: dlm_ls_stop(ls); break; case 1: dlm_ls_start(ls); break; default: ret = -EINVAL; } |
e2de7f565 [DLM] fix oops in... |
52 |
dlm_put_lockspace(ls); |
e7fd41792 [DLM] The core of... |
53 54 55 56 57 58 59 60 61 62 63 64 65 |
return ret; } static ssize_t dlm_event_store(struct dlm_ls *ls, const char *buf, size_t len) { ls->ls_uevent_result = simple_strtol(buf, NULL, 0); set_bit(LSFL_UEVENT_WAIT, &ls->ls_flags); wake_up(&ls->ls_uevent_wait); return len; } static ssize_t dlm_id_show(struct dlm_ls *ls, char *buf) { |
a1d144c71 [DLM] use snprint... |
66 67 |
return snprintf(buf, PAGE_SIZE, "%u ", ls->ls_global_id); |
e7fd41792 [DLM] The core of... |
68 69 70 71 72 73 74 |
} static ssize_t dlm_id_store(struct dlm_ls *ls, const char *buf, size_t len) { ls->ls_global_id = simple_strtoul(buf, NULL, 0); return len; } |
c56b39cd2 [DLM] PATCH 3/3 d... |
75 76 77 |
static ssize_t dlm_recover_status_show(struct dlm_ls *ls, char *buf) { uint32_t status = dlm_recover_status(ls); |
a1d144c71 [DLM] use snprint... |
78 79 |
return snprintf(buf, PAGE_SIZE, "%x ", status); |
c56b39cd2 [DLM] PATCH 3/3 d... |
80 |
} |
faa0f2677 [DLM] show nodeid... |
81 82 |
static ssize_t dlm_recover_nodeid_show(struct dlm_ls *ls, char *buf) { |
a1d144c71 [DLM] use snprint... |
83 84 |
return snprintf(buf, PAGE_SIZE, "%d ", ls->ls_recover_nodeid); |
faa0f2677 [DLM] show nodeid... |
85 |
} |
e7fd41792 [DLM] The core of... |
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
struct dlm_attr { struct attribute attr; ssize_t (*show)(struct dlm_ls *, char *); ssize_t (*store)(struct dlm_ls *, const char *, size_t); }; static struct dlm_attr dlm_attr_control = { .attr = {.name = "control", .mode = S_IWUSR}, .store = dlm_control_store }; static struct dlm_attr dlm_attr_event = { .attr = {.name = "event_done", .mode = S_IWUSR}, .store = dlm_event_store }; static struct dlm_attr dlm_attr_id = { .attr = {.name = "id", .mode = S_IRUGO | S_IWUSR}, .show = dlm_id_show, .store = dlm_id_store }; |
c56b39cd2 [DLM] PATCH 3/3 d... |
107 108 109 110 |
static struct dlm_attr dlm_attr_recover_status = { .attr = {.name = "recover_status", .mode = S_IRUGO}, .show = dlm_recover_status_show }; |
faa0f2677 [DLM] show nodeid... |
111 112 113 114 |
static struct dlm_attr dlm_attr_recover_nodeid = { .attr = {.name = "recover_nodeid", .mode = S_IRUGO}, .show = dlm_recover_nodeid_show }; |
e7fd41792 [DLM] The core of... |
115 116 117 118 |
static struct attribute *dlm_attrs[] = { &dlm_attr_control.attr, &dlm_attr_event.attr, &dlm_attr_id.attr, |
c56b39cd2 [DLM] PATCH 3/3 d... |
119 |
&dlm_attr_recover_status.attr, |
faa0f2677 [DLM] show nodeid... |
120 |
&dlm_attr_recover_nodeid.attr, |
e7fd41792 [DLM] The core of... |
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
NULL, }; static ssize_t dlm_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj); struct dlm_attr *a = container_of(attr, struct dlm_attr, attr); return a->show ? a->show(ls, buf) : 0; } static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len) { struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj); struct dlm_attr *a = container_of(attr, struct dlm_attr, attr); return a->store ? a->store(ls, buf, len) : len; } |
ba542e3b9 [DLM] Fix kref_pu... |
139 140 141 142 143 |
static void lockspace_kobj_release(struct kobject *k) { struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj); kfree(ls); } |
52cf25d0a Driver core: Cons... |
144 |
static const struct sysfs_ops dlm_attr_ops = { |
e7fd41792 [DLM] The core of... |
145 146 147 148 149 150 151 |
.show = dlm_attr_show, .store = dlm_attr_store, }; static struct kobj_type dlm_ktype = { .default_attrs = dlm_attrs, .sysfs_ops = &dlm_attr_ops, |
ba542e3b9 [DLM] Fix kref_pu... |
152 |
.release = lockspace_kobj_release, |
e7fd41792 [DLM] The core of... |
153 |
}; |
d405936b3 kset: convert dlm... |
154 |
static struct kset *dlm_kset; |
e7fd41792 [DLM] The core of... |
155 |
|
e7fd41792 [DLM] The core of... |
156 157 158 159 160 161 162 163 |
static int do_uevent(struct dlm_ls *ls, int in) { int error; if (in) kobject_uevent(&ls->ls_kobj, KOBJ_ONLINE); else kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); |
8b0e7b2cf [DLM] wait for co... |
164 165 166 167 |
log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving"); /* dlm_controld will see the uevent, do the necessary group management and then write to sysfs to wake us */ |
e7fd41792 [DLM] The core of... |
168 169 |
error = wait_event_interruptible(ls->ls_uevent_wait, test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); |
8b0e7b2cf [DLM] wait for co... |
170 171 |
log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result); |
e7fd41792 [DLM] The core of... |
172 173 174 175 176 |
if (error) goto out; error = ls->ls_uevent_result; out: |
8b0e7b2cf [DLM] wait for co... |
177 178 179 |
if (error) log_error(ls, "group %s failed %d %d", in ? "join" : "leave", error, ls->ls_uevent_result); |
e7fd41792 [DLM] The core of... |
180 181 |
return error; } |
b4a5d4bc3 dlm: Send lockspa... |
182 183 184 185 186 187 188 189 190 191 192 193 |
static int dlm_uevent(struct kset *kset, struct kobject *kobj, struct kobj_uevent_env *env) { struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj); add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name); return 0; } static struct kset_uevent_ops dlm_uevent_ops = { .uevent = dlm_uevent, }; |
e7fd41792 [DLM] The core of... |
194 |
|
30727174b dlm: add __init a... |
195 |
int __init dlm_lockspace_init(void) |
e7fd41792 [DLM] The core of... |
196 |
{ |
e7fd41792 [DLM] The core of... |
197 |
ls_count = 0; |
901359256 [DLM] Update DLM ... |
198 |
mutex_init(&ls_lock); |
e7fd41792 [DLM] The core of... |
199 200 |
INIT_LIST_HEAD(&lslist); spin_lock_init(&lslist_lock); |
b4a5d4bc3 dlm: Send lockspa... |
201 |
dlm_kset = kset_create_and_add("dlm", &dlm_uevent_ops, kernel_kobj); |
d405936b3 kset: convert dlm... |
202 |
if (!dlm_kset) { |
8e24eea72 fs: replace remai... |
203 204 |
printk(KERN_WARNING "%s: can not create kset ", __func__); |
d405936b3 kset: convert dlm... |
205 206 207 |
return -ENOMEM; } return 0; |
e7fd41792 [DLM] The core of... |
208 209 210 211 |
} void dlm_lockspace_exit(void) { |
d405936b3 kset: convert dlm... |
212 |
kset_unregister(dlm_kset); |
e7fd41792 [DLM] The core of... |
213 |
} |
c1dcf65ff dlm: fix locking ... |
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
static struct dlm_ls *find_ls_to_scan(void) { struct dlm_ls *ls; spin_lock(&lslist_lock); list_for_each_entry(ls, &lslist, ls_list) { if (time_after_eq(jiffies, ls->ls_scan_time + dlm_config.ci_scan_secs * HZ)) { spin_unlock(&lslist_lock); return ls; } } spin_unlock(&lslist_lock); return NULL; } |
e7fd41792 [DLM] The core of... |
229 230 231 232 233 |
static int dlm_scand(void *data) { struct dlm_ls *ls; while (!kthread_should_stop()) { |
c1dcf65ff dlm: fix locking ... |
234 235 |
ls = find_ls_to_scan(); if (ls) { |
85e86edf9 [DLM] block scand... |
236 |
if (dlm_lock_recovery_try(ls)) { |
c1dcf65ff dlm: fix locking ... |
237 |
ls->ls_scan_time = jiffies; |
85e86edf9 [DLM] block scand... |
238 |
dlm_scan_rsbs(ls); |
3ae1acf93 [DLM] add lock ti... |
239 |
dlm_scan_timeout(ls); |
c6ff669ba dlm: delayed repl... |
240 |
dlm_scan_waiters(ls); |
85e86edf9 [DLM] block scand... |
241 |
dlm_unlock_recovery(ls); |
c1dcf65ff dlm: fix locking ... |
242 243 |
} else { ls->ls_scan_time += HZ; |
85e86edf9 [DLM] block scand... |
244 |
} |
c6ff669ba dlm: delayed repl... |
245 |
continue; |
85e86edf9 [DLM] block scand... |
246 |
} |
c6ff669ba dlm: delayed repl... |
247 |
schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); |
e7fd41792 [DLM] The core of... |
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
} return 0; } static int dlm_scand_start(void) { struct task_struct *p; int error = 0; p = kthread_run(dlm_scand, NULL, "dlm_scand"); if (IS_ERR(p)) error = PTR_ERR(p); else scand_task = p; return error; } static void dlm_scand_stop(void) { kthread_stop(scand_task); } |
e7fd41792 [DLM] The core of... |
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
struct dlm_ls *dlm_find_lockspace_global(uint32_t id) { struct dlm_ls *ls; spin_lock(&lslist_lock); list_for_each_entry(ls, &lslist, ls_list) { if (ls->ls_global_id == id) { ls->ls_count++; goto out; } } ls = NULL; out: spin_unlock(&lslist_lock); return ls; } |
597d0cae0 [DLM] dlm: user l... |
286 |
struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace) |
e7fd41792 [DLM] The core of... |
287 |
{ |
597d0cae0 [DLM] dlm: user l... |
288 |
struct dlm_ls *ls; |
e7fd41792 [DLM] The core of... |
289 290 |
spin_lock(&lslist_lock); |
597d0cae0 [DLM] dlm: user l... |
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
list_for_each_entry(ls, &lslist, ls_list) { if (ls->ls_local_handle == lockspace) { ls->ls_count++; goto out; } } ls = NULL; out: spin_unlock(&lslist_lock); return ls; } struct dlm_ls *dlm_find_lockspace_device(int minor) { struct dlm_ls *ls; spin_lock(&lslist_lock); list_for_each_entry(ls, &lslist, ls_list) { if (ls->ls_device.minor == minor) { ls->ls_count++; goto out; } } ls = NULL; out: |
e7fd41792 [DLM] The core of... |
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
spin_unlock(&lslist_lock); return ls; } void dlm_put_lockspace(struct dlm_ls *ls) { spin_lock(&lslist_lock); ls->ls_count--; spin_unlock(&lslist_lock); } static void remove_lockspace(struct dlm_ls *ls) { for (;;) { spin_lock(&lslist_lock); if (ls->ls_count == 0) { |
0f8e0d9a3 dlm: allow multip... |
332 |
WARN_ON(ls->ls_create_count != 0); |
e7fd41792 [DLM] The core of... |
333 334 335 336 337 338 339 340 341 342 343 344 |
list_del(&ls->ls_list); spin_unlock(&lslist_lock); return; } spin_unlock(&lslist_lock); ssleep(1); } } static int threads_start(void) { int error; |
e7fd41792 [DLM] The core of... |
345 346 347 |
error = dlm_scand_start(); if (error) { log_print("cannot start dlm_scand thread %d", error); |
23e8e1aaa dlm: use workqueu... |
348 |
goto fail; |
e7fd41792 [DLM] The core of... |
349 350 351 352 353 354 355 356 357 358 359 360 361 |
} /* Thread for sending/receiving messages for all lockspace's */ error = dlm_lowcomms_start(); if (error) { log_print("cannot start dlm lowcomms %d", error); goto scand_fail; } return 0; scand_fail: dlm_scand_stop(); |
e7fd41792 [DLM] The core of... |
362 363 364 365 366 367 368 369 |
fail: return error; } static void threads_stop(void) { dlm_scand_stop(); dlm_lowcomms_stop(); |
e7fd41792 [DLM] The core of... |
370 |
} |
60f98d183 dlm: add recovery... |
371 372 373 374 |
static int new_lockspace(const char *name, const char *cluster, uint32_t flags, int lvblen, const struct dlm_lockspace_ops *ops, void *ops_arg, int *ops_result, dlm_lockspace_t **lockspace) |
e7fd41792 [DLM] The core of... |
375 376 |
{ struct dlm_ls *ls; |
0f8e0d9a3 dlm: allow multip... |
377 |
int i, size, error; |
79d72b544 [DLM] fix new_loc... |
378 |
int do_unreg = 0; |
60f98d183 dlm: add recovery... |
379 |
int namelen = strlen(name); |
e7fd41792 [DLM] The core of... |
380 381 382 383 384 385 386 387 388 |
if (namelen > DLM_LOCKSPACE_LEN) return -EINVAL; if (!lvblen || (lvblen % 8)) return -EINVAL; if (!try_module_get(THIS_MODULE)) return -EINVAL; |
dc68c7ed3 dlm: detect avail... |
389 |
if (!dlm_user_daemon_available()) { |
60f98d183 dlm: add recovery... |
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
log_print("dlm user daemon not available"); error = -EUNATCH; goto out; } if (ops && ops_result) { if (!dlm_config.ci_recover_callbacks) *ops_result = -EOPNOTSUPP; else *ops_result = 0; } if (dlm_config.ci_recover_callbacks && cluster && strncmp(cluster, dlm_config.ci_cluster_name, DLM_LOCKSPACE_LEN)) { log_print("dlm cluster name %s mismatch %s", dlm_config.ci_cluster_name, cluster); error = -EBADR; goto out; |
dc68c7ed3 dlm: detect avail... |
408 |
} |
0f8e0d9a3 dlm: allow multip... |
409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
error = 0; spin_lock(&lslist_lock); list_for_each_entry(ls, &lslist, ls_list) { WARN_ON(ls->ls_create_count <= 0); if (ls->ls_namelen != namelen) continue; if (memcmp(ls->ls_name, name, namelen)) continue; if (flags & DLM_LSFL_NEWEXCL) { error = -EEXIST; break; } ls->ls_create_count++; |
8511a2728 dlm: fix use coun... |
423 424 |
*lockspace = ls; error = 1; |
0f8e0d9a3 dlm: allow multip... |
425 |
break; |
e7fd41792 [DLM] The core of... |
426 |
} |
0f8e0d9a3 dlm: allow multip... |
427 |
spin_unlock(&lslist_lock); |
0f8e0d9a3 dlm: allow multip... |
428 |
if (error) |
8511a2728 dlm: fix use coun... |
429 |
goto out; |
0f8e0d9a3 dlm: allow multip... |
430 431 |
error = -ENOMEM; |
e7fd41792 [DLM] The core of... |
432 |
|
573c24c4a dlm: always use G... |
433 |
ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS); |
e7fd41792 [DLM] The core of... |
434 435 |
if (!ls) goto out; |
e7fd41792 [DLM] The core of... |
436 437 |
memcpy(ls->ls_name, name, namelen); ls->ls_namelen = namelen; |
e7fd41792 [DLM] The core of... |
438 439 440 |
ls->ls_lvblen = lvblen; ls->ls_count = 0; ls->ls_flags = 0; |
c1dcf65ff dlm: fix locking ... |
441 |
ls->ls_scan_time = jiffies; |
e7fd41792 [DLM] The core of... |
442 |
|
60f98d183 dlm: add recovery... |
443 444 445 446 |
if (ops && dlm_config.ci_recover_callbacks) { ls->ls_ops = ops; ls->ls_ops_arg = ops_arg; } |
3ae1acf93 [DLM] add lock ti... |
447 448 |
if (flags & DLM_LSFL_TIMEWARN) set_bit(LSFL_TIMEWARN, &ls->ls_flags); |
3ae1acf93 [DLM] add lock ti... |
449 |
|
fad59c139 [DLM] don't requi... |
450 |
/* ls_exflags are forced to match among nodes, and we don't |
0f8e0d9a3 dlm: allow multip... |
451 452 453 |
need to require all nodes to have some flags set */ ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS | DLM_LSFL_NEWEXCL)); |
fad59c139 [DLM] don't requi... |
454 |
|
68c817a1c [DLM] rename dlm_... |
455 |
size = dlm_config.ci_rsbtbl_size; |
e7fd41792 [DLM] The core of... |
456 |
ls->ls_rsbtbl_size = size; |
c282af499 dlm: use vmalloc ... |
457 |
ls->ls_rsbtbl = vmalloc(sizeof(struct dlm_rsbtable) * size); |
e7fd41792 [DLM] The core of... |
458 459 460 |
if (!ls->ls_rsbtbl) goto out_lsfree; for (i = 0; i < size; i++) { |
9beb3bf5a dlm: convert rsb ... |
461 462 |
ls->ls_rsbtbl[i].keep.rb_node = NULL; ls->ls_rsbtbl[i].toss.rb_node = NULL; |
c7be761a8 dlm: change rsbtb... |
463 |
spin_lock_init(&ls->ls_rsbtbl[i].lock); |
e7fd41792 [DLM] The core of... |
464 |
} |
3d6aa675f dlm: keep lkbs in... |
465 466 |
idr_init(&ls->ls_lkbidr); spin_lock_init(&ls->ls_lkbidr_spin); |
e7fd41792 [DLM] The core of... |
467 |
|
68c817a1c [DLM] rename dlm_... |
468 |
size = dlm_config.ci_dirtbl_size; |
e7fd41792 [DLM] The core of... |
469 |
ls->ls_dirtbl_size = size; |
c282af499 dlm: use vmalloc ... |
470 |
ls->ls_dirtbl = vmalloc(sizeof(struct dlm_dirtable) * size); |
e7fd41792 [DLM] The core of... |
471 472 473 474 |
if (!ls->ls_dirtbl) goto out_lkbfree; for (i = 0; i < size; i++) { INIT_LIST_HEAD(&ls->ls_dirtbl[i].list); |
305a47b17 dlm: Change rwloc... |
475 |
spin_lock_init(&ls->ls_dirtbl[i].lock); |
e7fd41792 [DLM] The core of... |
476 477 478 |
} INIT_LIST_HEAD(&ls->ls_waiters); |
901359256 [DLM] Update DLM ... |
479 |
mutex_init(&ls->ls_waiters_mutex); |
ef0c2bb05 [DLM] overlapping... |
480 481 |
INIT_LIST_HEAD(&ls->ls_orphans); mutex_init(&ls->ls_orphans_mutex); |
3ae1acf93 [DLM] add lock ti... |
482 483 |
INIT_LIST_HEAD(&ls->ls_timeout); mutex_init(&ls->ls_timeout_mutex); |
e7fd41792 [DLM] The core of... |
484 |
|
3881ac04e dlm: improve rsb ... |
485 486 |
INIT_LIST_HEAD(&ls->ls_new_rsb); spin_lock_init(&ls->ls_new_rsb_spin); |
e7fd41792 [DLM] The core of... |
487 488 489 490 491 492 493 494 495 |
INIT_LIST_HEAD(&ls->ls_nodes); INIT_LIST_HEAD(&ls->ls_nodes_gone); ls->ls_num_nodes = 0; ls->ls_low_nodeid = 0; ls->ls_total_weight = 0; ls->ls_node_array = NULL; memset(&ls->ls_stub_rsb, 0, sizeof(struct dlm_rsb)); ls->ls_stub_rsb.res_ls = ls; |
5de6319b1 [DLM] more info t... |
496 497 |
ls->ls_debug_rsb_dentry = NULL; ls->ls_debug_waiters_dentry = NULL; |
e7fd41792 [DLM] The core of... |
498 499 500 |
init_waitqueue_head(&ls->ls_uevent_wait); ls->ls_uevent_result = 0; |
8b0e7b2cf [DLM] wait for co... |
501 502 |
init_completion(&ls->ls_members_done); ls->ls_members_result = -1; |
e7fd41792 [DLM] The core of... |
503 |
|
23e8e1aaa dlm: use workqueu... |
504 505 |
mutex_init(&ls->ls_cb_mutex); INIT_LIST_HEAD(&ls->ls_cb_delay); |
e7fd41792 [DLM] The core of... |
506 |
ls->ls_recoverd_task = NULL; |
901359256 [DLM] Update DLM ... |
507 |
mutex_init(&ls->ls_recoverd_active); |
e7fd41792 [DLM] The core of... |
508 |
spin_lock_init(&ls->ls_recover_lock); |
98f176fb3 [DLM] don't accep... |
509 510 |
spin_lock_init(&ls->ls_rcom_spin); get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t)); |
e7fd41792 [DLM] The core of... |
511 512 513 514 |
ls->ls_recover_status = 0; ls->ls_recover_seq = 0; ls->ls_recover_args = NULL; init_rwsem(&ls->ls_in_recovery); |
c36258b59 [DLM] block dlm_r... |
515 |
init_rwsem(&ls->ls_recv_active); |
e7fd41792 [DLM] The core of... |
516 |
INIT_LIST_HEAD(&ls->ls_requestqueue); |
901359256 [DLM] Update DLM ... |
517 |
mutex_init(&ls->ls_requestqueue_mutex); |
597d0cae0 [DLM] dlm: user l... |
518 |
mutex_init(&ls->ls_clear_proc_locks); |
e7fd41792 [DLM] The core of... |
519 |
|
573c24c4a dlm: always use G... |
520 |
ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS); |
e7fd41792 [DLM] The core of... |
521 522 |
if (!ls->ls_recover_buf) goto out_dirfree; |
757a42719 dlm: add node slo... |
523 524 525 526 |
ls->ls_slot = 0; ls->ls_num_slots = 0; ls->ls_slots_size = 0; ls->ls_slots = NULL; |
e7fd41792 [DLM] The core of... |
527 528 529 |
INIT_LIST_HEAD(&ls->ls_recover_list); spin_lock_init(&ls->ls_recover_list_lock); ls->ls_recover_list_count = 0; |
597d0cae0 [DLM] dlm: user l... |
530 |
ls->ls_local_handle = ls; |
e7fd41792 [DLM] The core of... |
531 532 533 534 535 |
init_waitqueue_head(&ls->ls_wait_general); INIT_LIST_HEAD(&ls->ls_root_list); init_rwsem(&ls->ls_root_sem); down_write(&ls->ls_in_recovery); |
5f88f1ea1 [DLM] add new loc... |
536 |
spin_lock(&lslist_lock); |
0f8e0d9a3 dlm: allow multip... |
537 |
ls->ls_create_count = 1; |
5f88f1ea1 [DLM] add new loc... |
538 539 |
list_add(&ls->ls_list, &lslist); spin_unlock(&lslist_lock); |
23e8e1aaa dlm: use workqueu... |
540 541 542 543 544 545 546 |
if (flags & DLM_LSFL_FS) { error = dlm_callback_start(ls); if (error) { log_error(ls, "can't start dlm_callback %d", error); goto out_delist; } } |
5f88f1ea1 [DLM] add new loc... |
547 |
/* needs to find ls in lslist */ |
e7fd41792 [DLM] The core of... |
548 549 550 |
error = dlm_recoverd_start(ls); if (error) { log_error(ls, "can't start dlm_recoverd %d", error); |
23e8e1aaa dlm: use workqueu... |
551 |
goto out_callback; |
e7fd41792 [DLM] The core of... |
552 |
} |
901195ed7 Kobject: change G... |
553 554 555 |
ls->ls_kobj.kset = dlm_kset; error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL, "%s", ls->ls_name); |
e7fd41792 [DLM] The core of... |
556 |
if (error) |
23e8e1aaa dlm: use workqueu... |
557 |
goto out_recoverd; |
901195ed7 Kobject: change G... |
558 |
kobject_uevent(&ls->ls_kobj, KOBJ_ADD); |
79d72b544 [DLM] fix new_loc... |
559 560 561 |
/* let kobject handle freeing of ls if there's an error */ do_unreg = 1; |
e7fd41792 [DLM] The core of... |
562 |
|
8b0e7b2cf [DLM] wait for co... |
563 564 565 566 567 |
/* This uevent triggers dlm_controld in userspace to add us to the group of nodes that are members of this lockspace (managed by the cluster infrastructure.) Once it's done that, it tells us who the current lockspace members are (via configfs) and then tells the lockspace to start running (via sysfs) in dlm_ls_start(). */ |
e7fd41792 [DLM] The core of... |
568 569 |
error = do_uevent(ls, 1); if (error) |
23e8e1aaa dlm: use workqueu... |
570 |
goto out_recoverd; |
79d72b544 [DLM] fix new_loc... |
571 |
|
8b0e7b2cf [DLM] wait for co... |
572 573 574 575 |
wait_for_completion(&ls->ls_members_done); error = ls->ls_members_result; if (error) goto out_members; |
79d72b544 [DLM] fix new_loc... |
576 577 578 |
dlm_create_debug_file(ls); log_debug(ls, "join complete"); |
e7fd41792 [DLM] The core of... |
579 580 |
*lockspace = ls; return 0; |
8b0e7b2cf [DLM] wait for co... |
581 582 583 584 |
out_members: do_uevent(ls, 0); dlm_clear_members(ls); kfree(ls->ls_node_array); |
23e8e1aaa dlm: use workqueu... |
585 |
out_recoverd: |
5f88f1ea1 [DLM] add new loc... |
586 |
dlm_recoverd_stop(ls); |
23e8e1aaa dlm: use workqueu... |
587 588 |
out_callback: dlm_callback_stop(ls); |
79d72b544 [DLM] fix new_loc... |
589 |
out_delist: |
e7fd41792 [DLM] The core of... |
590 591 592 |
spin_lock(&lslist_lock); list_del(&ls->ls_list); spin_unlock(&lslist_lock); |
e7fd41792 [DLM] The core of... |
593 594 |
kfree(ls->ls_recover_buf); out_dirfree: |
c282af499 dlm: use vmalloc ... |
595 |
vfree(ls->ls_dirtbl); |
e7fd41792 [DLM] The core of... |
596 |
out_lkbfree: |
3d6aa675f dlm: keep lkbs in... |
597 |
idr_destroy(&ls->ls_lkbidr); |
c282af499 dlm: use vmalloc ... |
598 |
vfree(ls->ls_rsbtbl); |
e7fd41792 [DLM] The core of... |
599 |
out_lsfree: |
79d72b544 [DLM] fix new_loc... |
600 |
if (do_unreg) |
197b12d67 Kobject: convert ... |
601 |
kobject_put(&ls->ls_kobj); |
79d72b544 [DLM] fix new_loc... |
602 603 |
else kfree(ls); |
e7fd41792 [DLM] The core of... |
604 605 606 607 |
out: module_put(THIS_MODULE); return error; } |
60f98d183 dlm: add recovery... |
608 609 610 611 |
int dlm_new_lockspace(const char *name, const char *cluster, uint32_t flags, int lvblen, const struct dlm_lockspace_ops *ops, void *ops_arg, int *ops_result, dlm_lockspace_t **lockspace) |
e7fd41792 [DLM] The core of... |
612 613 |
{ int error = 0; |
901359256 [DLM] Update DLM ... |
614 |
mutex_lock(&ls_lock); |
e7fd41792 [DLM] The core of... |
615 616 617 618 |
if (!ls_count) error = threads_start(); if (error) goto out; |
60f98d183 dlm: add recovery... |
619 620 |
error = new_lockspace(name, cluster, flags, lvblen, ops, ops_arg, ops_result, lockspace); |
e7fd41792 [DLM] The core of... |
621 622 |
if (!error) ls_count++; |
8511a2728 dlm: fix use coun... |
623 624 625 |
if (error > 0) error = 0; if (!ls_count) |
8b0e7b2cf [DLM] wait for co... |
626 |
threads_stop(); |
e7fd41792 [DLM] The core of... |
627 |
out: |
901359256 [DLM] Update DLM ... |
628 |
mutex_unlock(&ls_lock); |
e7fd41792 [DLM] The core of... |
629 630 |
return error; } |
3d6aa675f dlm: keep lkbs in... |
631 |
static int lkb_idr_is_local(int id, void *p, void *data) |
e7fd41792 [DLM] The core of... |
632 |
{ |
3d6aa675f dlm: keep lkbs in... |
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 |
struct dlm_lkb *lkb = p; if (!lkb->lkb_nodeid) return 1; return 0; } static int lkb_idr_is_any(int id, void *p, void *data) { return 1; } static int lkb_idr_free(int id, void *p, void *data) { struct dlm_lkb *lkb = p; |
3d6aa675f dlm: keep lkbs in... |
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY) dlm_free_lvb(lkb->lkb_lvbptr); dlm_free_lkb(lkb); return 0; } /* NOTE: We check the lkbidr here rather than the resource table. This is because there may be LKBs queued as ASTs that have been unlinked from their RSBs and are pending deletion once the AST has been delivered */ static int lockspace_busy(struct dlm_ls *ls, int force) { int rv; spin_lock(&ls->ls_lkbidr_spin); if (force == 0) { rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls); } else if (force == 1) { rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_local, ls); } else { rv = 0; |
e7fd41792 [DLM] The core of... |
670 |
} |
3d6aa675f dlm: keep lkbs in... |
671 672 |
spin_unlock(&ls->ls_lkbidr_spin); return rv; |
e7fd41792 [DLM] The core of... |
673 674 675 676 |
} static int release_lockspace(struct dlm_ls *ls, int force) { |
e7fd41792 [DLM] The core of... |
677 |
struct dlm_rsb *rsb; |
9beb3bf5a dlm: convert rsb ... |
678 |
struct rb_node *n; |
0f8e0d9a3 dlm: allow multip... |
679 |
int i, busy, rv; |
3d6aa675f dlm: keep lkbs in... |
680 |
busy = lockspace_busy(ls, force); |
0f8e0d9a3 dlm: allow multip... |
681 682 683 |
spin_lock(&lslist_lock); if (ls->ls_create_count == 1) { |
3d6aa675f dlm: keep lkbs in... |
684 |
if (busy) { |
0f8e0d9a3 dlm: allow multip... |
685 |
rv = -EBUSY; |
3d6aa675f dlm: keep lkbs in... |
686 |
} else { |
0f8e0d9a3 dlm: allow multip... |
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 |
/* remove_lockspace takes ls off lslist */ ls->ls_create_count = 0; rv = 0; } } else if (ls->ls_create_count > 1) { rv = --ls->ls_create_count; } else { rv = -EINVAL; } spin_unlock(&lslist_lock); if (rv) { log_debug(ls, "release_lockspace no remove %d", rv); return rv; } |
e7fd41792 [DLM] The core of... |
702 |
|
0f8e0d9a3 dlm: allow multip... |
703 |
dlm_device_deregister(ls); |
e7fd41792 [DLM] The core of... |
704 |
|
dc68c7ed3 dlm: detect avail... |
705 |
if (force < 3 && dlm_user_daemon_available()) |
e7fd41792 [DLM] The core of... |
706 707 708 |
do_uevent(ls, 0); dlm_recoverd_stop(ls); |
23e8e1aaa dlm: use workqueu... |
709 |
dlm_callback_stop(ls); |
e7fd41792 [DLM] The core of... |
710 711 712 |
remove_lockspace(ls); dlm_delete_debug_file(ls); |
e7fd41792 [DLM] The core of... |
713 714 715 716 717 718 719 |
kfree(ls->ls_recover_buf); /* * Free direntry structs. */ dlm_dir_clear(ls); |
c282af499 dlm: use vmalloc ... |
720 |
vfree(ls->ls_dirtbl); |
e7fd41792 [DLM] The core of... |
721 722 |
/* |
3d6aa675f dlm: keep lkbs in... |
723 |
* Free all lkb's in idr |
e7fd41792 [DLM] The core of... |
724 |
*/ |
3d6aa675f dlm: keep lkbs in... |
725 726 727 |
idr_for_each(&ls->ls_lkbidr, lkb_idr_free, ls); idr_remove_all(&ls->ls_lkbidr); idr_destroy(&ls->ls_lkbidr); |
e7fd41792 [DLM] The core of... |
728 |
|
e7fd41792 [DLM] The core of... |
729 730 731 732 733 |
/* * Free all rsb's on rsbtbl[] lists */ for (i = 0; i < ls->ls_rsbtbl_size; i++) { |
9beb3bf5a dlm: convert rsb ... |
734 735 736 |
while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) { rsb = rb_entry(n, struct dlm_rsb, res_hashnode); rb_erase(n, &ls->ls_rsbtbl[i].keep); |
52bda2b5b dlm: use dlm pref... |
737 |
dlm_free_rsb(rsb); |
e7fd41792 [DLM] The core of... |
738 |
} |
9beb3bf5a dlm: convert rsb ... |
739 740 741 |
while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) { rsb = rb_entry(n, struct dlm_rsb, res_hashnode); rb_erase(n, &ls->ls_rsbtbl[i].toss); |
52bda2b5b dlm: use dlm pref... |
742 |
dlm_free_rsb(rsb); |
e7fd41792 [DLM] The core of... |
743 744 |
} } |
c282af499 dlm: use vmalloc ... |
745 |
vfree(ls->ls_rsbtbl); |
e7fd41792 [DLM] The core of... |
746 |
|
3881ac04e dlm: improve rsb ... |
747 748 749 750 751 752 |
while (!list_empty(&ls->ls_new_rsb)) { rsb = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb, res_hashchain); list_del(&rsb->res_hashchain); dlm_free_rsb(rsb); } |
e7fd41792 [DLM] The core of... |
753 754 755 |
/* * Free structures on any other lists */ |
2896ee37c [DLM] fix add_req... |
756 |
dlm_purge_requestqueue(ls); |
e7fd41792 [DLM] The core of... |
757 758 759 760 761 |
kfree(ls->ls_recover_args); dlm_clear_free_entries(ls); dlm_clear_members(ls); dlm_clear_members_gone(ls); kfree(ls->ls_node_array); |
0f8e0d9a3 dlm: allow multip... |
762 |
log_debug(ls, "release_lockspace final free"); |
197b12d67 Kobject: convert ... |
763 |
kobject_put(&ls->ls_kobj); |
79d72b544 [DLM] fix new_loc... |
764 |
/* The ls structure will be freed when the kobject is done with */ |
e7fd41792 [DLM] The core of... |
765 |
|
e7fd41792 [DLM] The core of... |
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 |
module_put(THIS_MODULE); return 0; } /* * Called when a system has released all its locks and is not going to use the * lockspace any longer. We free everything we're managing for this lockspace. * Remaining nodes will go through the recovery process as if we'd died. The * lockspace must continue to function as usual, participating in recoveries, * until this returns. * * Force has 4 possible values: * 0 - don't destroy locksapce if it has any LKBs * 1 - destroy lockspace if it has remote LKBs but not if it has local LKBs * 2 - destroy lockspace regardless of LKBs * 3 - destroy lockspace as part of a forced shutdown */ int dlm_release_lockspace(void *lockspace, int force) { struct dlm_ls *ls; |
0f8e0d9a3 dlm: allow multip... |
787 |
int error; |
e7fd41792 [DLM] The core of... |
788 789 790 791 792 |
ls = dlm_find_lockspace_local(lockspace); if (!ls) return -EINVAL; dlm_put_lockspace(ls); |
0f8e0d9a3 dlm: allow multip... |
793 794 795 796 797 |
mutex_lock(&ls_lock); error = release_lockspace(ls, force); if (!error) ls_count--; |
278afcbf4 dlm: fix shutdown... |
798 |
if (!ls_count) |
0f8e0d9a3 dlm: allow multip... |
799 800 801 802 |
threads_stop(); mutex_unlock(&ls_lock); return error; |
e7fd41792 [DLM] The core of... |
803 |
} |
dc68c7ed3 dlm: detect avail... |
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 |
void dlm_stop_lockspaces(void) { struct dlm_ls *ls; restart: spin_lock(&lslist_lock); list_for_each_entry(ls, &lslist, ls_list) { if (!test_bit(LSFL_RUNNING, &ls->ls_flags)) continue; spin_unlock(&lslist_lock); log_error(ls, "no userland control daemon, stopping lockspace"); dlm_ls_stop(ls); goto restart; } spin_unlock(&lslist_lock); } |