diff options
Diffstat (limited to 'fs/ocfs2/dlm/dlmmaster.c')
-rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 44f87caf3683..54e182a27caf 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -505,8 +505,10 @@ void dlm_change_lockres_owner(struct dlm_ctxt *dlm, | |||
505 | static void dlm_lockres_release(struct kref *kref) | 505 | static void dlm_lockres_release(struct kref *kref) |
506 | { | 506 | { |
507 | struct dlm_lock_resource *res; | 507 | struct dlm_lock_resource *res; |
508 | struct dlm_ctxt *dlm; | ||
508 | 509 | ||
509 | res = container_of(kref, struct dlm_lock_resource, refs); | 510 | res = container_of(kref, struct dlm_lock_resource, refs); |
511 | dlm = res->dlm; | ||
510 | 512 | ||
511 | /* This should not happen -- all lockres' have a name | 513 | /* This should not happen -- all lockres' have a name |
512 | * associated with them at init time. */ | 514 | * associated with them at init time. */ |
@@ -515,6 +517,7 @@ static void dlm_lockres_release(struct kref *kref) | |||
515 | mlog(0, "destroying lockres %.*s\n", res->lockname.len, | 517 | mlog(0, "destroying lockres %.*s\n", res->lockname.len, |
516 | res->lockname.name); | 518 | res->lockname.name); |
517 | 519 | ||
520 | spin_lock(&dlm->track_lock); | ||
518 | if (!list_empty(&res->tracking)) | 521 | if (!list_empty(&res->tracking)) |
519 | list_del_init(&res->tracking); | 522 | list_del_init(&res->tracking); |
520 | else { | 523 | else { |
@@ -522,6 +525,9 @@ static void dlm_lockres_release(struct kref *kref) | |||
522 | res->lockname.len, res->lockname.name); | 525 | res->lockname.len, res->lockname.name); |
523 | dlm_print_one_lock_resource(res); | 526 | dlm_print_one_lock_resource(res); |
524 | } | 527 | } |
528 | spin_unlock(&dlm->track_lock); | ||
529 | |||
530 | dlm_put(dlm); | ||
525 | 531 | ||
526 | if (!hlist_unhashed(&res->hash_node) || | 532 | if (!hlist_unhashed(&res->hash_node) || |
527 | !list_empty(&res->granted) || | 533 | !list_empty(&res->granted) || |
@@ -595,6 +601,10 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, | |||
595 | res->migration_pending = 0; | 601 | res->migration_pending = 0; |
596 | res->inflight_locks = 0; | 602 | res->inflight_locks = 0; |
597 | 603 | ||
604 | /* put in dlm_lockres_release */ | ||
605 | dlm_grab(dlm); | ||
606 | res->dlm = dlm; | ||
607 | |||
598 | kref_init(&res->refs); | 608 | kref_init(&res->refs); |
599 | 609 | ||
600 | /* just for consistency */ | 610 | /* just for consistency */ |
@@ -722,14 +732,21 @@ lookup: | |||
722 | if (tmpres) { | 732 | if (tmpres) { |
723 | int dropping_ref = 0; | 733 | int dropping_ref = 0; |
724 | 734 | ||
735 | spin_unlock(&dlm->spinlock); | ||
736 | |||
725 | spin_lock(&tmpres->spinlock); | 737 | spin_lock(&tmpres->spinlock); |
738 | /* We wait for the other thread that is mastering the resource */ | ||
739 | if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { | ||
740 | __dlm_wait_on_lockres(tmpres); | ||
741 | BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN); | ||
742 | } | ||
743 | |||
726 | if (tmpres->owner == dlm->node_num) { | 744 | if (tmpres->owner == dlm->node_num) { |
727 | BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF); | 745 | BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF); |
728 | dlm_lockres_grab_inflight_ref(dlm, tmpres); | 746 | dlm_lockres_grab_inflight_ref(dlm, tmpres); |
729 | } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) | 747 | } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) |
730 | dropping_ref = 1; | 748 | dropping_ref = 1; |
731 | spin_unlock(&tmpres->spinlock); | 749 | spin_unlock(&tmpres->spinlock); |
732 | spin_unlock(&dlm->spinlock); | ||
733 | 750 | ||
734 | /* wait until done messaging the master, drop our ref to allow | 751 | /* wait until done messaging the master, drop our ref to allow |
735 | * the lockres to be purged, start over. */ | 752 | * the lockres to be purged, start over. */ |
@@ -2949,7 +2966,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, | |||
2949 | struct dlm_node_iter *iter) | 2966 | struct dlm_node_iter *iter) |
2950 | { | 2967 | { |
2951 | struct dlm_migrate_request migrate; | 2968 | struct dlm_migrate_request migrate; |
2952 | int ret, status = 0; | 2969 | int ret, skip, status = 0; |
2953 | int nodenum; | 2970 | int nodenum; |
2954 | 2971 | ||
2955 | memset(&migrate, 0, sizeof(migrate)); | 2972 | memset(&migrate, 0, sizeof(migrate)); |
@@ -2966,12 +2983,27 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, | |||
2966 | nodenum == new_master) | 2983 | nodenum == new_master) |
2967 | continue; | 2984 | continue; |
2968 | 2985 | ||
2986 | /* We could race exit domain. If exited, skip. */ | ||
2987 | spin_lock(&dlm->spinlock); | ||
2988 | skip = (!test_bit(nodenum, dlm->domain_map)); | ||
2989 | spin_unlock(&dlm->spinlock); | ||
2990 | if (skip) { | ||
2991 | clear_bit(nodenum, iter->node_map); | ||
2992 | continue; | ||
2993 | } | ||
2994 | |||
2969 | ret = o2net_send_message(DLM_MIGRATE_REQUEST_MSG, dlm->key, | 2995 | ret = o2net_send_message(DLM_MIGRATE_REQUEST_MSG, dlm->key, |
2970 | &migrate, sizeof(migrate), nodenum, | 2996 | &migrate, sizeof(migrate), nodenum, |
2971 | &status); | 2997 | &status); |
2972 | if (ret < 0) | 2998 | if (ret < 0) { |
2973 | mlog_errno(ret); | 2999 | mlog(0, "migrate_request returned %d!\n", ret); |
2974 | else if (status < 0) { | 3000 | if (!dlm_is_host_down(ret)) { |
3001 | mlog(ML_ERROR, "unhandled error=%d!\n", ret); | ||
3002 | BUG(); | ||
3003 | } | ||
3004 | clear_bit(nodenum, iter->node_map); | ||
3005 | ret = 0; | ||
3006 | } else if (status < 0) { | ||
2975 | mlog(0, "migrate request (node %u) returned %d!\n", | 3007 | mlog(0, "migrate request (node %u) returned %d!\n", |
2976 | nodenum, status); | 3008 | nodenum, status); |
2977 | ret = status; | 3009 | ret = status; |