[PATCH v3 4/4] gfs2: protect demote requests during superblock teardown
From: Jiacheng Xu
Date: Sun Sep 20 2026 - 04:32:50 EST
The demote_rq sysfs callback can obtain a glock while unmount is
tearing down the glock hash and destroying sd_glock_wq. The callback
may then queue work through the destroyed workqueue.
Serialize the complete demote operation with s_umount and reject
requests while the superblock is not active. trylock semantics avoid
deadlocking with mount failure and unmount paths that remove sysfs.
Signed-off-by: Jiacheng Xu <stitch@xxxxxxxxxx>
---
fs/gfs2/sys.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index c5868354073a..c5c540fcce92 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -334,6 +334,7 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
+ struct super_block *sb = sdp->sd_vfs;
struct gfs2_glock *gl;
const struct gfs2_glock_operations *glops;
unsigned int glmode;
@@ -367,14 +368,22 @@ static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len
glops = gfs2_glops_list[gltype];
if (glops == NULL)
return -EINVAL;
+
+ if (!super_trylock_shared_active(sb))
+ return -EAGAIN;
+
if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
fs_info(sdp, "demote interface used\n");
rv = gfs2_glock_get(sdp, glnum, glops, NO_CREATE, &gl);
if (rv)
- return rv;
+ goto out_unlock;
gfs2_glock_cb(gl, glmode);
gfs2_glock_put(gl);
- return len;
+ rv = 0;
+
+out_unlock:
+ super_unlock_active(sb);
+ return rv ? rv : len;
}
--
2.51.0