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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.