From: Andreas Gruenbacher Date: Thu, 12 Sep 2024 21:29:41 +0000 (+0200) Subject: gfs2: Clean up delete work processing X-Git-Tag: v6.13-rc1~79^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0baa10b60cddb587a1a252a8db76b0cea439d1be;p=thirdparty%2Fkernel%2Flinux.git gfs2: Clean up delete work processing Function delete_work_func() was previously assuming that the GLF_TRY_TO_EVICT and GLF_VERIFY_DELETE flags won't both be set at the same time, but there probably are races in which that can happen, so handle that case correctly. Signed-off-by: Andreas Gruenbacher --- diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 9ec305b8d4d43..95f082f13a8c5 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1028,6 +1028,7 @@ static void delete_work_func(struct work_struct *work) struct delayed_work *dwork = to_delayed_work(work); struct gfs2_glock *gl = container_of(dwork, struct gfs2_glock, gl_delete); struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + bool verify_delete = test_and_clear_bit(GLF_VERIFY_DELETE, &gl->gl_flags); if (test_and_clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags)) { /* @@ -1048,15 +1049,15 @@ static void delete_work_func(struct work_struct *work) * step entirely. */ if (gfs2_try_evict(gl)) { - if (test_bit(SDF_KILL, &sdp->sd_flags)) - goto out; - if (gfs2_queue_verify_delete(gl, true)) - return; + if (!test_bit(SDF_KILL, &sdp->sd_flags)) { + gfs2_glock_hold(gl); + if (!gfs2_queue_verify_delete(gl, true)) + gfs2_glock_put(gl); + } } - goto out; } - if (test_and_clear_bit(GLF_VERIFY_DELETE, &gl->gl_flags)) { + if (verify_delete) { u64 no_addr = gl->gl_name.ln_number; struct inode *inode; @@ -1073,7 +1074,6 @@ static void delete_work_func(struct work_struct *work) } } -out: gfs2_glock_put(gl); }