aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-07-07 05:02:36 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2008-07-07 05:02:36 -0400
commit265d529cef6fd57698d79b3c0edd3a8178059ea6 (patch)
treed92cc42c3f9db89bdce635a78f9d8d1904dde43a /fs/gfs2/glock.c
parentf58ba889106af60f52af792efbe1973e458a2138 (diff)
[GFS2] Fix delayed demote race
There is a race in the delayed demote code where it does the wrong thing if a demotion to UN has occurred for other reasons before the delay has expired. This patch adds an assert to catch that condition as well as fixing the root cause by adding an additional check for the UN state. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 8d5450f3c3ef..cd0aa213fb2f 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -587,6 +587,7 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock)
587 if (nonblock) 587 if (nonblock)
588 goto out_sched; 588 goto out_sched;
589 set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); 589 set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
590 GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE);
590 gl->gl_target = gl->gl_demote_state; 591 gl->gl_target = gl->gl_demote_state;
591 } else { 592 } else {
592 if (test_bit(GLF_DEMOTE, &gl->gl_flags)) 593 if (test_bit(GLF_DEMOTE, &gl->gl_flags))
@@ -617,7 +618,9 @@ static void glock_work_func(struct work_struct *work)
617 if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) 618 if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags))
618 finish_xmote(gl, gl->gl_reply); 619 finish_xmote(gl, gl->gl_reply);
619 spin_lock(&gl->gl_spin); 620 spin_lock(&gl->gl_spin);
620 if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags)) { 621 if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
622 gl->gl_state != LM_ST_UNLOCKED &&
623 gl->gl_demote_state != LM_ST_EXCLUSIVE) {
621 unsigned long holdtime, now = jiffies; 624 unsigned long holdtime, now = jiffies;
622 holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; 625 holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
623 if (time_before(now, holdtime)) 626 if (time_before(now, holdtime))