fix do_emergency_remount_callback() and do_umount_root() The former is racy - fetching ->s_root outside of ->s_umount. The latter actually never propagates errors (ret in inner scope shadows ret in the outer, so any assignments are lost by the time we get to return ret;). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/namespace.c b/fs/namespace.c index 7833480..82e9b38 100644 --- a/fs/namespace.c +++ b/fs/namespace.c
@@ -1419,17 +1419,15 @@ static void shrink_submounts(struct mount *mnt); static int do_umount_root(struct super_block *sb) { int ret = 0; - struct fs_context fc = { - .purpose = FS_CONTEXT_FOR_UMOUNT, - .fs_type = sb->s_type, - .root = sb->s_root, - .sb_flags = SB_RDONLY, - .sb_flags_mask = SB_RDONLY, - }; - down_write(&sb->s_umount); if (!sb_rdonly(sb)) { - int ret; + struct fs_context fc = { + .purpose = FS_CONTEXT_FOR_UMOUNT, + .fs_type = sb->s_type, + .root = sb->s_root, + .sb_flags = SB_RDONLY, + .sb_flags_mask = SB_RDONLY, + }; if (fc.fs_type->init_fs_context) ret = fc.fs_type->init_fs_context(&fc, NULL);
diff --git a/fs/super.c b/fs/super.c index 5520193..4d1646d 100644 --- a/fs/super.c +++ b/fs/super.c
@@ -1016,17 +1016,16 @@ int reconfigure_super(struct fs_context *fc) static void do_emergency_remount_callback(struct super_block *sb) { - struct fs_context fc = { - .purpose = FS_CONTEXT_FOR_EMERGENCY_RO, - .fs_type = sb->s_type, - .root = sb->s_root, - .sb_flags = SB_RDONLY, - .sb_flags_mask = SB_RDONLY, - }; - down_write(&sb->s_umount); if (sb->s_root && sb->s_bdev && (sb->s_flags & SB_BORN) && !sb_rdonly(sb)) { + struct fs_context fc = { + .purpose = FS_CONTEXT_FOR_EMERGENCY_RO, + .fs_type = sb->s_type, + .root = sb->s_root, + .sb_flags = SB_RDONLY, + .sb_flags_mask = SB_RDONLY, + }; int ret; if (fc.fs_type->init_fs_context)