diff options
Diffstat (limited to 'fs/dlm/lockspace.c')
-rw-r--r-- | fs/dlm/lockspace.c | 86 |
1 files changed, 70 insertions, 16 deletions
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index a677b2a5eed4..1dc72105ab12 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -197,13 +197,24 @@ static int do_uevent(struct dlm_ls *ls, int in) | |||
197 | else | 197 | else |
198 | kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); | 198 | kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); |
199 | 199 | ||
200 | log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving"); | ||
201 | |||
202 | /* dlm_controld will see the uevent, do the necessary group management | ||
203 | and then write to sysfs to wake us */ | ||
204 | |||
200 | error = wait_event_interruptible(ls->ls_uevent_wait, | 205 | error = wait_event_interruptible(ls->ls_uevent_wait, |
201 | test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); | 206 | test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); |
207 | |||
208 | log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result); | ||
209 | |||
202 | if (error) | 210 | if (error) |
203 | goto out; | 211 | goto out; |
204 | 212 | ||
205 | error = ls->ls_uevent_result; | 213 | error = ls->ls_uevent_result; |
206 | out: | 214 | out: |
215 | if (error) | ||
216 | log_error(ls, "group %s failed %d %d", in ? "join" : "leave", | ||
217 | error, ls->ls_uevent_result); | ||
207 | return error; | 218 | return error; |
208 | } | 219 | } |
209 | 220 | ||
@@ -234,8 +245,13 @@ static int dlm_scand(void *data) | |||
234 | struct dlm_ls *ls; | 245 | struct dlm_ls *ls; |
235 | 246 | ||
236 | while (!kthread_should_stop()) { | 247 | while (!kthread_should_stop()) { |
237 | list_for_each_entry(ls, &lslist, ls_list) | 248 | list_for_each_entry(ls, &lslist, ls_list) { |
238 | dlm_scan_rsbs(ls); | 249 | if (dlm_lock_recovery_try(ls)) { |
250 | dlm_scan_rsbs(ls); | ||
251 | dlm_scan_timeout(ls); | ||
252 | dlm_unlock_recovery(ls); | ||
253 | } | ||
254 | } | ||
239 | schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); | 255 | schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); |
240 | } | 256 | } |
241 | return 0; | 257 | return 0; |
@@ -395,6 +411,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
395 | { | 411 | { |
396 | struct dlm_ls *ls; | 412 | struct dlm_ls *ls; |
397 | int i, size, error = -ENOMEM; | 413 | int i, size, error = -ENOMEM; |
414 | int do_unreg = 0; | ||
398 | 415 | ||
399 | if (namelen > DLM_LOCKSPACE_LEN) | 416 | if (namelen > DLM_LOCKSPACE_LEN) |
400 | return -EINVAL; | 417 | return -EINVAL; |
@@ -417,11 +434,22 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
417 | goto out; | 434 | goto out; |
418 | memcpy(ls->ls_name, name, namelen); | 435 | memcpy(ls->ls_name, name, namelen); |
419 | ls->ls_namelen = namelen; | 436 | ls->ls_namelen = namelen; |
420 | ls->ls_exflags = flags; | ||
421 | ls->ls_lvblen = lvblen; | 437 | ls->ls_lvblen = lvblen; |
422 | ls->ls_count = 0; | 438 | ls->ls_count = 0; |
423 | ls->ls_flags = 0; | 439 | ls->ls_flags = 0; |
424 | 440 | ||
441 | if (flags & DLM_LSFL_TIMEWARN) | ||
442 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); | ||
443 | |||
444 | if (flags & DLM_LSFL_FS) | ||
445 | ls->ls_allocation = GFP_NOFS; | ||
446 | else | ||
447 | ls->ls_allocation = GFP_KERNEL; | ||
448 | |||
449 | /* ls_exflags are forced to match among nodes, and we don't | ||
450 | need to require all nodes to have TIMEWARN or FS set */ | ||
451 | ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS)); | ||
452 | |||
425 | size = dlm_config.ci_rsbtbl_size; | 453 | size = dlm_config.ci_rsbtbl_size; |
426 | ls->ls_rsbtbl_size = size; | 454 | ls->ls_rsbtbl_size = size; |
427 | 455 | ||
@@ -461,6 +489,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
461 | mutex_init(&ls->ls_waiters_mutex); | 489 | mutex_init(&ls->ls_waiters_mutex); |
462 | INIT_LIST_HEAD(&ls->ls_orphans); | 490 | INIT_LIST_HEAD(&ls->ls_orphans); |
463 | mutex_init(&ls->ls_orphans_mutex); | 491 | mutex_init(&ls->ls_orphans_mutex); |
492 | INIT_LIST_HEAD(&ls->ls_timeout); | ||
493 | mutex_init(&ls->ls_timeout_mutex); | ||
464 | 494 | ||
465 | INIT_LIST_HEAD(&ls->ls_nodes); | 495 | INIT_LIST_HEAD(&ls->ls_nodes); |
466 | INIT_LIST_HEAD(&ls->ls_nodes_gone); | 496 | INIT_LIST_HEAD(&ls->ls_nodes_gone); |
@@ -477,6 +507,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
477 | 507 | ||
478 | init_waitqueue_head(&ls->ls_uevent_wait); | 508 | init_waitqueue_head(&ls->ls_uevent_wait); |
479 | ls->ls_uevent_result = 0; | 509 | ls->ls_uevent_result = 0; |
510 | init_completion(&ls->ls_members_done); | ||
511 | ls->ls_members_result = -1; | ||
480 | 512 | ||
481 | ls->ls_recoverd_task = NULL; | 513 | ls->ls_recoverd_task = NULL; |
482 | mutex_init(&ls->ls_recoverd_active); | 514 | mutex_init(&ls->ls_recoverd_active); |
@@ -513,32 +545,49 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
513 | error = dlm_recoverd_start(ls); | 545 | error = dlm_recoverd_start(ls); |
514 | if (error) { | 546 | if (error) { |
515 | log_error(ls, "can't start dlm_recoverd %d", error); | 547 | log_error(ls, "can't start dlm_recoverd %d", error); |
516 | goto out_rcomfree; | 548 | goto out_delist; |
517 | } | 549 | } |
518 | 550 | ||
519 | dlm_create_debug_file(ls); | ||
520 | |||
521 | error = kobject_setup(ls); | 551 | error = kobject_setup(ls); |
522 | if (error) | 552 | if (error) |
523 | goto out_del; | 553 | goto out_stop; |
524 | 554 | ||
525 | error = kobject_register(&ls->ls_kobj); | 555 | error = kobject_register(&ls->ls_kobj); |
526 | if (error) | 556 | if (error) |
527 | goto out_del; | 557 | goto out_stop; |
558 | |||
559 | /* let kobject handle freeing of ls if there's an error */ | ||
560 | do_unreg = 1; | ||
561 | |||
562 | /* This uevent triggers dlm_controld in userspace to add us to the | ||
563 | group of nodes that are members of this lockspace (managed by the | ||
564 | cluster infrastructure.) Once it's done that, it tells us who the | ||
565 | current lockspace members are (via configfs) and then tells the | ||
566 | lockspace to start running (via sysfs) in dlm_ls_start(). */ | ||
528 | 567 | ||
529 | error = do_uevent(ls, 1); | 568 | error = do_uevent(ls, 1); |
530 | if (error) | 569 | if (error) |
531 | goto out_unreg; | 570 | goto out_stop; |
571 | |||
572 | wait_for_completion(&ls->ls_members_done); | ||
573 | error = ls->ls_members_result; | ||
574 | if (error) | ||
575 | goto out_members; | ||
576 | |||
577 | dlm_create_debug_file(ls); | ||
578 | |||
579 | log_debug(ls, "join complete"); | ||
532 | 580 | ||
533 | *lockspace = ls; | 581 | *lockspace = ls; |
534 | return 0; | 582 | return 0; |
535 | 583 | ||
536 | out_unreg: | 584 | out_members: |
537 | kobject_unregister(&ls->ls_kobj); | 585 | do_uevent(ls, 0); |
538 | out_del: | 586 | dlm_clear_members(ls); |
539 | dlm_delete_debug_file(ls); | 587 | kfree(ls->ls_node_array); |
588 | out_stop: | ||
540 | dlm_recoverd_stop(ls); | 589 | dlm_recoverd_stop(ls); |
541 | out_rcomfree: | 590 | out_delist: |
542 | spin_lock(&lslist_lock); | 591 | spin_lock(&lslist_lock); |
543 | list_del(&ls->ls_list); | 592 | list_del(&ls->ls_list); |
544 | spin_unlock(&lslist_lock); | 593 | spin_unlock(&lslist_lock); |
@@ -550,7 +599,10 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
550 | out_rsbfree: | 599 | out_rsbfree: |
551 | kfree(ls->ls_rsbtbl); | 600 | kfree(ls->ls_rsbtbl); |
552 | out_lsfree: | 601 | out_lsfree: |
553 | kfree(ls); | 602 | if (do_unreg) |
603 | kobject_unregister(&ls->ls_kobj); | ||
604 | else | ||
605 | kfree(ls); | ||
554 | out: | 606 | out: |
555 | module_put(THIS_MODULE); | 607 | module_put(THIS_MODULE); |
556 | return error; | 608 | return error; |
@@ -570,6 +622,8 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace, | |||
570 | error = new_lockspace(name, namelen, lockspace, flags, lvblen); | 622 | error = new_lockspace(name, namelen, lockspace, flags, lvblen); |
571 | if (!error) | 623 | if (!error) |
572 | ls_count++; | 624 | ls_count++; |
625 | else if (!ls_count) | ||
626 | threads_stop(); | ||
573 | out: | 627 | out: |
574 | mutex_unlock(&ls_lock); | 628 | mutex_unlock(&ls_lock); |
575 | return error; | 629 | return error; |
@@ -696,7 +750,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
696 | dlm_clear_members_gone(ls); | 750 | dlm_clear_members_gone(ls); |
697 | kfree(ls->ls_node_array); | 751 | kfree(ls->ls_node_array); |
698 | kobject_unregister(&ls->ls_kobj); | 752 | kobject_unregister(&ls->ls_kobj); |
699 | /* The ls structure will be freed when the kobject is done with */ | 753 | /* The ls structure will be freed when the kobject is done with */ |
700 | 754 | ||
701 | mutex_lock(&ls_lock); | 755 | mutex_lock(&ls_lock); |
702 | ls_count--; | 756 | ls_count--; |