From nobody Wed Apr 15 04:24:57 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD0A9C04A68 for ; Wed, 27 Jul 2022 06:45:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230032AbiG0Gpr (ORCPT ); Wed, 27 Jul 2022 02:45:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230231AbiG0Gor (ORCPT ); Wed, 27 Jul 2022 02:44:47 -0400 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A3EA419BB for ; Tue, 26 Jul 2022 23:44:44 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id b7-20020a17090a12c700b001f20eb82a08so1208083pjg.3 for ; Tue, 26 Jul 2022 23:44:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pGLiVi9XQM3vyY9yITwEB0JmMmI/TjfPvTsfSo82B+s=; b=Q8Ri/ANocPXcmRgdrkKVri46FcK3O3C3JdOPric+SMDZ+Pragy79ydjKbLC6dun3Lm H5P25v3IibiUlW3DKE4InnUBqT3rRPR2ee5vmpIaIoJJngMxOTgnk/abbiLGN7SwRKZ6 TtxaJXZMXXFX1R13s8ztNmXNxqb1L1zFxQ/rw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pGLiVi9XQM3vyY9yITwEB0JmMmI/TjfPvTsfSo82B+s=; b=mbAZBQ65gF7B1rEGvftTBmXKcptNCkAK0sY0lDUUmhefcGD+ygdlXiYMq1ivRbsP/M 1SjltoO7VQva+DkmNJEKuCTJ6olAUoNUFrVih3uJkrtgRrEnpGTyn08043xtHCx9xyHo QVhQtiZ9wnbAp4b8adlt9SDXDDrb02G3aYgVwoSWf4cFvUpfSttgXvMV5P2yU+L5k48s P9GQrB31Cjf0+G8AQGRnVJSxIUo28zqPkMerkp1P1VA7WAWj6WiTtvKHl+70z/hVELq6 yqMj67Lu5Vajohgj9LUdB738WDl5tZrhMsOHXSWd+64uxN38foQYtSjfFbpy46LJbE7q zEfg== X-Gm-Message-State: AJIora+pfGjB/zIUbid/a8FewjrdzisjkQAUdpCRZCn2YVppr1rRWQ1R vBgDbpdNnJqfOkeqHARKo9pJDQ== X-Google-Smtp-Source: AGRyM1tkFYpNmNzxbkSrpQ31JzoVI6BtKahQUmPC06Go6XQSkBdv3w6GTkGVFH0PVlTiR63gAIFoRw== X-Received: by 2002:a17:90b:198d:b0:1f3:f72:cfdc with SMTP id mv13-20020a17090b198d00b001f30f72cfdcmr530341pjb.237.1658904283540; Tue, 26 Jul 2022 23:44:43 -0700 (PDT) Received: from dlunevwfh.roam.corp.google.com (n122-107-196-14.sbr2.nsw.optusnet.com.au. [122.107.196.14]) by smtp.gmail.com with ESMTPSA id f4-20020a170902684400b0016bdf0032b9sm12627001pln.110.2022.07.26.23.44.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Jul 2022 23:44:43 -0700 (PDT) From: Daniil Lunev To: Miklos Szeredi , Alexander Viro Cc: linux-fsdevel@vger.kernel.org, fuse-devel@lists.sourceforge.net, Christoph Hellwig , linux-kernel@vger.kernel.org, Daniil Lunev Subject: [PATCH v5 1/2] fs/super: function to prevent re-use of block-device-based superblocks Date: Wed, 27 Jul 2022 16:44:24 +1000 Message-Id: <20220727164328.v5.1.I73b7338e13b233e8b0bf366c753cbc2b360817cb@changeid> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20220727064425.4144478-1-dlunev@chromium.org> References: <20220727064425.4144478-1-dlunev@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The function is to be called from filesystem-specific code to mark a superblock to be ignored by superblock test and thus never re-used. The function also unregisters bdi if the bdi is per-superblock to avoid collision if a new superblock is created to represent the filesystem. generic_shutdown_super() skips unregistering bdi for a retired superlock as it assumes retire function has already done it. This patch adds the functionality only for the block-device-based supers, since the primary use case of the feature is to gracefully handle force unmount of external devices, mounted with FUSE. This can be further extended to cover all superblocks, if the need arises. Signed-off-by: Daniil Lunev Reviewed-by: Christoph Hellwig --- Changes in v5: - Commit message - Extended retire_super comment to clarify behaviour. Changes in v4: - Simplify condition according to Christoph Hellwig's comments. Changes in v3: - Back to state tracking from v1 - Use s_iflag to mark superblocked ignored - Only unregister private bdi in retire, without freeing Changes in v2: - Remove super from list of superblocks instead of using a flag fs/super.c | 32 ++++++++++++++++++++++++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/fs/super.c b/fs/super.c index 60f57c7bc0a69..8565fffc9ae31 100644 --- a/fs/super.c +++ b/fs/super.c @@ -422,6 +422,34 @@ bool trylock_super(struct super_block *sb) return false; } =20 +/** + * retire_super - prevents superblock from being reused + * @sb: superblock to retire + * + * The function marks superblock to be ignored in superblock test, which + * prevents it from being reused for any new mounts. If the superblock has + * a private bdi, it also unregisters it, but doesn't reduce the refcount + * of the superblock to prevent potential races. The refcount is reduced + * by generic_shutdown_super(). The function can not be called concurrently + * with generic_shutdown_super(). It is safe to call the function multiple + * times, subsequent calls have no effect. + * + * The marker will affect the re-use only for block-device-based + * superblocks. Other superblocks will still get marked if this function is + * used, but that will not affect their reusability. + */ +void retire_super(struct super_block *sb) +{ + down_write(&sb->s_umount); + if (sb->s_iflags & SB_I_PERSB_BDI) { + bdi_unregister(sb->s_bdi); + sb->s_iflags &=3D ~SB_I_PERSB_BDI; + } + sb->s_iflags |=3D SB_I_RETIRED; + up_write(&sb->s_umount); +} +EXPORT_SYMBOL(retire_super); + /** * generic_shutdown_super - common helper for ->kill_sb() * @sb: superblock to kill @@ -1216,7 +1244,7 @@ static int set_bdev_super_fc(struct super_block *s, s= truct fs_context *fc) =20 static int test_bdev_super_fc(struct super_block *s, struct fs_context *fc) { - return s->s_bdev =3D=3D fc->sget_key; + return !(s->s_iflags & SB_I_RETIRED) && s->s_bdev =3D=3D fc->sget_key; } =20 /** @@ -1307,7 +1335,7 @@ EXPORT_SYMBOL(get_tree_bdev); =20 static int test_bdev_super(struct super_block *s, void *data) { - return (void *)s->s_bdev =3D=3D data; + return !(s->s_iflags & SB_I_RETIRED) && (void *)s->s_bdev =3D=3D data; } =20 struct dentry *mount_bdev(struct file_system_type *fs_type, diff --git a/include/linux/fs.h b/include/linux/fs.h index 9ad5e3520fae5..246120ee05733 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1412,6 +1412,7 @@ extern int send_sigurg(struct fown_struct *fown); #define SB_I_SKIP_SYNC 0x00000100 /* Skip superblock at global sync */ #define SB_I_PERSB_BDI 0x00000200 /* has a per-sb bdi */ #define SB_I_TS_EXPIRY_WARNED 0x00000400 /* warned about timestamp range e= xpiry */ +#define SB_I_RETIRED 0x00000800 /* superblock shouldn't be reused */ =20 /* Possible states of 'frozen' field */ enum { @@ -2432,6 +2433,7 @@ extern struct dentry *mount_nodev(struct file_system_= type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int)); extern struct dentry *mount_subtree(struct vfsmount *mnt, const char *path= ); +void retire_super(struct super_block *sb); void generic_shutdown_super(struct super_block *sb); void kill_block_super(struct super_block *sb); void kill_anon_super(struct super_block *sb); --=20 2.31.0 From nobody Wed Apr 15 04:24:57 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BAC1C04A68 for ; Wed, 27 Jul 2022 06:45:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231200AbiG0Gpw (ORCPT ); Wed, 27 Jul 2022 02:45:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230286AbiG0Gov (ORCPT ); Wed, 27 Jul 2022 02:44:51 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0695841D14 for ; Tue, 26 Jul 2022 23:44:48 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id 15-20020a17090a098f00b001f305b453feso1226597pjo.1 for ; Tue, 26 Jul 2022 23:44:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XDNROrSqKzyA1L1M+SB07diVx6X/b8xPoeGY/Lj78Aw=; b=GpIKOXIWUDtcIO0SokOTsUOk5j320G3Xti70ANRzozbGTAoONxsCskms0m1FM4iZax G8CG/9OK5j7tfbvPwFjAeFpGnWSaw98voWkjYrIckmrR1TWV33Imol32Bkn4T91gRG59 Xq2O02ojrRvXM9jgOBn6/uYONtxri39d1GPMU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XDNROrSqKzyA1L1M+SB07diVx6X/b8xPoeGY/Lj78Aw=; b=QTym68pVm4Zq+Doo5HvIe/v6pDjkAwFUwmtajty6Dq+Pu6HE0R8G581LoEmZmQmOmK c7xxJzmLQGbNSg1R0TqgvhY06RY373BEo0Wc1S4UO+ePHFZPuO+aP2nM5tHRq6MIK5d5 7vZdAepdNFQsAyDksYNh+YHY6mEV+VkxepoOomGzLWYGO+Z4P+1USddGePqsexp69LXM 8B8Hlf4mP9B0Ej0W23shO0cEdYlR1YYVVgKcwLKtynpDcVVpXL9ys0WriVWU0s7tkQyP c492fBgBw5HVGRSiOczQO2TFtuNadG27DMvktDFS9/Ck8eOi1pA/YZq40zidckO1xmCf 5eyg== X-Gm-Message-State: AJIora/xn8ulU4ifiZ9a6847xyDmQz96cBSCbtCyq6gXJf3+9iiqI+KK N17aH95k2nu6u/O9atZ6RF4Smg== X-Google-Smtp-Source: AGRyM1uex+Nm55OX2ZGryHSVY2YxmlleVBEPD5U7Boyj5d+KDkszRor2X7950nOxTGuLbEPNPBBvSw== X-Received: by 2002:a17:902:a382:b0:16d:b787:9e86 with SMTP id x2-20020a170902a38200b0016db7879e86mr374930pla.105.1658904287478; Tue, 26 Jul 2022 23:44:47 -0700 (PDT) Received: from dlunevwfh.roam.corp.google.com (n122-107-196-14.sbr2.nsw.optusnet.com.au. [122.107.196.14]) by smtp.gmail.com with ESMTPSA id f4-20020a170902684400b0016bdf0032b9sm12627001pln.110.2022.07.26.23.44.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Jul 2022 23:44:47 -0700 (PDT) From: Daniil Lunev To: Miklos Szeredi , Alexander Viro Cc: linux-fsdevel@vger.kernel.org, fuse-devel@lists.sourceforge.net, Christoph Hellwig , linux-kernel@vger.kernel.org, Daniil Lunev Subject: [PATCH v5 2/2] FUSE: Retire block-device-based superblock on force unmount Date: Wed, 27 Jul 2022 16:44:25 +1000 Message-Id: <20220727164328.v5.2.Ia8e6b14cb01caf13a4290236e37b04dff5626bc7@changeid> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20220727064425.4144478-1-dlunev@chromium.org> References: <20220727064425.4144478-1-dlunev@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Force unmount of FUSE severes the connection with the user space, even if there are still open files. Subsequent remount tries to re-use the superblock held by the open files, which is meaningless in the FUSE case after disconnect - reused super block doesn't have userspace counterpart attached to it and is incapable of doing any IO. This patch adds the functionality only for the block-device-based supers, since the primary use case of the feature is to gracefully handle force unmount of external devices, mounted with FUSE. This can be further extended to cover all superblocks, if the need arises. Signed-off-by: Daniil Lunev --- Changes in v5: - Restrict retire_super call in FUSE to be issued for fuseblk only. - Commit message Changes in v2: - Use an exported function instead of directly modifying superblock fs/fuse/inode.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 8c0665c5dff88..9e931f53794bb 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -476,8 +476,14 @@ static void fuse_umount_begin(struct super_block *sb) { struct fuse_conn *fc =3D get_fuse_conn_super(sb); =20 - if (!fc->no_force_umount) - fuse_abort_conn(fc); + if (fc->no_force_umount) + return; + + fuse_abort_conn(fc); + + // Only retire block-device-based superblocks. + if (sb->s_bdev !=3D NULL) + retire_super(sb); } =20 static void fuse_send_destroy(struct fuse_mount *fm) --=20 2.31.0