diff options
Diffstat (limited to 'fs/dlm/lockspace.c')
-rw-r--r-- | fs/dlm/lockspace.c | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index a1d8f1af144b..a1ea25face82 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -2,7 +2,7 @@ | |||
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved. |
6 | ** | 6 | ** |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -386,12 +386,15 @@ static void threads_stop(void) | |||
386 | dlm_lowcomms_stop(); | 386 | dlm_lowcomms_stop(); |
387 | } | 387 | } |
388 | 388 | ||
389 | static int new_lockspace(const char *name, int namelen, void **lockspace, | 389 | static int new_lockspace(const char *name, const char *cluster, |
390 | uint32_t flags, int lvblen) | 390 | uint32_t flags, int lvblen, |
391 | const struct dlm_lockspace_ops *ops, void *ops_arg, | ||
392 | int *ops_result, dlm_lockspace_t **lockspace) | ||
391 | { | 393 | { |
392 | struct dlm_ls *ls; | 394 | struct dlm_ls *ls; |
393 | int i, size, error; | 395 | int i, size, error; |
394 | int do_unreg = 0; | 396 | int do_unreg = 0; |
397 | int namelen = strlen(name); | ||
395 | 398 | ||
396 | if (namelen > DLM_LOCKSPACE_LEN) | 399 | if (namelen > DLM_LOCKSPACE_LEN) |
397 | return -EINVAL; | 400 | return -EINVAL; |
@@ -403,8 +406,24 @@ static int new_lockspace(const char *name, int namelen, void **lockspace, | |||
403 | return -EINVAL; | 406 | return -EINVAL; |
404 | 407 | ||
405 | if (!dlm_user_daemon_available()) { | 408 | if (!dlm_user_daemon_available()) { |
406 | module_put(THIS_MODULE); | 409 | log_print("dlm user daemon not available"); |
407 | return -EUNATCH; | 410 | error = -EUNATCH; |
411 | goto out; | ||
412 | } | ||
413 | |||
414 | if (ops && ops_result) { | ||
415 | if (!dlm_config.ci_recover_callbacks) | ||
416 | *ops_result = -EOPNOTSUPP; | ||
417 | else | ||
418 | *ops_result = 0; | ||
419 | } | ||
420 | |||
421 | if (dlm_config.ci_recover_callbacks && cluster && | ||
422 | strncmp(cluster, dlm_config.ci_cluster_name, DLM_LOCKSPACE_LEN)) { | ||
423 | log_print("dlm cluster name %s mismatch %s", | ||
424 | dlm_config.ci_cluster_name, cluster); | ||
425 | error = -EBADR; | ||
426 | goto out; | ||
408 | } | 427 | } |
409 | 428 | ||
410 | error = 0; | 429 | error = 0; |
@@ -442,6 +461,11 @@ static int new_lockspace(const char *name, int namelen, void **lockspace, | |||
442 | ls->ls_flags = 0; | 461 | ls->ls_flags = 0; |
443 | ls->ls_scan_time = jiffies; | 462 | ls->ls_scan_time = jiffies; |
444 | 463 | ||
464 | if (ops && dlm_config.ci_recover_callbacks) { | ||
465 | ls->ls_ops = ops; | ||
466 | ls->ls_ops_arg = ops_arg; | ||
467 | } | ||
468 | |||
445 | if (flags & DLM_LSFL_TIMEWARN) | 469 | if (flags & DLM_LSFL_TIMEWARN) |
446 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); | 470 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); |
447 | 471 | ||
@@ -457,8 +481,8 @@ static int new_lockspace(const char *name, int namelen, void **lockspace, | |||
457 | if (!ls->ls_rsbtbl) | 481 | if (!ls->ls_rsbtbl) |
458 | goto out_lsfree; | 482 | goto out_lsfree; |
459 | for (i = 0; i < size; i++) { | 483 | for (i = 0; i < size; i++) { |
460 | INIT_LIST_HEAD(&ls->ls_rsbtbl[i].list); | 484 | ls->ls_rsbtbl[i].keep.rb_node = NULL; |
461 | INIT_LIST_HEAD(&ls->ls_rsbtbl[i].toss); | 485 | ls->ls_rsbtbl[i].toss.rb_node = NULL; |
462 | spin_lock_init(&ls->ls_rsbtbl[i].lock); | 486 | spin_lock_init(&ls->ls_rsbtbl[i].lock); |
463 | } | 487 | } |
464 | 488 | ||
@@ -525,6 +549,11 @@ static int new_lockspace(const char *name, int namelen, void **lockspace, | |||
525 | if (!ls->ls_recover_buf) | 549 | if (!ls->ls_recover_buf) |
526 | goto out_dirfree; | 550 | goto out_dirfree; |
527 | 551 | ||
552 | ls->ls_slot = 0; | ||
553 | ls->ls_num_slots = 0; | ||
554 | ls->ls_slots_size = 0; | ||
555 | ls->ls_slots = NULL; | ||
556 | |||
528 | INIT_LIST_HEAD(&ls->ls_recover_list); | 557 | INIT_LIST_HEAD(&ls->ls_recover_list); |
529 | spin_lock_init(&ls->ls_recover_list_lock); | 558 | spin_lock_init(&ls->ls_recover_list_lock); |
530 | ls->ls_recover_list_count = 0; | 559 | ls->ls_recover_list_count = 0; |
@@ -614,8 +643,10 @@ static int new_lockspace(const char *name, int namelen, void **lockspace, | |||
614 | return error; | 643 | return error; |
615 | } | 644 | } |
616 | 645 | ||
617 | int dlm_new_lockspace(const char *name, int namelen, void **lockspace, | 646 | int dlm_new_lockspace(const char *name, const char *cluster, |
618 | uint32_t flags, int lvblen) | 647 | uint32_t flags, int lvblen, |
648 | const struct dlm_lockspace_ops *ops, void *ops_arg, | ||
649 | int *ops_result, dlm_lockspace_t **lockspace) | ||
619 | { | 650 | { |
620 | int error = 0; | 651 | int error = 0; |
621 | 652 | ||
@@ -625,7 +656,8 @@ int dlm_new_lockspace(const char *name, int namelen, void **lockspace, | |||
625 | if (error) | 656 | if (error) |
626 | goto out; | 657 | goto out; |
627 | 658 | ||
628 | error = new_lockspace(name, namelen, lockspace, flags, lvblen); | 659 | error = new_lockspace(name, cluster, flags, lvblen, ops, ops_arg, |
660 | ops_result, lockspace); | ||
629 | if (!error) | 661 | if (!error) |
630 | ls_count++; | 662 | ls_count++; |
631 | if (error > 0) | 663 | if (error > 0) |
@@ -685,7 +717,7 @@ static int lockspace_busy(struct dlm_ls *ls, int force) | |||
685 | static int release_lockspace(struct dlm_ls *ls, int force) | 717 | static int release_lockspace(struct dlm_ls *ls, int force) |
686 | { | 718 | { |
687 | struct dlm_rsb *rsb; | 719 | struct dlm_rsb *rsb; |
688 | struct list_head *head; | 720 | struct rb_node *n; |
689 | int i, busy, rv; | 721 | int i, busy, rv; |
690 | 722 | ||
691 | busy = lockspace_busy(ls, force); | 723 | busy = lockspace_busy(ls, force); |
@@ -746,20 +778,15 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
746 | */ | 778 | */ |
747 | 779 | ||
748 | for (i = 0; i < ls->ls_rsbtbl_size; i++) { | 780 | for (i = 0; i < ls->ls_rsbtbl_size; i++) { |
749 | head = &ls->ls_rsbtbl[i].list; | 781 | while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) { |
750 | while (!list_empty(head)) { | 782 | rsb = rb_entry(n, struct dlm_rsb, res_hashnode); |
751 | rsb = list_entry(head->next, struct dlm_rsb, | 783 | rb_erase(n, &ls->ls_rsbtbl[i].keep); |
752 | res_hashchain); | ||
753 | |||
754 | list_del(&rsb->res_hashchain); | ||
755 | dlm_free_rsb(rsb); | 784 | dlm_free_rsb(rsb); |
756 | } | 785 | } |
757 | 786 | ||
758 | head = &ls->ls_rsbtbl[i].toss; | 787 | while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) { |
759 | while (!list_empty(head)) { | 788 | rsb = rb_entry(n, struct dlm_rsb, res_hashnode); |
760 | rsb = list_entry(head->next, struct dlm_rsb, | 789 | rb_erase(n, &ls->ls_rsbtbl[i].toss); |
761 | res_hashchain); | ||
762 | list_del(&rsb->res_hashchain); | ||
763 | dlm_free_rsb(rsb); | 790 | dlm_free_rsb(rsb); |
764 | } | 791 | } |
765 | } | 792 | } |