Skip to content

Commit a431d49

Browse files
author
Andreas Gruenbacher
committed
gfs2: Fix request cancelation bug
In finish_xmote(), when a locking request is canceled, the corresponding holder is moved to the tail of the holders list instead of being dequeued immediately. When there is only a single holder, the canceled locking request is then immediately repeated. This makes no sense; it looks like another remnant of LM_FLAG_PRIORITY support. Instead, dequeue canceled holders and proceed with the next holder in finish_xmote(). We can then easily detect in gfs2_glock_dq() when a holder has been canceled. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent d838605 commit a431d49

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

fs/gfs2/glock.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -607,14 +607,19 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
607607
if (gh && (ret & LM_OUT_CANCELED))
608608
gfs2_holder_wake(gh);
609609
if (gh && !test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags)) {
610-
/* move to back of queue and try next entry */
611610
if (ret & LM_OUT_CANCELED) {
612-
list_move_tail(&gh->gh_list, &gl->gl_holders);
611+
list_del_init(&gh->gh_list);
612+
trace_gfs2_glock_queue(gh, 0);
613+
gl->gl_target = gl->gl_state;
613614
gh = find_first_waiter(gl);
614-
gl->gl_target = gh->gh_state;
615-
if (do_promote(gl))
616-
goto out;
617-
goto retry;
615+
if (gh) {
616+
gl->gl_target = gh->gh_state;
617+
if (do_promote(gl))
618+
goto out;
619+
do_xmote(gl, gh, gl->gl_target);
620+
return;
621+
}
622+
goto out;
618623
}
619624
/* Some error or failed "try lock" - report it */
620625
if ((ret & LM_OUT_ERROR) ||
@@ -627,7 +632,6 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
627632
switch(state) {
628633
/* Unlocked due to conversion deadlock, try again */
629634
case LM_ST_UNLOCKED:
630-
retry:
631635
do_xmote(gl, gh, gl->gl_target);
632636
break;
633637
/* Conversion fails, unlock and try again */
@@ -1672,6 +1676,8 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
16721676
gl->gl_name.ln_sbd->sd_lockstruct.ls_ops->lm_cancel(gl);
16731677
wait_on_bit(&gh->gh_iflags, HIF_WAIT, TASK_UNINTERRUPTIBLE);
16741678
spin_lock(&gl->gl_lockref.lock);
1679+
if (!gfs2_holder_queued(gh))
1680+
goto out;
16751681
}
16761682

16771683
/*

0 commit comments

Comments
 (0)