diff options
Diffstat (limited to 'fs/gfs2/glock.c')
| -rw-r--r-- | fs/gfs2/glock.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 8b674b1f3a55..f455a03a09e2 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -241,15 +241,14 @@ int gfs2_glock_put(struct gfs2_glock *gl) | |||
| 241 | int rv = 0; | 241 | int rv = 0; |
| 242 | 242 | ||
| 243 | write_lock(gl_lock_addr(gl->gl_hash)); | 243 | write_lock(gl_lock_addr(gl->gl_hash)); |
| 244 | if (atomic_dec_and_test(&gl->gl_ref)) { | 244 | if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) { |
| 245 | hlist_del(&gl->gl_list); | 245 | hlist_del(&gl->gl_list); |
| 246 | write_unlock(gl_lock_addr(gl->gl_hash)); | ||
| 247 | spin_lock(&lru_lock); | ||
| 248 | if (!list_empty(&gl->gl_lru)) { | 246 | if (!list_empty(&gl->gl_lru)) { |
| 249 | list_del_init(&gl->gl_lru); | 247 | list_del_init(&gl->gl_lru); |
| 250 | atomic_dec(&lru_count); | 248 | atomic_dec(&lru_count); |
| 251 | } | 249 | } |
| 252 | spin_unlock(&lru_lock); | 250 | spin_unlock(&lru_lock); |
| 251 | write_unlock(gl_lock_addr(gl->gl_hash)); | ||
| 253 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); | 252 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); |
| 254 | glock_free(gl); | 253 | glock_free(gl); |
| 255 | rv = 1; | 254 | rv = 1; |
| @@ -513,7 +512,6 @@ retry: | |||
| 513 | GLOCK_BUG_ON(gl, 1); | 512 | GLOCK_BUG_ON(gl, 1); |
| 514 | } | 513 | } |
| 515 | spin_unlock(&gl->gl_spin); | 514 | spin_unlock(&gl->gl_spin); |
| 516 | gfs2_glock_put(gl); | ||
| 517 | return; | 515 | return; |
| 518 | } | 516 | } |
| 519 | 517 | ||
| @@ -524,8 +522,6 @@ retry: | |||
| 524 | if (glops->go_xmote_bh) { | 522 | if (glops->go_xmote_bh) { |
| 525 | spin_unlock(&gl->gl_spin); | 523 | spin_unlock(&gl->gl_spin); |
| 526 | rv = glops->go_xmote_bh(gl, gh); | 524 | rv = glops->go_xmote_bh(gl, gh); |
| 527 | if (rv == -EAGAIN) | ||
| 528 | return; | ||
| 529 | spin_lock(&gl->gl_spin); | 525 | spin_lock(&gl->gl_spin); |
| 530 | if (rv) { | 526 | if (rv) { |
| 531 | do_error(gl, rv); | 527 | do_error(gl, rv); |
| @@ -540,7 +536,6 @@ out: | |||
| 540 | clear_bit(GLF_LOCK, &gl->gl_flags); | 536 | clear_bit(GLF_LOCK, &gl->gl_flags); |
| 541 | out_locked: | 537 | out_locked: |
| 542 | spin_unlock(&gl->gl_spin); | 538 | spin_unlock(&gl->gl_spin); |
| 543 | gfs2_glock_put(gl); | ||
| 544 | } | 539 | } |
| 545 | 540 | ||
| 546 | static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock, | 541 | static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock, |
| @@ -600,7 +595,6 @@ __acquires(&gl->gl_spin) | |||
| 600 | 595 | ||
| 601 | if (!(ret & LM_OUT_ASYNC)) { | 596 | if (!(ret & LM_OUT_ASYNC)) { |
| 602 | finish_xmote(gl, ret); | 597 | finish_xmote(gl, ret); |
| 603 | gfs2_glock_hold(gl); | ||
| 604 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 598 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
| 605 | gfs2_glock_put(gl); | 599 | gfs2_glock_put(gl); |
| 606 | } else { | 600 | } else { |
| @@ -672,12 +666,17 @@ out: | |||
| 672 | return; | 666 | return; |
| 673 | 667 | ||
| 674 | out_sched: | 668 | out_sched: |
| 669 | clear_bit(GLF_LOCK, &gl->gl_flags); | ||
| 670 | smp_mb__after_clear_bit(); | ||
| 675 | gfs2_glock_hold(gl); | 671 | gfs2_glock_hold(gl); |
| 676 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 672 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
| 677 | gfs2_glock_put_nolock(gl); | 673 | gfs2_glock_put_nolock(gl); |
| 674 | return; | ||
| 675 | |||
| 678 | out_unlock: | 676 | out_unlock: |
| 679 | clear_bit(GLF_LOCK, &gl->gl_flags); | 677 | clear_bit(GLF_LOCK, &gl->gl_flags); |
| 680 | goto out; | 678 | smp_mb__after_clear_bit(); |
| 679 | return; | ||
| 681 | } | 680 | } |
| 682 | 681 | ||
| 683 | static void delete_work_func(struct work_struct *work) | 682 | static void delete_work_func(struct work_struct *work) |
| @@ -707,9 +706,12 @@ static void glock_work_func(struct work_struct *work) | |||
| 707 | { | 706 | { |
| 708 | unsigned long delay = 0; | 707 | unsigned long delay = 0; |
| 709 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work); | 708 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work); |
| 709 | int drop_ref = 0; | ||
| 710 | 710 | ||
| 711 | if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) | 711 | if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) { |
| 712 | finish_xmote(gl, gl->gl_reply); | 712 | finish_xmote(gl, gl->gl_reply); |
| 713 | drop_ref = 1; | ||
| 714 | } | ||
| 713 | down_read(&gfs2_umount_flush_sem); | 715 | down_read(&gfs2_umount_flush_sem); |
| 714 | spin_lock(&gl->gl_spin); | 716 | spin_lock(&gl->gl_spin); |
| 715 | if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && | 717 | if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && |
| @@ -727,6 +729,8 @@ static void glock_work_func(struct work_struct *work) | |||
| 727 | if (!delay || | 729 | if (!delay || |
| 728 | queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | 730 | queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) |
| 729 | gfs2_glock_put(gl); | 731 | gfs2_glock_put(gl); |
| 732 | if (drop_ref) | ||
| 733 | gfs2_glock_put(gl); | ||
| 730 | } | 734 | } |
| 731 | 735 | ||
| 732 | /** | 736 | /** |
| @@ -1361,10 +1365,6 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask) | |||
| 1361 | list_del_init(&gl->gl_lru); | 1365 | list_del_init(&gl->gl_lru); |
| 1362 | atomic_dec(&lru_count); | 1366 | atomic_dec(&lru_count); |
| 1363 | 1367 | ||
| 1364 | /* Check if glock is about to be freed */ | ||
| 1365 | if (atomic_read(&gl->gl_ref) == 0) | ||
| 1366 | continue; | ||
| 1367 | |||
| 1368 | /* Test for being demotable */ | 1368 | /* Test for being demotable */ |
| 1369 | if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { | 1369 | if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { |
| 1370 | gfs2_glock_hold(gl); | 1370 | gfs2_glock_hold(gl); |
| @@ -1375,10 +1375,11 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask) | |||
| 1375 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1375 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
| 1376 | nr--; | 1376 | nr--; |
| 1377 | } | 1377 | } |
| 1378 | clear_bit(GLF_LOCK, &gl->gl_flags); | ||
| 1379 | smp_mb__after_clear_bit(); | ||
| 1378 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1380 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
| 1379 | gfs2_glock_put_nolock(gl); | 1381 | gfs2_glock_put_nolock(gl); |
| 1380 | spin_unlock(&gl->gl_spin); | 1382 | spin_unlock(&gl->gl_spin); |
| 1381 | clear_bit(GLF_LOCK, &gl->gl_flags); | ||
| 1382 | spin_lock(&lru_lock); | 1383 | spin_lock(&lru_lock); |
| 1383 | continue; | 1384 | continue; |
| 1384 | } | 1385 | } |
