diff options
author | Bob Peterson <rpeterso@redhat.com> | 2021-05-18 09:12:10 -0400 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2021-05-20 13:31:37 +0200 |
commit | 20265d9a67e40eafd39a8884658ca2e36f05985d (patch) | |
tree | f944efab603c456faf64c95ae23c783ba011dd3e /fs/gfs2 | |
parent | 4194dec4b4169e5a9a5171db60c2ec00c4d8cf16 (diff) | |
download | lwn-20265d9a67e40eafd39a8884658ca2e36f05985d.tar.gz lwn-20265d9a67e40eafd39a8884658ca2e36f05985d.zip |
gfs2: fix scheduling while atomic bug in glocks
Before this patch, in the unlikely event that gfs2_glock_dq encountered
a withdraw, it would do a wait_on_bit to wait for its journal to be
recovered, but it never released the glock's spin_lock, which caused a
scheduling-while-atomic error.
This patch unlocks the lockref spin_lock before waiting for recovery.
Fixes: 601ef0d52e96 ("gfs2: Force withdraw to replay journals and wait for it to finish")
Cc: stable@vger.kernel.org # v5.7+
Reported-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index ea7fc5c641c7..8c547db210fb 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1466,9 +1466,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh) glock_blocked_by_withdraw(gl) && gh->gh_gl != sdp->sd_jinode_gl) { sdp->sd_glock_dqs_held++; + spin_unlock(&gl->gl_lockref.lock); might_sleep(); wait_on_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY, TASK_UNINTERRUPTIBLE); + spin_lock(&gl->gl_lockref.lock); } if (gh->gh_flags & GL_NOCACHE) handle_callback(gl, LM_ST_UNLOCKED, 0, false); |