Commit 65547661 authored by Jan Kara's avatar Jan Kara

ext2: Call dquot_writeback_dquots() with s_umount held

ext2_sync_fs() could be called without s_umount semaphore held when
called through ext2_write_super() from __ext2_write_inode(). This
function then calls dquot_writeback_dquots() which relies on s_umount to
be held for protection against other quota operations.

In fact __ext2_write_inode() does not need all the functionality
ext2_write_super() provides. It is enough to just write the superblock.
So use ext2_sync_super() instead.

Fixes: 9d1ccbe7Reported-by: default avatarJan Beulich <jbeulich@suse.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent ab494964
...@@ -796,7 +796,8 @@ void ext2_error(struct super_block *, const char *, const char *, ...); ...@@ -796,7 +796,8 @@ void ext2_error(struct super_block *, const char *, const char *, ...);
extern __printf(3, 4) extern __printf(3, 4)
void ext2_msg(struct super_block *, const char *, const char *, ...); void ext2_msg(struct super_block *, const char *, const char *, ...);
extern void ext2_update_dynamic_rev (struct super_block *sb); extern void ext2_update_dynamic_rev (struct super_block *sb);
extern void ext2_write_super (struct super_block *); extern void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es,
int wait);
/* /*
* Inodes and files operations * Inodes and files operations
......
...@@ -1615,7 +1615,7 @@ static int __ext2_write_inode(struct inode *inode, int do_sync) ...@@ -1615,7 +1615,7 @@ static int __ext2_write_inode(struct inode *inode, int do_sync)
EXT2_SET_RO_COMPAT_FEATURE(sb, EXT2_SET_RO_COMPAT_FEATURE(sb,
EXT2_FEATURE_RO_COMPAT_LARGE_FILE); EXT2_FEATURE_RO_COMPAT_LARGE_FILE);
spin_unlock(&EXT2_SB(sb)->s_lock); spin_unlock(&EXT2_SB(sb)->s_lock);
ext2_write_super(sb); ext2_sync_super(sb, EXT2_SB(sb)->s_es, 1);
} }
} }
} }
......
...@@ -36,8 +36,7 @@ ...@@ -36,8 +36,7 @@
#include "xattr.h" #include "xattr.h"
#include "acl.h" #include "acl.h"
static void ext2_sync_super(struct super_block *sb, static void ext2_write_super(struct super_block *sb);
struct ext2_super_block *es, int wait);
static int ext2_remount (struct super_block * sb, int * flags, char * data); static int ext2_remount (struct super_block * sb, int * flags, char * data);
static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
static int ext2_sync_fs(struct super_block *sb, int wait); static int ext2_sync_fs(struct super_block *sb, int wait);
...@@ -1194,7 +1193,7 @@ static void ext2_clear_super_error(struct super_block *sb) ...@@ -1194,7 +1193,7 @@ static void ext2_clear_super_error(struct super_block *sb)
} }
} }
static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es, void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es,
int wait) int wait)
{ {
ext2_clear_super_error(sb); ext2_clear_super_error(sb);
...@@ -1270,7 +1269,7 @@ static int ext2_unfreeze(struct super_block *sb) ...@@ -1270,7 +1269,7 @@ static int ext2_unfreeze(struct super_block *sb)
return 0; return 0;
} }
void ext2_write_super(struct super_block *sb) static void ext2_write_super(struct super_block *sb)
{ {
if (!(sb->s_flags & MS_RDONLY)) if (!(sb->s_flags & MS_RDONLY))
ext2_sync_fs(sb, 1); ext2_sync_fs(sb, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment