gfs2: Check for empty queue in run_queue
[ Upstream commit d838605fea6eabae3746a276fd448f6719eb3926 ] In run_queue(), check if the queue of pending requests is empty instead of blindly assuming that it won't be. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
2e37d331c0
commit
769d1bccd1
@@ -853,11 +853,12 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock)
|
|||||||
__releases(&gl->gl_lockref.lock)
|
__releases(&gl->gl_lockref.lock)
|
||||||
__acquires(&gl->gl_lockref.lock)
|
__acquires(&gl->gl_lockref.lock)
|
||||||
{
|
{
|
||||||
struct gfs2_holder *gh = NULL;
|
struct gfs2_holder *gh;
|
||||||
|
|
||||||
if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
|
if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* While a demote is in progress, the GLF_LOCK flag must be set. */
|
||||||
GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags));
|
GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags));
|
||||||
|
|
||||||
if (test_bit(GLF_DEMOTE, &gl->gl_flags) &&
|
if (test_bit(GLF_DEMOTE, &gl->gl_flags) &&
|
||||||
@@ -869,18 +870,22 @@ __acquires(&gl->gl_lockref.lock)
|
|||||||
set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
|
set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
|
||||||
GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE);
|
GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE);
|
||||||
gl->gl_target = gl->gl_demote_state;
|
gl->gl_target = gl->gl_demote_state;
|
||||||
|
do_xmote(gl, NULL, gl->gl_target);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (test_bit(GLF_DEMOTE, &gl->gl_flags))
|
if (test_bit(GLF_DEMOTE, &gl->gl_flags))
|
||||||
gfs2_demote_wake(gl);
|
gfs2_demote_wake(gl);
|
||||||
if (do_promote(gl))
|
if (do_promote(gl))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
gh = find_first_waiter(gl);
|
gh = find_first_waiter(gl);
|
||||||
|
if (!gh)
|
||||||
|
goto out_unlock;
|
||||||
gl->gl_target = gh->gh_state;
|
gl->gl_target = gh->gh_state;
|
||||||
if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
|
if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
|
||||||
do_error(gl, 0); /* Fail queued try locks */
|
do_error(gl, 0); /* Fail queued try locks */
|
||||||
|
do_xmote(gl, gh, gl->gl_target);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
do_xmote(gl, gh, gl->gl_target);
|
|
||||||
return;
|
|
||||||
|
|
||||||
out_sched:
|
out_sched:
|
||||||
clear_bit(GLF_LOCK, &gl->gl_flags);
|
clear_bit(GLF_LOCK, &gl->gl_flags);
|
||||||
|
Reference in New Issue
Block a user