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 1fc88c7..c784154 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1419,17 +1419,15 @@
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 d988c39..9cb0264 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1016,17 +1016,16 @@
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)