Commit 265d529cef6fd57698d79b3c0edd3a8178059ea6
1 parent
f58ba88910
Exists in
master
and in
7 other branches
[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>
Showing 1 changed file with 4 additions and 1 deletions Side-by-side Diff
fs/gfs2/glock.c
... | ... | @@ -587,6 +587,7 @@ |
587 | 587 | if (nonblock) |
588 | 588 | goto out_sched; |
589 | 589 | set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); |
590 | + GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE); | |
590 | 591 | gl->gl_target = gl->gl_demote_state; |
591 | 592 | } else { |
592 | 593 | if (test_bit(GLF_DEMOTE, &gl->gl_flags)) |
... | ... | @@ -617,7 +618,9 @@ |
617 | 618 | if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) |
618 | 619 | finish_xmote(gl, gl->gl_reply); |
619 | 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 | 624 | unsigned long holdtime, now = jiffies; |
622 | 625 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; |
623 | 626 | if (time_before(now, holdtime)) |