diff options
Diffstat (limited to 'fs/dlm/lock.c')
-rw-r--r-- | fs/dlm/lock.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 85a0e73ba808..5f6963904107 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -3278,6 +3278,7 @@ static void purge_queue(struct dlm_rsb *r, struct list_head *queue, | |||
3278 | 3278 | ||
3279 | list_for_each_entry_safe(lkb, safe, queue, lkb_statequeue) { | 3279 | list_for_each_entry_safe(lkb, safe, queue, lkb_statequeue) { |
3280 | if (test(ls, lkb)) { | 3280 | if (test(ls, lkb)) { |
3281 | rsb_set_flag(r, RSB_LOCKS_PURGED); | ||
3281 | del_lkb(r, lkb); | 3282 | del_lkb(r, lkb); |
3282 | /* this put should free the lkb */ | 3283 | /* this put should free the lkb */ |
3283 | if (!dlm_put_lkb(lkb)) | 3284 | if (!dlm_put_lkb(lkb)) |
@@ -3334,27 +3335,40 @@ int dlm_purge_locks(struct dlm_ls *ls) | |||
3334 | return 0; | 3335 | return 0; |
3335 | } | 3336 | } |
3336 | 3337 | ||
3337 | int dlm_grant_after_purge(struct dlm_ls *ls) | 3338 | static struct dlm_rsb *find_purged_rsb(struct dlm_ls *ls, int bucket) |
3339 | { | ||
3340 | struct dlm_rsb *r, *r_ret = NULL; | ||
3341 | |||
3342 | read_lock(&ls->ls_rsbtbl[bucket].lock); | ||
3343 | list_for_each_entry(r, &ls->ls_rsbtbl[bucket].list, res_hashchain) { | ||
3344 | if (!rsb_flag(r, RSB_LOCKS_PURGED)) | ||
3345 | continue; | ||
3346 | hold_rsb(r); | ||
3347 | rsb_clear_flag(r, RSB_LOCKS_PURGED); | ||
3348 | r_ret = r; | ||
3349 | break; | ||
3350 | } | ||
3351 | read_unlock(&ls->ls_rsbtbl[bucket].lock); | ||
3352 | return r_ret; | ||
3353 | } | ||
3354 | |||
3355 | void dlm_grant_after_purge(struct dlm_ls *ls) | ||
3338 | { | 3356 | { |
3339 | struct dlm_rsb *r; | 3357 | struct dlm_rsb *r; |
3340 | int i; | 3358 | int i; |
3341 | 3359 | ||
3342 | for (i = 0; i < ls->ls_rsbtbl_size; i++) { | 3360 | for (i = 0; i < ls->ls_rsbtbl_size; i++) { |
3343 | read_lock(&ls->ls_rsbtbl[i].lock); | 3361 | r = find_purged_rsb(ls, i); |
3344 | list_for_each_entry(r, &ls->ls_rsbtbl[i].list, res_hashchain) { | 3362 | if (!r) |
3345 | hold_rsb(r); | 3363 | continue; |
3346 | lock_rsb(r); | 3364 | lock_rsb(r); |
3347 | if (is_master(r)) { | 3365 | if (is_master(r)) { |
3348 | grant_pending_locks(r); | 3366 | grant_pending_locks(r); |
3349 | confirm_master(r, 0); | 3367 | confirm_master(r, 0); |
3350 | } | ||
3351 | unlock_rsb(r); | ||
3352 | put_rsb(r); | ||
3353 | } | 3368 | } |
3354 | read_unlock(&ls->ls_rsbtbl[i].lock); | 3369 | unlock_rsb(r); |
3370 | put_rsb(r); | ||
3355 | } | 3371 | } |
3356 | |||
3357 | return 0; | ||
3358 | } | 3372 | } |
3359 | 3373 | ||
3360 | static struct dlm_lkb *search_remid_list(struct list_head *head, int nodeid, | 3374 | static struct dlm_lkb *search_remid_list(struct list_head *head, int nodeid, |