[PATCH RFC 27/28] xfs: allow remounting read-only after a shutdown
Christian Brauner
brauner at kernel.org
Mon Oct 12 03:21:12 PDT 2026
A shut down xfs can't be remounted read-only. xfs_remount_ro() starts
with sync_filesystem() and xfs_fs_sync_fs() fails with -EIO because the
log can't be forced anymore. So "mount -o remount,ro" fails with EIO and
the filesystem stays read-write. And emergency remount (sysrq u) asks
every read-write superblock on a block device to go read-only with
SB_FORCE. xfs refuses that too and reconfigure_super() warns before it
sets SB_RDONLY anyway:
sysrq: Emergency Remount R/O
forced remount of a xfs fs returned -5
WARNING: fs/super.c:1133 at reconfigure_super+0x498/0xb20, CPU#0: kworker/0:1/11
With panic_on_warn that's a panic from sysrq u. ext4 had the same
problem in its emergency state.
Nothing can be written after a shutdown but going read-only doesn't need
to write anything. So ignore the errors from flushing the filesystem and
from freeing the COW staging extents and post-EOF preallocations once
xfs is shut down. That includes a shutdown the flush causes itself
because the log can't be written. xfs_blockgc_free_space() skips every
inode after a shutdown anyway. The rest of xfs_remount_ro() copes with a
shutdown just like unmount does. It stops the background workers and
xfs_log_clean() leaves a shut down log alone.
And refuse going back to read-write with -EIO after a shutdown. So far
xfs_remount_rw() didn't check for that at all and went on to clear the
read-only state and restart the background workers.
Reproducer (the sb_rdonly selftest after this patch covers the mount(2)
path):
truncate -s 512M img; mkfs.xfs -q img; mount -o loop img /mnt
xfs_io -x -c shutdown /mnt
mount -o remount,ro /mnt # EIO, stays read-write
echo u > /proc/sysrq-trigger # WARNING: forced remount of a xfs fs returned -5
Fixes: b97cca3ba909 ("xfs: only bother with sync_filesystem during readonly remount")
Cc: stable at vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
---
fs/xfs/xfs_super.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index b24db75eaedc..6d82fd069918 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -2041,6 +2041,10 @@ xfs_remount_rw(
struct xfs_sb *sbp = &mp->m_sb;
int error;
+ /* Nothing can be written anymore after a shutdown. */
+ if (xfs_is_shutdown(mp))
+ return -EIO;
+
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp &&
xfs_readonly_buftarg(mp->m_logdev_targp)) {
xfs_warn(mp,
@@ -2115,9 +2119,14 @@ xfs_remount_ro(
};
int error;
- /* Flush all the dirty data to disk. */
+ /*
+ * Flush all the dirty data to disk. After a shutdown, including one
+ * that the flush itself caused, that fails. But going read-only still
+ * has to work, emergency remount (sysrq u) relies on that. The rest
+ * copes with a shutdown like unmount does.
+ */
error = sync_filesystem(mp->m_super);
- if (error)
+ if (error && !xfs_is_shutdown(mp))
return error;
/*
@@ -2133,7 +2142,7 @@ xfs_remount_ro(
* cached inode, so this requires a synchronous cache scan.
*/
error = xfs_blockgc_free_space(mp, &icw);
- if (error) {
+ if (error && !xfs_is_shutdown(mp)) {
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
return error;
}
--
2.53.0
More information about the linux-mtd
mailing list