[PATCH RFC 25/28] ext4: allow remounting read-only in the emergency state
Christian Brauner
brauner at kernel.org
Mon Oct 12 03:21:10 PDT 2026
__ext4_remount() refuses any change of the read-only state with -EROFS
while ext4_emergency_state() is set, i.e. after FS_IOC_SHUTDOWN, after
an error with errors=remount-ro or after an error that forces the
filesystem read-only like ext4_abort(). None of them sets SB_RDONLY
anymore. So a plain remount to read-only fails 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. ext4 refuses that too and
reconfigure_super() warns before it sets SB_RDONLY anyway:
EXT4-fs (vda): Remounting filesystem read-only
sysrq: Emergency Remount R/O
forced remount of a ext4 fs returned -30
WARNING: fs/super.c:1133 at reconfigure_super+0x498/0xb20, CPU#3: kworker/3:1/50
do_emergency_remount_callback+0xc4/0x100
__iterate_supers+0x33d/0x410
do_emergency_remount+0x20/0x40
With panic_on_warn that's a panic from sysrq u.
Nothing may be written in the emergency state but becoming read-only
doesn't need to write anything. So allow going read-only and skip
everything in that branch that would touch the disk. That's
sync_filesystem(), which fails with the emergency errno anyway,
dquot_suspend(), the s_state update and ext4_mark_recovery_complete().
Note that after a shutdown with FS_SHUTDOWN_FLAGS_DEFAULT the journal is
still live and the latter would really write. Also skip the superblock
commit a remount does for a filesystem without a journal, like
ext4_put_super() does in that state. Going read-write is still refused
with -EROFS and option-only remounts work as before. Quotas stay on
until umount.
That's the rule the filesystems converted earlier in this series follow
as well. In the emergency state going read-write fails and going
read-only works, writing at most what was dirtied before the error.
Reproducer (the sb_rdonly selftest after this patch covers the mount(2)
path):
truncate -s 64M img; mkfs.ext4 -q img
mount -o loop,errors=remount-ro img /mnt
xfs_io -x -c shutdown /mnt # or any ext4 error, e.g.
# echo x > /sys/fs/ext4/loop0/trigger_fs_error
mount -o remount,ro /mnt # EROFS, stays read-write
echo u > /proc/sysrq-trigger # WARNING: forced remount of a ext4 fs returned -30
Fixes: 95257987a638 ("ext4: drop EXT4_MF_FS_ABORTED flag")
Fixes: d3476f3dad4a ("ext4: don't set SB_RDONLY after filesystem errors")
Cc: stable at vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
---
fs/ext4/super.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d636b89090a2..643c304460ec 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -6711,11 +6711,18 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
if ((bool)(fc->sb_flags & SB_RDONLY) != sb_rdonly(sb)) {
if (ext4_emergency_state(sb)) {
- err = -EROFS;
- goto restore_opts;
- }
-
- if (fc->sb_flags & SB_RDONLY) {
+ /*
+ * Nothing may be written in the emergency state. Going
+ * read-write stays refused, but going read-only must
+ * not fail or emergency remount (sysrq u) WARNs. So
+ * just become read-only without touching the disk.
+ */
+ if (!(fc->sb_flags & SB_RDONLY)) {
+ err = -EROFS;
+ goto restore_opts;
+ }
+ sb->s_flags |= SB_RDONLY;
+ } else if (fc->sb_flags & SB_RDONLY) {
err = sync_filesystem(sb);
if (err < 0)
goto restore_opts;
@@ -6826,7 +6833,8 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
goto restore_opts;
}
- if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY)) {
+ if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY) &&
+ !ext4_emergency_state(sb)) {
err = ext4_commit_super(sb);
if (err)
goto restore_opts;
--
2.53.0
More information about the linux-mtd
mailing list