From: Jan Kara <jack@suse.cz>
To: <linux-fsdevel@vger.kernel.org>
Cc: Dave Chinner <david@fromorbit.com>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>
Subject: [PATCH 11/13] fs: Make sb_start_write() return error on shutdown filesystem
Date: Wed, 7 Aug 2024 20:29:56 +0200 [thread overview]
Message-ID: <20240807183003.23562-11-jack@suse.cz> (raw)
In-Reply-To: <20240807180706.30713-1-jack@suse.cz>
Introduce new SB_I_SHUTDOWN flag that a filesystem can set when it is
forcefully shutting down (usually due to errors). Make sb_start_write()
return errors for such superblocks to avoid modifications to it which
reduces noise in the error logs and generally makes life somewhat easier
for filesystems. We teach all sb_start_write() callers to handle the
error.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/btrfs/block-group.c | 3 ++-
fs/btrfs/defrag.c | 6 +++++-
fs/btrfs/volumes.c | 13 +++++++++----
fs/ext4/mmp.c | 4 +++-
fs/namespace.c | 8 ++++++--
fs/open.c | 4 +++-
fs/overlayfs/util.c | 3 +--
fs/quota/quota.c | 4 ++--
fs/xfs/xfs_ioctl.c | 4 +++-
include/linux/fs.h | 16 ++++++++++++----
10 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 498442d0c216..fdd833f1f7df 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1800,7 +1800,8 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
if (!btrfs_should_reclaim(fs_info))
return;
- sb_start_write(fs_info->sb);
+ if (sb_start_write(fs_info->sb) < 0)
+ return;
if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) {
sb_end_write(fs_info->sb);
diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
index f6dbda37a361..6d14c9be4060 100644
--- a/fs/btrfs/defrag.c
+++ b/fs/btrfs/defrag.c
@@ -274,7 +274,11 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
range.start = cur;
range.extent_thresh = defrag->extent_thresh;
- sb_start_write(fs_info->sb);
+ ret = sb_start_write(fs_info->sb);
+ if (ret < 0) {
+ iput(inode);
+ goto cleanup;
+ }
ret = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
BTRFS_DEFRAG_BATCH);
sb_end_write(fs_info->sb);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index fcedc43ef291..f7b6b307c4bf 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4589,9 +4589,11 @@ int btrfs_balance(struct btrfs_fs_info *fs_info,
static int balance_kthread(void *data)
{
struct btrfs_fs_info *fs_info = data;
- int ret = 0;
+ int ret;
- sb_start_write(fs_info->sb);
+ ret = sb_start_write(fs_info->sb);
+ if (ret < 0)
+ return ret;
mutex_lock(&fs_info->balance_mutex);
if (fs_info->balance_ctl)
ret = btrfs_balance(fs_info, fs_info->balance_ctl, NULL);
@@ -8231,12 +8233,15 @@ static int relocating_repair_kthread(void *data)
struct btrfs_block_group *cache = data;
struct btrfs_fs_info *fs_info = cache->fs_info;
u64 target;
- int ret = 0;
+ int ret;
target = cache->start;
btrfs_put_block_group(cache);
- sb_start_write(fs_info->sb);
+ ret = sb_start_write(fs_info->sb);
+ if (ret < 0)
+ return ret;
+
if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) {
btrfs_info(fs_info,
"zoned: skip relocating block group %llu to repair: EBUSY",
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index bd946d0c71b7..96f69b6835f9 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -63,7 +63,9 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
* We protect against freezing so that we don't create dirty buffers
* on frozen filesystem.
*/
- sb_start_write(sb);
+ err = sb_start_write(sb);
+ if (err < 0)
+ return err;
err = write_mmp_block_thawed(sb, bh);
sb_end_write(sb);
return err;
diff --git a/fs/namespace.c b/fs/namespace.c
index 1c5591673f96..43fad685531e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -512,7 +512,9 @@ int mnt_want_write(struct vfsmount *m)
{
int ret;
- sb_start_write(m->mnt_sb);
+ ret = sb_start_write(m->mnt_sb);
+ if (ret)
+ return ret;
ret = mnt_get_write_access(m);
if (ret)
sb_end_write(m->mnt_sb);
@@ -556,7 +558,9 @@ int mnt_want_write_file(struct file *file)
{
int ret;
- sb_start_write(file_inode(file)->i_sb);
+ ret = sb_start_write(file_inode(file)->i_sb);
+ if (ret)
+ return ret;
ret = mnt_get_write_access_file(file);
if (ret)
sb_end_write(file_inode(file)->i_sb);
diff --git a/fs/open.c b/fs/open.c
index 4bce4ba776ab..8fe9f4968969 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -175,7 +175,9 @@ long do_ftruncate(struct file *file, loff_t length, int small)
/* Check IS_APPEND on real upper inode */
if (IS_APPEND(file_inode(file)))
return -EPERM;
- sb_start_write(inode->i_sb);
+ error = sb_start_write(inode->i_sb);
+ if (error)
+ return error;
error = security_file_truncate(file);
if (!error)
error = do_truncate(file_mnt_idmap(file), dentry, length,
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index b53fa14506a9..f97bf2458c66 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -28,8 +28,7 @@ int ovl_get_write_access(struct dentry *dentry)
int __must_check ovl_start_write(struct dentry *dentry)
{
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
- sb_start_write(ovl_upper_mnt(ofs)->mnt_sb);
- return 0;
+ return sb_start_write(ovl_upper_mnt(ofs)->mnt_sb);
}
int ovl_want_write(struct dentry *dentry)
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 0e41fb84060f..df9c4d08f135 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -896,8 +896,8 @@ static struct super_block *quotactl_block(const char __user *special, int cmd)
else
up_read(&sb->s_umount);
/* Wait for sb to unfreeze */
- sb_start_write(sb);
- sb_end_write(sb);
+ if (sb_start_write(sb) == 0)
+ sb_end_write(sb);
put_super(sb);
goto retry;
}
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 4e933db75b12..5cf9e568324a 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1499,7 +1499,9 @@ xfs_file_ioctl(
trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);
- sb_start_write(mp->m_super);
+ error = sb_start_write(mp->m_super);
+ if (error)
+ return error;
error = xfs_blockgc_free_space(mp, &icw);
sb_end_write(mp->m_super);
return error;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 755a4c83a2bf..44ae86f46b12 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1190,6 +1190,9 @@ enum {
SB_I_TS_EXPIRY_WARNED, /* warned about timestamp range expiry */
SB_I_RETIRED, /* superblock shouldn't be reused */
SB_I_NOUMASK, /* VFS does not apply umask */
+ SB_I_SHUTDOWN, /* The filesystem has shutdown. Refuse
+ * modification attempts with error as they are
+ * a futile exercise. */
};
/* Possible states of 'frozen' field */
@@ -1823,9 +1826,12 @@ static inline void sb_end_intwrite(struct super_block *sb)
* -> i_mutex (write path, truncate, directory ops, ...)
* -> s_umount (freeze_super, thaw_super)
*/
-static inline void sb_start_write(struct super_block *sb)
+static inline int __must_check sb_start_write(struct super_block *sb)
{
+ if (sb_test_iflag(sb, SB_I_SHUTDOWN))
+ return -EROFS;
__sb_start_write(sb, SB_FREEZE_WRITE);
+ return 0;
}
static inline bool __must_check sb_start_write_trylock(struct super_block *sb)
@@ -2891,8 +2897,7 @@ static inline int __must_check file_start_write(struct file *file)
{
if (!S_ISREG(file_inode(file)->i_mode))
return 0;
- sb_start_write(file_inode(file)->i_sb);
- return 0;
+ return sb_start_write(file_inode(file)->i_sb);
}
static inline bool __must_check file_start_write_trylock(struct file *file)
@@ -2925,8 +2930,11 @@ static inline void file_end_write(struct file *file)
static inline int __must_check kiocb_start_write(struct kiocb *iocb)
{
struct inode *inode = file_inode(iocb->ki_filp);
+ int err;
- sb_start_write(inode->i_sb);
+ err = sb_start_write(inode->i_sb);
+ if (err)
+ return err;
/*
* Fool lockdep by telling it the lock got released so that it
* doesn't complain about the held lock when we return to userspace.
--
2.35.3
next prev parent reply other threads:[~2024-08-07 18:30 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-07 18:29 [PATCH RFC 0/13] fs: generic filesystem shutdown handling Jan Kara
2024-08-07 18:29 ` [PATCH 01/13] fs: Define bit numbers for SB_I_ flags Jan Kara
2024-08-07 18:29 ` [PATCH 02/13] fs: Convert fs_context use of SB_I_ flags to new constants Jan Kara
2024-08-07 18:29 ` [PATCH 03/13] fs: Convert mount_too_revealing() to new s_iflags handling functions Jan Kara
2024-08-07 18:29 ` [PATCH 04/13] fs: Convert remaining usage of SB_I_ flags Jan Kara
2024-08-07 18:29 ` [PATCH 05/13] fs: Drop old SB_I_ constants Jan Kara
2024-08-07 18:29 ` [PATCH 06/13] fs: Drop unnecessary underscore from _SB_I_ constants Jan Kara
2024-08-08 11:47 ` Amir Goldstein
2024-08-08 14:35 ` Darrick J. Wong
2024-08-08 14:50 ` Christian Brauner
2024-08-08 17:34 ` Jan Kara
2024-08-07 18:29 ` [PATCH 07/13] overlayfs: Make ovl_start_write() return error Jan Kara
2024-08-08 12:01 ` Amir Goldstein
2024-08-07 18:29 ` [PATCH 08/13] fs: Teach callers of kiocb_start_write() to handle errors Jan Kara
2024-08-07 18:29 ` [PATCH 09/13] fs: Teach callers of file_start_write() " Jan Kara
2024-08-07 18:29 ` [PATCH 10/13] fs: Add __must_check annotations to sb_start_write_trylock() and similar Jan Kara
2024-08-07 18:29 ` Jan Kara [this message]
2024-08-07 18:29 ` [PATCH 12/13] fs: Make sb_start_pagefault() return error on shutdown filesystem Jan Kara
2024-08-07 18:29 ` [PATCH 13/13] ext4: Replace EXT4_FLAGS_SHUTDOWN flag with a generic SB_I_SHUTDOWN Jan Kara
2024-08-07 23:18 ` [PATCH RFC 0/13] fs: generic filesystem shutdown handling Dave Chinner
2024-08-08 14:32 ` Jan Kara
2024-08-13 12:46 ` Christian Brauner
2024-08-14 0:09 ` Dave Chinner
2024-08-08 14:51 ` Darrick J. Wong
2024-08-09 2:30 ` Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240807183003.23562-11-jack@suse.cz \
--to=jack@suse.cz \
--cc=brauner@kernel.org \
--cc=david@fromorbit.com \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).