diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index b3ed58551e74..384cae623ed3 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -422,11 +422,11 @@ void gfs2_holder_uninit(struct gfs2_holder *gh) | |||
422 | static void gfs2_holder_wake(struct gfs2_holder *gh) | 422 | static void gfs2_holder_wake(struct gfs2_holder *gh) |
423 | { | 423 | { |
424 | clear_bit(HIF_WAIT, &gh->gh_iflags); | 424 | clear_bit(HIF_WAIT, &gh->gh_iflags); |
425 | smp_mb(); | 425 | smp_mb__after_clear_bit(); |
426 | wake_up_bit(&gh->gh_iflags, HIF_WAIT); | 426 | wake_up_bit(&gh->gh_iflags, HIF_WAIT); |
427 | } | 427 | } |
428 | 428 | ||
429 | static int holder_wait(void *word) | 429 | static int just_schedule(void *word) |
430 | { | 430 | { |
431 | schedule(); | 431 | schedule(); |
432 | return 0; | 432 | return 0; |
@@ -435,7 +435,20 @@ static int holder_wait(void *word) | |||
435 | static void wait_on_holder(struct gfs2_holder *gh) | 435 | static void wait_on_holder(struct gfs2_holder *gh) |
436 | { | 436 | { |
437 | might_sleep(); | 437 | might_sleep(); |
438 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, holder_wait, TASK_UNINTERRUPTIBLE); | 438 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE); |
439 | } | ||
440 | |||
441 | static void gfs2_demote_wake(struct gfs2_glock *gl) | ||
442 | { | ||
443 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | ||
444 | smp_mb__after_clear_bit(); | ||
445 | wake_up_bit(&gl->gl_flags, GLF_DEMOTE); | ||
446 | } | ||
447 | |||
448 | static void wait_on_demote(struct gfs2_glock *gl) | ||
449 | { | ||
450 | might_sleep(); | ||
451 | wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE); | ||
439 | } | 452 | } |
440 | 453 | ||
441 | /** | 454 | /** |
@@ -528,7 +541,7 @@ static int rq_demote(struct gfs2_glock *gl) | |||
528 | 541 | ||
529 | if (gl->gl_state == gl->gl_demote_state || | 542 | if (gl->gl_state == gl->gl_demote_state || |
530 | gl->gl_state == LM_ST_UNLOCKED) { | 543 | gl->gl_state == LM_ST_UNLOCKED) { |
531 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 544 | gfs2_demote_wake(gl); |
532 | return 0; | 545 | return 0; |
533 | } | 546 | } |
534 | set_bit(GLF_LOCK, &gl->gl_flags); | 547 | set_bit(GLF_LOCK, &gl->gl_flags); |
@@ -666,12 +679,22 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl) | |||
666 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED | 679 | * practise: LM_ST_SHARED and LM_ST_UNLOCKED |
667 | */ | 680 | */ |
668 | 681 | ||
669 | static void handle_callback(struct gfs2_glock *gl, unsigned int state) | 682 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote) |
670 | { | 683 | { |
671 | spin_lock(&gl->gl_spin); | 684 | spin_lock(&gl->gl_spin); |
672 | if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { | 685 | if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { |
673 | gl->gl_demote_state = state; | 686 | gl->gl_demote_state = state; |
674 | gl->gl_demote_time = jiffies; | 687 | gl->gl_demote_time = jiffies; |
688 | if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && | ||
689 | gl->gl_object) { | ||
690 | struct inode *inode = igrab(gl->gl_object); | ||
691 | spin_unlock(&gl->gl_spin); | ||
692 | if (inode) { | ||
693 | d_prune_aliases(inode); | ||
694 | iput(inode); | ||
695 | } | ||
696 | return; | ||
697 | } | ||
675 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { | 698 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { |
676 | gl->gl_demote_state = state; | 699 | gl->gl_demote_state = state; |
677 | } | 700 | } |
@@ -740,7 +763,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
740 | if (ret & LM_OUT_CANCELED) | 763 | if (ret & LM_OUT_CANCELED) |
741 | op_done = 0; | 764 | op_done = 0; |
742 | else | 765 | else |
743 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 766 | gfs2_demote_wake(gl); |
744 | } else { | 767 | } else { |
745 | spin_lock(&gl->gl_spin); | 768 | spin_lock(&gl->gl_spin); |
746 | list_del_init(&gh->gh_list); | 769 | list_del_init(&gh->gh_list); |
@@ -848,7 +871,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
848 | gfs2_assert_warn(sdp, !ret); | 871 | gfs2_assert_warn(sdp, !ret); |
849 | 872 | ||
850 | state_change(gl, LM_ST_UNLOCKED); | 873 | state_change(gl, LM_ST_UNLOCKED); |
851 | clear_bit(GLF_DEMOTE, &gl->gl_flags); | 874 | gfs2_demote_wake(gl); |
852 | 875 | ||
853 | if (glops->go_inval) | 876 | if (glops->go_inval) |
854 | glops->go_inval(gl, DIO_METADATA); | 877 | glops->go_inval(gl, DIO_METADATA); |
@@ -1174,7 +1197,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1174 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 1197 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
1175 | 1198 | ||
1176 | if (gh->gh_flags & GL_NOCACHE) | 1199 | if (gh->gh_flags & GL_NOCACHE) |
1177 | handle_callback(gl, LM_ST_UNLOCKED); | 1200 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1178 | 1201 | ||
1179 | gfs2_glmutex_lock(gl); | 1202 | gfs2_glmutex_lock(gl); |
1180 | 1203 | ||
@@ -1196,6 +1219,13 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1196 | spin_unlock(&gl->gl_spin); | 1219 | spin_unlock(&gl->gl_spin); |
1197 | } | 1220 | } |
1198 | 1221 | ||
1222 | void gfs2_glock_dq_wait(struct gfs2_holder *gh) | ||
1223 | { | ||
1224 | struct gfs2_glock *gl = gh->gh_gl; | ||
1225 | gfs2_glock_dq(gh); | ||
1226 | wait_on_demote(gl); | ||
1227 | } | ||
1228 | |||
1199 | /** | 1229 | /** |
1200 | * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it | 1230 | * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it |
1201 | * @gh: the holder structure | 1231 | * @gh: the holder structure |
@@ -1456,7 +1486,7 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name, | |||
1456 | if (!gl) | 1486 | if (!gl) |
1457 | return; | 1487 | return; |
1458 | 1488 | ||
1459 | handle_callback(gl, state); | 1489 | handle_callback(gl, state, 1); |
1460 | 1490 | ||
1461 | spin_lock(&gl->gl_spin); | 1491 | spin_lock(&gl->gl_spin); |
1462 | run_queue(gl); | 1492 | run_queue(gl); |
@@ -1596,7 +1626,7 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp) | |||
1596 | if (gfs2_glmutex_trylock(gl)) { | 1626 | if (gfs2_glmutex_trylock(gl)) { |
1597 | if (list_empty(&gl->gl_holders) && | 1627 | if (list_empty(&gl->gl_holders) && |
1598 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) | 1628 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) |
1599 | handle_callback(gl, LM_ST_UNLOCKED); | 1629 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1600 | gfs2_glmutex_unlock(gl); | 1630 | gfs2_glmutex_unlock(gl); |
1601 | } | 1631 | } |
1602 | 1632 | ||
@@ -1709,7 +1739,7 @@ static void clear_glock(struct gfs2_glock *gl) | |||
1709 | if (gfs2_glmutex_trylock(gl)) { | 1739 | if (gfs2_glmutex_trylock(gl)) { |
1710 | if (list_empty(&gl->gl_holders) && | 1740 | if (list_empty(&gl->gl_holders) && |
1711 | gl->gl_state != LM_ST_UNLOCKED) | 1741 | gl->gl_state != LM_ST_UNLOCKED) |
1712 | handle_callback(gl, LM_ST_UNLOCKED); | 1742 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1713 | gfs2_glmutex_unlock(gl); | 1743 | gfs2_glmutex_unlock(gl); |
1714 | } | 1744 | } |
1715 | } | 1745 | } |