aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <[email protected]>2024-08-05 22:12:41 +0200
committerTheodore Ts'o <[email protected]>2024-08-26 23:53:20 -0400
commitd3476f3dad4ad68ae5f6b008ea6591d1520da5d8 (patch)
tree08c6ca8556271e0e13aac77f139e070c2073504a
parentd1bc560e9a9c78d0b2314692847fc8661e0aeb99 (diff)
ext4: don't set SB_RDONLY after filesystem errors
When the filesystem is mounted with errors=remount-ro, we were setting SB_RDONLY flag to stop all filesystem modifications. We knew this misses proper locking (sb->s_umount) and does not go through proper filesystem remount procedure but it has been the way this worked since early ext2 days and it was good enough for catastrophic situation damage mitigation. Recently, syzbot has found a way (see link) to trigger warnings in filesystem freezing because the code got confused by SB_RDONLY changing under its hands. Since these days we set EXT4_FLAGS_SHUTDOWN on the superblock which is enough to stop all filesystem modifications, modifying SB_RDONLY shouldn't be needed. So stop doing that. Link: https://lore.kernel.org/all/[email protected] Reported-by: Christian Brauner <[email protected]> Signed-off-by: Jan Kara <[email protected]> Reviewed-by: Christian Brauner <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
-rw-r--r--fs/ext4/super.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 89d9b34d787a..58423e6bf3d0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -735,11 +735,12 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
/*
- * Make sure updated value of ->s_mount_flags will be visible before
- * ->s_flags update
+ * EXT4_FLAGS_SHUTDOWN was set which stops all filesystem
+ * modifications. We don't set SB_RDONLY because that requires
+ * sb->s_umount semaphore and setting it without proper remount
+ * procedure is confusing code such as freeze_super() leading to
+ * deadlocks and other problems.
*/
- smp_wmb();
- sb->s_flags |= SB_RDONLY;
}
static void update_super_work(struct work_struct *work)