From nobody Mon Sep 28 14:47:12 2026 Received: from azure-sdnproxy.icoremail.net (azure-sdnproxy.icoremail.net [13.75.44.102]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6DDD530D3FF for ; Fri, 21 Aug 2026 04:11:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.75.44.102 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285521; cv=none; b=Bex146ySA6N6UEJIk3Q6U9uAm3GUzkYolm5A6Lm3NP+XVAE7PJgnaMubTl/H4quddUh+F+qs/UEC3FPZ/URikkA/FHflCLVcB1cnQi5o08CMrTlsL8pPvrYjfUWhannKx/EFnnQvsDfrGdRIzVm5+xepgIMJ1+9AnUG6CDhyXQI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285521; c=relaxed/simple; bh=TvvW9Yj8lfRbmwzYyg06PReI+La2u5Ur66VQ/yFMs7g=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=fUH1KbyLHiesmT4U455yEA57sLCgA37TJs+dWVaIAq3K3JsqGZzMBDbwus0ZgofR5tWjfHeHVQiYGuk/HlHBdPa+uSabdFhaB2LbnxbI3o/wa03VhCxLPfvnQe1YUXDflAagkb+lQ4tcAbL8lXZ0ktFnqNt7U4bo4psIl5EZVDo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn; spf=pass smtp.mailfrom=zju.edu.cn; arc=none smtp.client-ip=13.75.44.102 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zju.edu.cn Received: from zju.edu.cn (unknown [10.190.129.65]) by mtasvr (Coremail) with SMTP id _____wAH8TYK0Idqup2wAA--.10763S3; Fri, 21 Aug 2026 12:11:54 +0800 (CST) Received: from stitch$zju.edu.cn ( [10.190.129.65] ) by ajax-webmail-mail-app3 (Coremail) ; Fri, 21 Aug 2026 12:11:53 +0800 (GMT+08:00) Date: Fri, 21 Aug 2026 12:11:53 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Jiacheng Xu" To: "Andreas Gruenbacher" Cc: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/5] gfs2: protect quota refresh from superblock teardown X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2025.3-cmXT6 build 20260617(6f868824) Copyright (c) 2002-2026 www.mailtech.cn zju.edu.cn In-Reply-To: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> References: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <42b8a85f.162c4.1a02284a6da.Coremail.stitch@zju.edu.cn> X-Coremail-Locale: zh_CN X-CM-TRANSID: zS_KCgC3oncJ0IdqE+qNBA--.24696W X-CM-SenderInfo: qtrxiiaqttimo62m3hxhgxhubq/1tbiAwQJC2qGXxcNSAAFsh X-CM-DELIVERINFO: =?B?NUT0xwXKKxbFmtjJiESix3B1w3tMoM3snk/k5SVzZVydjEqe1eefKHnLf95EnB4iem egW9p9QbwFO/M6dbbDVJYHFkbukLGKhicS5+qqIqsPA4n5zu03F8m2kMq7pX/yo13R3fBi JBUm3IRBay9n0E9oY7jv4JWfJdYHBuv6fQUOO6pruRvTMZr4W/HzcqpKp2CMQQ== X-Coremail-Antispam: 1Uk129KBj93XoW3ArWfAryUAFyrAF1rKr4ftFc_yoWxCFW7pF 4qvay5Gr4DGr17ursIy3WrWa4Fg3yfuF47Ar1Ig3W7AryqyrsagFy7tF10vFWUGwsFyw15 XF40gasI9ryDGrXCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUPGb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AK xVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0Y48IcxkI7V AKI48G6xCjnVAKz4kxM4xvF2IEb7IF0Fy264kE64k0F24lFcxC0VAYjxAxZF0Ex2IqxwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jrv_JF1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Jr0_Gr1l6VACY4xI67k04243AbIYCTnIWIevJa73UjIFyTuYvj xU7LZcUUUUU Content-Type: text/plain; charset="utf-8" The quota_refresh sysfs attributes become visible before fill_super() has completed, so the quota inode can still be uninitialized when a userspace write reaches gfs2_quota_refresh(). The same callback can also race with superblock teardown. Serialize the callback with the superblock lifetime using a read-side s_umount lock. Use down_read_trylock() so the mount failure path can remove the sysfs files while holding the write side of the lock without deadlocking, and reject accesses before SB_ACTIVE is set. Return -EAGAIN when the filesystem is not available for the callback. Tested-by: Jiacheng Xu Signed-off-by: Jiacheng Xu --- fs/gfs2/quota.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 001c8b39ca55..d065b51950d7 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1384,19 +1384,36 @@ int gfs2_quota_sync(struct super_block *sb, int typ= e) =20 int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) { + struct super_block *sb =3D sdp->sd_vfs; struct gfs2_quota_data *qd; struct gfs2_holder q_gh; int error; =20 + /* + * The sysfs files are created before fill_super completes. Avoid + * blocking on s_umount because the mount failure path removes the + * sysfs files while holding it for writing. + */ + if (!down_read_trylock(&sb->s_umount)) + return -EAGAIN; + + if (!(sb->s_flags & SB_ACTIVE)) { + error =3D -EAGAIN; + goto out_unlock; + } + error =3D qd_get(sdp, qid, &qd); if (error) - return error; + goto out_unlock; =20 error =3D do_glock(qd, FORCE, &q_gh); if (!error) gfs2_glock_dq_uninit(&q_gh); =20 qd_put(qd); + +out_unlock: + up_read(&sb->s_umount); return error; } =20 --=20 2.25.1 > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-21 12:09:21 (=E6=98=9F=E6=9C= =9F=E4=BA=94) > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > =E4=B8=BB=E9=A2=98: [PATCH v2 0/5] gfs2: protect sysfs callbacks from sup= erblock teardown >=20 > The GFS2 sysfs files become visible before fill_super() completes and > remain present until after filesystem resources have been released. > Consequently, callbacks that access quota, statfs, glock or journal > state can race with mount failure rollback or unmount teardown. >=20 > The quota refresh fix was originally sent as a standalone [PATCH]. This > version folds it into a complete series and adds the corresponding > lifetime protection for the other affected sysfs callbacks. >=20 > All callbacks use down_read_trylock() on s_umount and verify SB_ACTIVE. > Returning -EAGAIN avoids deadlock when mount failure or unmount holds > the write side of s_umount while removing the sysfs files. >=20 > Changes in v2: > - Folded the original quota refresh fix into a five-patch series. > - Added statfs_sync, quota_sync, demote_rq and status fixes. >=20 > Jiacheng Xu (5): > gfs2: protect quota refresh from superblock teardown > gfs2: protect statfs sync sysfs callback > gfs2: protect quota sync sysfs callback > gfs2: protect demote requests during superblock teardown > gfs2: protect status sysfs reads during teardown >=20 > fs/gfs2/quota.c | 19 ++++++++++++++- > fs/gfs2/sys.c | 65 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 76 insertions(+), 8 deletions(-) >=20 >=20 > base-commit: 0f23d56f17fdfc7db69d51f64c8b91bbab947aa9 > --=20 > 2.25.1 >=20 > > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-19 15:01:07 (=E6=98=9F=E6= =9C=9F=E4=B8=89) > > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > > =E4=B8=BB=E9=A2=98: [PATCH] gfs2: Fix NULL pointer dereference in quota= refresh > >=20 > > The GFS2 sysfs files are registered before init_inodes() completes. > > Consequently, the quota_refresh_user and quota_refresh_group sysfs > > attributes can be accessed while sdp->sd_quota_inode has not been > > initialized yet. > >=20 > > A concurrent write to quota_refresh_user may then call do_glock(), which > > dereferences sdp->sd_quota_inode. This can result in a NULL pointer der= eference=20 > > in do_glock(). The same callback can also race with superblock > > teardown and access data after the filesystem has started to shut down. > >=20 > > Moving sysfs registration after init_inodes() would avoid the initializ= ation > > window, but is not suitable because the lock manager may need the GFS2 > > sysfs files during the remaining mount sequence. > >=20 > > Serialize gfs2_quota_refresh() with the superblock lifetime instead. > > Acquire s_umount for reading before accessing quota data. Mount failure= and > > unmount paths hold s_umount for writing, so this prevents the callback = from > > running while the superblock is being initialized or destroyed. > >=20 > > Use down_read_trylock() instead of down_read() because the mount failure > > path may already hold s_umount for writing while removing the sysfs fil= es. > > Returning -EAGAIN allows the sysfs write to fail without introducing a > > deadlock. > >=20 > > Also verify SB_ACTIVE after acquiring the read lock, since the sysfs > > attributes become visible before the superblock is fully active. > >=20 > > The reproducer of the issue is attached. After applying this patch,=20 > > the reproducer no longer triggers the kernel crash.=20 > >=20 > > Signed-off-by: Jiacheng Xu > > Tested-by: Jiacheng Xu > > --- > > fs/gfs2/quota.c | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > >=20 > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c > > index 001c8b39ca55..d50534ed9379 100644 > > --- a/fs/gfs2/quota.c > > +++ b/fs/gfs2/quota.c > > @@ -1384,19 +1384,36 @@ int gfs2_quota_sync(struct super_block *sb, int= type) > >=20 > > int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) > > { > > + struct super_block *sb =3D sdp->sd_vfs; > > struct gfs2_quota_data *qd; > > struct gfs2_holder q_gh; > > int error; > >=20 > > + /* > > + * The sysfs files are created before fill_super completes. Avoid > > + * blocking on s_umount because the mount failure path removes the > > + * sysfs files while holding it for writing. > > + */ > > + if (!down_read_trylock(&sb->s_umount)) > > + return -EAGAIN; > > + > > + if (!(sb->s_flags & SB_ACTIVE)) { > > + error =3D -EAGAIN; > > + goto out_unlock; > > + } > > + > > error =3D qd_get(sdp, qid, &qd); > > if (error) > > - return error; > > + goto out_unlock; > >=20 > > error =3D do_glock(qd, FORCE, &q_gh); > > if (!error) > > gfs2_glock_dq_uninit(&q_gh); > >=20 > > qd_put(qd); > >=20 > > +out_unlock: > > + up_read(&sb->s_umount); > > return error; > > } From nobody Mon Sep 28 14:47:12 2026 Received: from azure-sdnproxy.icoremail.net (azure-sdnproxy.icoremail.net [40.65.178.148]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CF10F339378 for ; Fri, 21 Aug 2026 04:14:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=40.65.178.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285661; cv=none; b=Q9z+0Tb4NeXgY11iMPzBLy2XYumeaVLwk7FalY58uFIuXdc1NKQ67uRku4GXhah94w+dINZ0dgxbzD6fFngbkk+NQK8ez6YEbKyBG4i7qFp8MoQyGsDYurLoHFICpNW92j03DB5CwQI6mzd5bIeOdDck28wwPE3gRRHjILI8aCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285661; c=relaxed/simple; bh=dQKjRS4x8i/ry5dOLFcbG3Od6ez9z1ZAuiQKyVVyEzY=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=eaN9WZKKoicFxE7JCcZukuAhcY1rIJWSbqPlvfo7nca66UzgUgoLWTF+qKJxXLJ3gAKUCnL3PvvLQW+8ohAynR2eZ2yzQcfbgY+lawRl3WU0zq6OJRbuW9ALNjtzpFdCpCiQ7+V2DUgkiGvRDDT0bojJgKme4ZP6tHDlZW1ySIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn; spf=pass smtp.mailfrom=zju.edu.cn; arc=none smtp.client-ip=40.65.178.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zju.edu.cn Received: from zju.edu.cn (unknown [10.190.129.65]) by mtasvr (Coremail) with SMTP id _____wBH8zyS0IdqX5+wAA--.11117S3; Fri, 21 Aug 2026 12:14:10 +0800 (CST) Received: from stitch$zju.edu.cn ( [10.190.129.65] ) by ajax-webmail-mail-app3 (Coremail) ; Fri, 21 Aug 2026 12:14:09 +0800 (GMT+08:00) Date: Fri, 21 Aug 2026 12:14:09 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Jiacheng Xu" To: "Andreas Gruenbacher" Cc: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/5] gfs2: protect statfs sync sysfs callback X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2025.3-cmXT6 build 20260617(6f868824) Copyright (c) 2002-2026 www.mailtech.cn zju.edu.cn In-Reply-To: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> References: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <709e3a0d.162ca.1a02286ba27.Coremail.stitch@zju.edu.cn> X-Coremail-Locale: zh_CN X-CM-TRANSID: zS_KCgBngHKR0Idqc+2NBA--.19918W X-CM-SenderInfo: qtrxiiaqttimo62m3hxhgxhubq/1tbiAwQJC2qGXxcNSAAGsi X-CM-DELIVERINFO: =?B?9bVDBgXKKxbFmtjJiESix3B1w3tMoM3snk/k5SVzZVydjEqe1eefKHnLf95EnB4iem egW9p9QbwFO/M6dbbDVJYHFkb54pQxkhfOdLJziqAONZcQZqCutf/cGF9Xc1WeBfhurScK +jAJ9Sp9NJx5A+t8mIHUunE5Ku2G8QHEZAKbhggYKrxBUx6YyzDh5SRSvmAkCw== X-Coremail-Antispam: 1Uk129KBj93XoW3GrWruF43Ww43KFWxGry5KFX_yoWxWFWfpF 4DZay5Cr4kGr17WayakF1rWa4Fg3yfuF47JryIg3W7Ar98twnIgFySqFy0vFy8GrZrCw1U Xr4vqasI9rWDGFXCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUPGb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AK xVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUXVWUAwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0Y48IcxkI7V AKI48G6xCjnVAKz4kxM4xvF2IEb7IF0Fy264kE64k0F24lFcxC0VAYjxAxZF0Ex2IqxwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jrv_JF1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Jr0_Gr1l6VACY4xI67k04243AbIYCTnIWIevJa73UjIFyTuYvj xU29YwDUUUU Content-Type: text/plain; charset="utf-8" The statfs_sync sysfs file remains accessible while gfs2_put_super() releases sd_statfs_inode during unmount. A concurrent write can then enter gfs2_statfs_sync() and dereference the released inode. Serialize the sysfs callback with the superblock lifetime. Use a non-blocking read lock so mount failure and unmount paths can remove the sysfs files while holding s_umount for writing, and reject access before the superblock becomes active. Signed-off-by: Jiacheng Xu --- fs/gfs2/sys.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index ea2c7b9e4a77..0e2d65982c29 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -210,6 +210,7 @@ static ssize_t withdraw_store(struct gfs2_sbd *sdp, con= st char *buf, size_t len) static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { + struct super_block *sb =3D sdp->sd_vfs; int error, val; =20 if (!capable(CAP_SYS_ADMIN)) @@ -222,8 +223,19 @@ static ssize_t statfs_sync_store(struct gfs2_sbd *sdp,= const char *buf, if (val !=3D 1) return -EINVAL; =20 - gfs2_statfs_sync(sdp->sd_vfs, 0); - return len; + if (!down_read_trylock(&sb->s_umount)) + return -EAGAIN; + + if (!(sb->s_flags & SB_ACTIVE)) { + error =3D -EAGAIN; + goto out_unlock; + } + + gfs2_statfs_sync(sb, 0); + +out_unlock: + up_read(&sb->s_umount); + return error ? error : len; } =20 static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, --=20 2.25.1 > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-21 12:09:21 (=E6=98=9F=E6=9C= =9F=E4=BA=94) > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > =E4=B8=BB=E9=A2=98: [PATCH v2 0/5] gfs2: protect sysfs callbacks from sup= erblock teardown >=20 > The GFS2 sysfs files become visible before fill_super() completes and > remain present until after filesystem resources have been released. > Consequently, callbacks that access quota, statfs, glock or journal > state can race with mount failure rollback or unmount teardown. >=20 > The quota refresh fix was originally sent as a standalone [PATCH]. This > version folds it into a complete series and adds the corresponding > lifetime protection for the other affected sysfs callbacks. >=20 > All callbacks use down_read_trylock() on s_umount and verify SB_ACTIVE. > Returning -EAGAIN avoids deadlock when mount failure or unmount holds > the write side of s_umount while removing the sysfs files. >=20 > Changes in v2: > - Folded the original quota refresh fix into a five-patch series. > - Added statfs_sync, quota_sync, demote_rq and status fixes. >=20 > Jiacheng Xu (5): > gfs2: protect quota refresh from superblock teardown > gfs2: protect statfs sync sysfs callback > gfs2: protect quota sync sysfs callback > gfs2: protect demote requests during superblock teardown > gfs2: protect status sysfs reads during teardown >=20 > fs/gfs2/quota.c | 19 ++++++++++++++- > fs/gfs2/sys.c | 65 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 76 insertions(+), 8 deletions(-) >=20 >=20 > base-commit: 0f23d56f17fdfc7db69d51f64c8b91bbab947aa9 > --=20 > 2.25.1 >=20 > > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-19 15:01:07 (=E6=98=9F=E6= =9C=9F=E4=B8=89) > > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > > =E4=B8=BB=E9=A2=98: [PATCH] gfs2: Fix NULL pointer dereference in quota= refresh > >=20 > > The GFS2 sysfs files are registered before init_inodes() completes. > > Consequently, the quota_refresh_user and quota_refresh_group sysfs > > attributes can be accessed while sdp->sd_quota_inode has not been > > initialized yet. > >=20 > > A concurrent write to quota_refresh_user may then call do_glock(), which > > dereferences sdp->sd_quota_inode. This can result in a NULL pointer der= eference=20 > > in do_glock(). The same callback can also race with superblock > > teardown and access data after the filesystem has started to shut down. > >=20 > > Moving sysfs registration after init_inodes() would avoid the initializ= ation > > window, but is not suitable because the lock manager may need the GFS2 > > sysfs files during the remaining mount sequence. > >=20 > > Serialize gfs2_quota_refresh() with the superblock lifetime instead. > > Acquire s_umount for reading before accessing quota data. Mount failure= and > > unmount paths hold s_umount for writing, so this prevents the callback = from > > running while the superblock is being initialized or destroyed. > >=20 > > Use down_read_trylock() instead of down_read() because the mount failure > > path may already hold s_umount for writing while removing the sysfs fil= es. > > Returning -EAGAIN allows the sysfs write to fail without introducing a > > deadlock. > >=20 > > Also verify SB_ACTIVE after acquiring the read lock, since the sysfs > > attributes become visible before the superblock is fully active. > >=20 > > The reproducer of the issue is attached. After applying this patch,=20 > > the reproducer no longer triggers the kernel crash.=20 > >=20 > > Signed-off-by: Jiacheng Xu > > Tested-by: Jiacheng Xu > > --- > > fs/gfs2/quota.c | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > >=20 > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c > > index 001c8b39ca55..d50534ed9379 100644 > > --- a/fs/gfs2/quota.c > > +++ b/fs/gfs2/quota.c > > @@ -1384,19 +1384,36 @@ int gfs2_quota_sync(struct super_block *sb, int= type) > >=20 > > int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) > > { > > + struct super_block *sb =3D sdp->sd_vfs; > > struct gfs2_quota_data *qd; > > struct gfs2_holder q_gh; > > int error; > >=20 > > + /* > > + * The sysfs files are created before fill_super completes. Avoid > > + * blocking on s_umount because the mount failure path removes the > > + * sysfs files while holding it for writing. > > + */ > > + if (!down_read_trylock(&sb->s_umount)) > > + return -EAGAIN; > > + > > + if (!(sb->s_flags & SB_ACTIVE)) { > > + error =3D -EAGAIN; > > + goto out_unlock; > > + } > > + > > error =3D qd_get(sdp, qid, &qd); > > if (error) > > - return error; > > + goto out_unlock; > >=20 > > error =3D do_glock(qd, FORCE, &q_gh); > > if (!error) > > gfs2_glock_dq_uninit(&q_gh); > >=20 > > qd_put(qd); > >=20 > > +out_unlock: > > + up_read(&sb->s_umount); > > return error; > > } From nobody Mon Sep 28 14:47:12 2026 Received: from zg8tmtyylji0my4xnjeumjiw.icoremail.net (zg8tmtyylji0my4xnjeumjiw.icoremail.net [162.243.161.220]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7DE6737B00E for ; Fri, 21 Aug 2026 04:15:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=162.243.161.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285707; cv=none; b=tjjnr1saIySOJDszJlk0DGgv5guT7mWyjmvWdQGr9F2IOJbR5bH5A1WwV/IiEVcpXvJGTb/+MLxp22mInJBJCMOFOAPop8PlGYL/n1tb4j2RkREsT8GQwq5t9TF4aWJASYNcDxMGU4nXidRZqANIqS7niyiDr/iXHc553/CilMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285707; c=relaxed/simple; bh=YW5I84G4bP6qI7hB41anPcWtGZh6Ggplsw+z84pHteE=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=SNqhjZSOBsyESsaM//e0XY/o8aBv40KA5Rb20RBakLRbxZrrNlVuQfvMksJeyujoBmfg12Td0zXvE3O3o3sCG4AirE45B1PCz9Y7b4xULnPPQubQH7rALRONRJ3tpliuah6BETRDNBlOcBcpM514FSrCbr2QFA/tiT+J4Njm/Ko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn; spf=pass smtp.mailfrom=zju.edu.cn; arc=none smtp.client-ip=162.243.161.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zju.edu.cn Received: from zju.edu.cn (unknown [10.190.129.65]) by mtasvr (Coremail) with SMTP id _____wBnEz3E0Idqz5+wAA--.11013S3; Fri, 21 Aug 2026 12:15:00 +0800 (CST) Received: from stitch$zju.edu.cn ( [10.190.129.65] ) by ajax-webmail-mail-app3 (Coremail) ; Fri, 21 Aug 2026 12:14:59 +0800 (GMT+08:00) Date: Fri, 21 Aug 2026 12:14:59 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Jiacheng Xu" To: "Andreas Gruenbacher" Cc: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/5] gfs2: protect quota sync sysfs callback X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2025.3-cmXT6 build 20260617(6f868824) Copyright (c) 2002-2026 www.mailtech.cn zju.edu.cn In-Reply-To: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> References: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <2b17084e.162cb.1a022877d91.Coremail.stitch@zju.edu.cn> X-Coremail-Locale: zh_CN X-CM-TRANSID: zS_KCgDnsXXD0IdqZ+6NBA--.25461W X-CM-SenderInfo: qtrxiiaqttimo62m3hxhgxhubq/1tbiAwQJC2qGXxcNSAAHsj X-CM-DELIVERINFO: =?B?vzbmuQXKKxbFmtjJiESix3B1w3tMoM3snk/k5SVzZVydjEqe1eefKHnLf95EnB4iem egW9p9QbwFO/M6dbbDVJYHFkYZVCyhUtN23FgWKwQINYs9uGCIZHWPwAVxC/i9kS1+2X6z 1U2AS2zB/DfFrX2NtsADLkIYk2rYF5/76hBsvYvDZAzQpZCY0tmtBHpXTWN/1Q== X-Coremail-Antispam: 1Uk129KBj93XoWxKFWkCryUGryfJF43Xry8Xrc_yoWxXw1kpF 4qvay5Cr4kJr17uFW3KF4rWa4rW3yfuF47Jr4Ig3W7Ar98trsagFyIqFy0vFyUGwsrCr1U XF4vqasI9ryDGFXCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUPCb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AK xVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUXVWUAwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0Y48IcxkI7V AKI48G6xCjnVAKz4kxM4xvF2IEb7IF0Fy264kE64k0F24lFcxC0VAYjxAxZF0Ex2IqxwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jrv_JF1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Gr0_Gr1UMVCEFcxC0VAYjxAxZFUvcSsGvfC2KfnxnUUI43ZEXa 7IU8ag4PUUUUU== Content-Type: text/plain; charset="utf-8" The quota_sync sysfs callback can run while quota cleanup is releasing the quota bitmap and internal quota inodes during mount rollback or unmount. Hold s_umount for reading while synchronizing quota data and reject requests before the superblock is active. Use trylock semantics so the callback cannot deadlock with the write-side teardown path. Signed-off-by: Jiacheng Xu --- fs/gfs2/sys.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 0e2d65982c29..94b23a6d7efe 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -241,6 +241,7 @@ static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, = const char *buf, static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { + struct super_block *sb =3D sdp->sd_vfs; int error, val; =20 if (!capable(CAP_SYS_ADMIN)) @@ -253,8 +254,19 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, = const char *buf, if (val !=3D 1) return -EINVAL; =20 - gfs2_quota_sync(sdp->sd_vfs, 0); - return len; + if (!down_read_trylock(&sb->s_umount)) + return -EAGAIN; + + if (!(sb->s_flags & SB_ACTIVE)) { + error =3D -EAGAIN; + goto out_unlock; + } + + gfs2_quota_sync(sb, 0); + +out_unlock: + up_read(&sb->s_umount); + return error ? error : len; } =20 static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *= buf, --=20 2.25.1 > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-21 12:09:21 (=E6=98=9F=E6=9C= =9F=E4=BA=94) > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > =E4=B8=BB=E9=A2=98: [PATCH v2 0/5] gfs2: protect sysfs callbacks from sup= erblock teardown >=20 > The GFS2 sysfs files become visible before fill_super() completes and > remain present until after filesystem resources have been released. > Consequently, callbacks that access quota, statfs, glock or journal > state can race with mount failure rollback or unmount teardown. >=20 > The quota refresh fix was originally sent as a standalone [PATCH]. This > version folds it into a complete series and adds the corresponding > lifetime protection for the other affected sysfs callbacks. >=20 > All callbacks use down_read_trylock() on s_umount and verify SB_ACTIVE. > Returning -EAGAIN avoids deadlock when mount failure or unmount holds > the write side of s_umount while removing the sysfs files. >=20 > Changes in v2: > - Folded the original quota refresh fix into a five-patch series. > - Added statfs_sync, quota_sync, demote_rq and status fixes. >=20 > Jiacheng Xu (5): > gfs2: protect quota refresh from superblock teardown > gfs2: protect statfs sync sysfs callback > gfs2: protect quota sync sysfs callback > gfs2: protect demote requests during superblock teardown > gfs2: protect status sysfs reads during teardown >=20 > fs/gfs2/quota.c | 19 ++++++++++++++- > fs/gfs2/sys.c | 65 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 76 insertions(+), 8 deletions(-) >=20 >=20 > base-commit: 0f23d56f17fdfc7db69d51f64c8b91bbab947aa9 > --=20 > 2.25.1 >=20 > > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-19 15:01:07 (=E6=98=9F=E6= =9C=9F=E4=B8=89) > > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > > =E4=B8=BB=E9=A2=98: [PATCH] gfs2: Fix NULL pointer dereference in quota= refresh > >=20 > > The GFS2 sysfs files are registered before init_inodes() completes. > > Consequently, the quota_refresh_user and quota_refresh_group sysfs > > attributes can be accessed while sdp->sd_quota_inode has not been > > initialized yet. > >=20 > > A concurrent write to quota_refresh_user may then call do_glock(), which > > dereferences sdp->sd_quota_inode. This can result in a NULL pointer der= eference=20 > > in do_glock(). The same callback can also race with superblock > > teardown and access data after the filesystem has started to shut down. > >=20 > > Moving sysfs registration after init_inodes() would avoid the initializ= ation > > window, but is not suitable because the lock manager may need the GFS2 > > sysfs files during the remaining mount sequence. > >=20 > > Serialize gfs2_quota_refresh() with the superblock lifetime instead. > > Acquire s_umount for reading before accessing quota data. Mount failure= and > > unmount paths hold s_umount for writing, so this prevents the callback = from > > running while the superblock is being initialized or destroyed. > >=20 > > Use down_read_trylock() instead of down_read() because the mount failure > > path may already hold s_umount for writing while removing the sysfs fil= es. > > Returning -EAGAIN allows the sysfs write to fail without introducing a > > deadlock. > >=20 > > Also verify SB_ACTIVE after acquiring the read lock, since the sysfs > > attributes become visible before the superblock is fully active. > >=20 > > The reproducer of the issue is attached. After applying this patch,=20 > > the reproducer no longer triggers the kernel crash.=20 > >=20 > > Signed-off-by: Jiacheng Xu > > Tested-by: Jiacheng Xu > > --- > > fs/gfs2/quota.c | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > >=20 > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c > > index 001c8b39ca55..d50534ed9379 100644 > > --- a/fs/gfs2/quota.c > > +++ b/fs/gfs2/quota.c > > @@ -1384,19 +1384,36 @@ int gfs2_quota_sync(struct super_block *sb, int= type) > >=20 > > int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) > > { > > + struct super_block *sb =3D sdp->sd_vfs; > > struct gfs2_quota_data *qd; > > struct gfs2_holder q_gh; > > int error; > >=20 > > + /* > > + * The sysfs files are created before fill_super completes. Avoid > > + * blocking on s_umount because the mount failure path removes the > > + * sysfs files while holding it for writing. > > + */ > > + if (!down_read_trylock(&sb->s_umount)) > > + return -EAGAIN; > > + > > + if (!(sb->s_flags & SB_ACTIVE)) { > > + error =3D -EAGAIN; > > + goto out_unlock; > > + } > > + > > error =3D qd_get(sdp, qid, &qd); > > if (error) > > - return error; > > + goto out_unlock; > >=20 > > error =3D do_glock(qd, FORCE, &q_gh); > > if (!error) > > gfs2_glock_dq_uninit(&q_gh); > >=20 > > qd_put(qd); > >=20 > > +out_unlock: > > + up_read(&sb->s_umount); > > return error; > > } From nobody Mon Sep 28 14:47:12 2026 Received: from zg8tmtyylji0my4xnjeumjiw.icoremail.net (zg8tmtyylji0my4xnjeumjiw.icoremail.net [162.243.161.220]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4584D313543 for ; Fri, 21 Aug 2026 04:16:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=162.243.161.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285771; cv=none; b=R40r3+hLCA8b5NzvKe/In7XzhuL5GETQYHgRHEJhnZ3UqFg+ThojOIq6EJOg/LbXrViBl368H/Bq2wD7iDd7Jofqg0wi6urw4Cty8PxL9gxAIxPtluaXSGX6zk93ue5EDmAb/Ea6LDUkt+sK5NLH1PSGEst5KsOvymWYuOhDikM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285771; c=relaxed/simple; bh=VukrZm6YEZHEWKQ/6ANAOvRBud/xoXK4g/NupKUulcE=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=B/amojYDr6olptIWr8xP6xLhNEMaXTV6y3EEXSmku52VkP+z5pO2Jxk+C2+ywWtKNHgGgNjSJF+uN0x0/pR6hU6d8Uf0nUbyyGsMz3ATTU/aIZLhihu1ihbR9e2ShA6oHO4yOzymxxT8uS29e5ATPT5LG+GLsk7F37JomO2ChwU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn; spf=pass smtp.mailfrom=zju.edu.cn; arc=none smtp.client-ip=162.243.161.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zju.edu.cn Received: from zju.edu.cn (unknown [10.190.129.65]) by mtasvr (Coremail) with SMTP id _____wC3sD_90IdqYKCwAA--.10948S3; Fri, 21 Aug 2026 12:15:57 +0800 (CST) Received: from stitch$zju.edu.cn ( [10.190.129.65] ) by ajax-webmail-mail-app3 (Coremail) ; Fri, 21 Aug 2026 12:15:57 +0800 (GMT+08:00) Date: Fri, 21 Aug 2026 12:15:57 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Jiacheng Xu" To: "Andreas Gruenbacher" Cc: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/5] gfs2: protect demote requests during superblock X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2025.3-cmXT6 build 20260617(6f868824) Copyright (c) 2002-2026 www.mailtech.cn zju.edu.cn In-Reply-To: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> References: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <3ee7b770.162d1.1a022885d61.Coremail.stitch@zju.edu.cn> X-Coremail-Locale: zh_CN X-CM-TRANSID: zS_KCgBngHL90IdqXe+NBA--.19920W X-CM-SenderInfo: qtrxiiaqttimo62m3hxhgxhubq/1tbiAwQJC2qGXxcNSAAIss X-CM-DELIVERINFO: =?B?gckH8gXKKxbFmtjJiESix3B1w3tMoM3snk/k5SVzZVydjEqe1eefKHnLf95EnB4iem egW9p9QbwFO/M6dbbDVJYHFkZ8tOrTfRNhWv0XtHADsjPHTue9kye1RcsFm6ebIWvk4PAX aEMVeg7QKTAEsr5fj46rMnQzUTmpudiqhhTnJZh9KUn2G/FMb1FOqLBnRCtR/g== X-Coremail-Antispam: 1Uk129KBj93XoW3XFyxWrW7XryrWFWxZFWDAwc_yoWxAw4fpF 4qvay5Cr4kGr17uayS9a1rWa4Fg3yfuF47Ar1Ig3W7Ar90qrsagFyftFy0vFyrCws7Cr1j qF40qasI9ryDGFXCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUPCb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AK xVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUAVWUtwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0Y48IcxkI7V AKI48G6xCjnVAKz4kxM4xvF2IEb7IF0Fy264kE64k0F24lFcxC0VAYjxAxZF0Ex2IqxwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jrv_JF1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Gr0_Gr1UMVCEFcxC0VAYjxAxZFUvcSsGvfC2KfnxnUUI43ZEXa 7IU8TCJJUUUUU== Content-Type: text/plain; charset="utf-8" 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 --- fs/gfs2/sys.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 94b23a6d7efe..99596b1ac08b 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -315,6 +315,7 @@ static ssize_t quota_refresh_group_store(struct gfs2_sb= d *sdp, const char *buf, =20 static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size= _t len) { + struct super_block *sb =3D sdp->sd_vfs; struct gfs2_glock *gl; const struct gfs2_glock_operations *glops; unsigned int glmode; @@ -348,14 +349,27 @@ static ssize_t demote_rq_store(struct gfs2_sbd *sdp, = const char *buf, size_t len glops =3D gfs2_glops_list[gltype]; if (glops =3D=3D NULL) return -EINVAL; + + if (!down_read_trylock(&sb->s_umount)) + return -EAGAIN; + + if (!(sb->s_flags & SB_ACTIVE)) { + rv =3D -EAGAIN; + goto out_unlock; + } + if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags)) fs_info(sdp, "demote interface used\n"); rv =3D 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 =3D 0; + +out_unlock: + up_read(&sb->s_umount); + return rv ? rv : len; } =20 =20 --=20 2.25.1 > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-21 12:09:21 (=E6=98=9F=E6=9C= =9F=E4=BA=94) > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > =E4=B8=BB=E9=A2=98: [PATCH v2 0/5] gfs2: protect sysfs callbacks from sup= erblock teardown >=20 > The GFS2 sysfs files become visible before fill_super() completes and > remain present until after filesystem resources have been released. > Consequently, callbacks that access quota, statfs, glock or journal > state can race with mount failure rollback or unmount teardown. >=20 > The quota refresh fix was originally sent as a standalone [PATCH]. This > version folds it into a complete series and adds the corresponding > lifetime protection for the other affected sysfs callbacks. >=20 > All callbacks use down_read_trylock() on s_umount and verify SB_ACTIVE. > Returning -EAGAIN avoids deadlock when mount failure or unmount holds > the write side of s_umount while removing the sysfs files. >=20 > Changes in v2: > - Folded the original quota refresh fix into a five-patch series. > - Added statfs_sync, quota_sync, demote_rq and status fixes. >=20 > Jiacheng Xu (5): > gfs2: protect quota refresh from superblock teardown > gfs2: protect statfs sync sysfs callback > gfs2: protect quota sync sysfs callback > gfs2: protect demote requests during superblock teardown > gfs2: protect status sysfs reads during teardown >=20 > fs/gfs2/quota.c | 19 ++++++++++++++- > fs/gfs2/sys.c | 65 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 76 insertions(+), 8 deletions(-) >=20 >=20 > base-commit: 0f23d56f17fdfc7db69d51f64c8b91bbab947aa9 > --=20 > 2.25.1 >=20 > > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-19 15:01:07 (=E6=98=9F=E6= =9C=9F=E4=B8=89) > > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > > =E4=B8=BB=E9=A2=98: [PATCH] gfs2: Fix NULL pointer dereference in quota= refresh > >=20 > > The GFS2 sysfs files are registered before init_inodes() completes. > > Consequently, the quota_refresh_user and quota_refresh_group sysfs > > attributes can be accessed while sdp->sd_quota_inode has not been > > initialized yet. > >=20 > > A concurrent write to quota_refresh_user may then call do_glock(), which > > dereferences sdp->sd_quota_inode. This can result in a NULL pointer der= eference=20 > > in do_glock(). The same callback can also race with superblock > > teardown and access data after the filesystem has started to shut down. > >=20 > > Moving sysfs registration after init_inodes() would avoid the initializ= ation > > window, but is not suitable because the lock manager may need the GFS2 > > sysfs files during the remaining mount sequence. > >=20 > > Serialize gfs2_quota_refresh() with the superblock lifetime instead. > > Acquire s_umount for reading before accessing quota data. Mount failure= and > > unmount paths hold s_umount for writing, so this prevents the callback = from > > running while the superblock is being initialized or destroyed. > >=20 > > Use down_read_trylock() instead of down_read() because the mount failure > > path may already hold s_umount for writing while removing the sysfs fil= es. > > Returning -EAGAIN allows the sysfs write to fail without introducing a > > deadlock. > >=20 > > Also verify SB_ACTIVE after acquiring the read lock, since the sysfs > > attributes become visible before the superblock is fully active. > >=20 > > The reproducer of the issue is attached. After applying this patch,=20 > > the reproducer no longer triggers the kernel crash.=20 > >=20 > > Signed-off-by: Jiacheng Xu > > Tested-by: Jiacheng Xu > > --- > > fs/gfs2/quota.c | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > >=20 > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c > > index 001c8b39ca55..d50534ed9379 100644 > > --- a/fs/gfs2/quota.c > > +++ b/fs/gfs2/quota.c > > @@ -1384,19 +1384,36 @@ int gfs2_quota_sync(struct super_block *sb, int= type) > >=20 > > int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) > > { > > + struct super_block *sb =3D sdp->sd_vfs; > > struct gfs2_quota_data *qd; > > struct gfs2_holder q_gh; > > int error; > >=20 > > + /* > > + * The sysfs files are created before fill_super completes. Avoid > > + * blocking on s_umount because the mount failure path removes the > > + * sysfs files while holding it for writing. > > + */ > > + if (!down_read_trylock(&sb->s_umount)) > > + return -EAGAIN; > > + > > + if (!(sb->s_flags & SB_ACTIVE)) { > > + error =3D -EAGAIN; > > + goto out_unlock; > > + } > > + > > error =3D qd_get(sdp, qid, &qd); > > if (error) > > - return error; > > + goto out_unlock; > >=20 > > error =3D do_glock(qd, FORCE, &q_gh); > > if (!error) > > gfs2_glock_dq_uninit(&q_gh); > >=20 > > qd_put(qd); > >=20 > > +out_unlock: > > + up_read(&sb->s_umount); > > return error; > > } From nobody Mon Sep 28 14:47:12 2026 Received: from azure-sdnproxy.icoremail.net (azure-sdnproxy.icoremail.net [13.75.44.102]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 69EAF360EFA for ; Fri, 21 Aug 2026 04:16:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.75.44.102 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285821; cv=none; b=fpDXwhJ9U1iiI4z8RalV2YmxkCRiFXDvyQWBJc9iPZ+2i+MWowBkk32fGQoD5xLMLpph7cwTHnYukTtanky/nRMZP+GOJZbND/168nXuczrSnKcyld+syz5a3dsxKRbYw1xTUqiBVY+kVuPf9btsdxaF8gQTdwlAjuwXbZipHJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787285821; c=relaxed/simple; bh=RrXXq1WiyNn9wP9RK3pema77majpGIACQT7oKPUVwts=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=QZ9lc7c6yNrJSqOn/pT/pJaUNkCyQnHxrTH9u4/Gj7Glg3qwRkkEN+vfxO4yLnYqgwrikW9GIh6qaQaemPLHU9eSE1clEDC0qtWzNeIHZ4ibu7SW13l7IXHT4gPT9FHM36jzEg+HUuICwcVZUM35f1SWwmxRjdLIE+6PiTVAfeo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn; spf=pass smtp.mailfrom=zju.edu.cn; arc=none smtp.client-ip=13.75.44.102 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=zju.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zju.edu.cn Received: from zju.edu.cn (unknown [10.190.129.65]) by mtasvr (Coremail) with SMTP id _____wBXaygt0Ydq76CwAA--.11119S3; Fri, 21 Aug 2026 12:16:45 +0800 (CST) Received: from stitch$zju.edu.cn ( [10.190.129.65] ) by ajax-webmail-mail-app3 (Coremail) ; Fri, 21 Aug 2026 12:16:45 +0800 (GMT+08:00) Date: Fri, 21 Aug 2026 12:16:45 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Jiacheng Xu" To: "Andreas Gruenbacher" Cc: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/5] gfs2: protect status sysfs reads during teardown X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2025.3-cmXT6 build 20260617(6f868824) Copyright (c) 2002-2026 www.mailtech.cn zju.edu.cn In-Reply-To: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> References: <6a91508.162bd.1a0228251e8.Coremail.stitch@zju.edu.cn> Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <6ef42bba.162d3.1a022891a50.Coremail.stitch@zju.edu.cn> X-Coremail-Locale: zh_CN X-CM-TRANSID: zS_KCgDnsXUt0YdqMPCNBA--.25465W X-CM-SenderInfo: qtrxiiaqttimo62m3hxhgxhubq/1tbiAwQJC2qGXxcNSAAJst X-CM-DELIVERINFO: =?B?A03uKAXKKxbFmtjJiESix3B1w3tMoM3snk/k5SVzZVydjEqe1eefKHnLf95EnB4iem egW9p9QbwFO/M6dbbDVJYHFkbx64gIxmFjGKSPkVRyPlFbManS/GbhdGOH/gvpibxZ8+UZ AkA6TpbgLVMoi5/M2eZEQCCX+RsvKFgD3Ku+U0Jt4A8nOyuhRJBIKBgQUSWmpg== X-Coremail-Antispam: 1Uk129KBj93XoW3Ar4xCFWfGFy8CrWUWr45urX_yoWxXF18pF 4qvay5Cr4kGr17uayakF1rWa4rW3yfuFW7Jr4Sg3W3Zr9rtrsagFyIqFy0vryUCrsrCw1j qF40qasI9ryDGrXCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUPCb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AK xVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUAVWUtwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0Y48IcxkI7V AKI48G6xCjnVAKz4kxM4xvF2IEb7IF0Fy264kE64k0F24lFcxC0VAYjxAxZF0Ex2IqxwCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jrv_JF1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Gr0_Gr1UMVCEFcxC0VAYjxAxZFUvcSsGvfC2KfnxnUUI43ZEXa 7IU8TCJJUUUUU== Content-Type: text/plain; charset="utf-8" status_show() reads sd_jdesc without synchronizing with gfs2_jindex_free(). The journal descriptor can be cleared and freed after the pointer is read but before its journal id is dereferenced. Serialize the complete status snapshot with the superblock lifetime and return -EAGAIN while the superblock is being initialized or shut down. Signed-off-by: Jiacheng Xu --- fs/gfs2/sys.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 99596b1ac08b..bfa3229e757d 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -65,9 +65,19 @@ static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) =20 static ssize_t status_show(struct gfs2_sbd *sdp, char *buf) { - unsigned long f =3D sdp->sd_flags; + struct super_block *sb =3D sdp->sd_vfs; + unsigned long f; ssize_t s; =20 + if (!down_read_trylock(&sb->s_umount)) + return -EAGAIN; + + if (!(sb->s_flags & SB_ACTIVE)) { + s =3D -EAGAIN; + goto out_unlock; + } + + f =3D sdp->sd_flags; s =3D sysfs_emit(buf, "Journal Checked: %d\n" "Journal Live: %d\n" @@ -125,6 +135,9 @@ static ssize_t status_show(struct gfs2_sbd *sdp, char *= buf) atomic_read(&sdp->sd_log_pinned), atomic_read(&sdp->sd_log_thresh1), atomic_read(&sdp->sd_log_thresh2)); + +out_unlock: + up_read(&sb->s_umount); return s; } =20 --=20 2.25.1 > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-21 12:09:21 (=E6=98=9F=E6=9C= =9F=E4=BA=94) > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > =E4=B8=BB=E9=A2=98: [PATCH v2 0/5] gfs2: protect sysfs callbacks from sup= erblock teardown >=20 > The GFS2 sysfs files become visible before fill_super() completes and > remain present until after filesystem resources have been released. > Consequently, callbacks that access quota, statfs, glock or journal > state can race with mount failure rollback or unmount teardown. >=20 > The quota refresh fix was originally sent as a standalone [PATCH]. This > version folds it into a complete series and adds the corresponding > lifetime protection for the other affected sysfs callbacks. >=20 > All callbacks use down_read_trylock() on s_umount and verify SB_ACTIVE. > Returning -EAGAIN avoids deadlock when mount failure or unmount holds > the write side of s_umount while removing the sysfs files. >=20 > Changes in v2: > - Folded the original quota refresh fix into a five-patch series. > - Added statfs_sync, quota_sync, demote_rq and status fixes. >=20 > Jiacheng Xu (5): > gfs2: protect quota refresh from superblock teardown > gfs2: protect statfs sync sysfs callback > gfs2: protect quota sync sysfs callback > gfs2: protect demote requests during superblock teardown > gfs2: protect status sysfs reads during teardown >=20 > fs/gfs2/quota.c | 19 ++++++++++++++- > fs/gfs2/sys.c | 65 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 76 insertions(+), 8 deletions(-) >=20 >=20 > base-commit: 0f23d56f17fdfc7db69d51f64c8b91bbab947aa9 > --=20 > 2.25.1 >=20 > > -----=E5=8E=9F=E5=A7=8B=E9=82=AE=E4=BB=B6----- > > =E5=8F=91=E4=BB=B6=E4=BA=BA: "Jiacheng Xu" > > =E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:2026-08-19 15:01:07 (=E6=98=9F=E6= =9C=9F=E4=B8=89) > > =E6=94=B6=E4=BB=B6=E4=BA=BA: "Andreas Gruenbacher" > > =E6=8A=84=E9=80=81: gfs2@lists.linux.dev, linux-kernel@vger.kernel.org > > =E4=B8=BB=E9=A2=98: [PATCH] gfs2: Fix NULL pointer dereference in quota= refresh > >=20 > > The GFS2 sysfs files are registered before init_inodes() completes. > > Consequently, the quota_refresh_user and quota_refresh_group sysfs > > attributes can be accessed while sdp->sd_quota_inode has not been > > initialized yet. > >=20 > > A concurrent write to quota_refresh_user may then call do_glock(), which > > dereferences sdp->sd_quota_inode. This can result in a NULL pointer der= eference=20 > > in do_glock(). The same callback can also race with superblock > > teardown and access data after the filesystem has started to shut down. > >=20 > > Moving sysfs registration after init_inodes() would avoid the initializ= ation > > window, but is not suitable because the lock manager may need the GFS2 > > sysfs files during the remaining mount sequence. > >=20 > > Serialize gfs2_quota_refresh() with the superblock lifetime instead. > > Acquire s_umount for reading before accessing quota data. Mount failure= and > > unmount paths hold s_umount for writing, so this prevents the callback = from > > running while the superblock is being initialized or destroyed. > >=20 > > Use down_read_trylock() instead of down_read() because the mount failure > > path may already hold s_umount for writing while removing the sysfs fil= es. > > Returning -EAGAIN allows the sysfs write to fail without introducing a > > deadlock. > >=20 > > Also verify SB_ACTIVE after acquiring the read lock, since the sysfs > > attributes become visible before the superblock is fully active. > >=20 > > The reproducer of the issue is attached. After applying this patch,=20 > > the reproducer no longer triggers the kernel crash.=20 > >=20 > > Signed-off-by: Jiacheng Xu > > Tested-by: Jiacheng Xu > > --- > > fs/gfs2/quota.c | 19 ++++++++++++++++++- > > 1 file changed, 18 insertions(+), 1 deletion(-) > >=20 > > diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c > > index 001c8b39ca55..d50534ed9379 100644 > > --- a/fs/gfs2/quota.c > > +++ b/fs/gfs2/quota.c > > @@ -1384,19 +1384,36 @@ int gfs2_quota_sync(struct super_block *sb, int= type) > >=20 > > int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) > > { > > + struct super_block *sb =3D sdp->sd_vfs; > > struct gfs2_quota_data *qd; > > struct gfs2_holder q_gh; > > int error; > >=20 > > + /* > > + * The sysfs files are created before fill_super completes. Avoid > > + * blocking on s_umount because the mount failure path removes the > > + * sysfs files while holding it for writing. > > + */ > > + if (!down_read_trylock(&sb->s_umount)) > > + return -EAGAIN; > > + > > + if (!(sb->s_flags & SB_ACTIVE)) { > > + error =3D -EAGAIN; > > + goto out_unlock; > > + } > > + > > error =3D qd_get(sdp, qid, &qd); > > if (error) > > - return error; > > + goto out_unlock; > >=20 > > error =3D do_glock(qd, FORCE, &q_gh); > > if (!error) > > gfs2_glock_dq_uninit(&q_gh); > >=20 > > qd_put(qd); > >=20 > > +out_unlock: > > + up_read(&sb->s_umount); > > return error; > > }