drop ->s_umount around acct_auto_close()

just repeat the frozen check after regaining it, and check that sb
is still alive.  If several threads hit acct_auto_close() at the
same time, acct_auto_close() will survive that just fine.  And we
really don't want to play with writes and closing the file with
->s_umount held exclusive - it's a deadlock country.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2014-08-07 07:32:06 -04:00
parent 2798d4ce61
commit 0aec09d049
1 changed files with 14 additions and 4 deletions

View File

@ -702,12 +702,22 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
return -EACCES;
#endif
if (flags & MS_RDONLY)
acct_auto_close(&sb->s_pins);
shrink_dcache_sb(sb);
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
if (remount_ro) {
if (sb->s_pins.first) {
up_write(&sb->s_umount);
acct_auto_close(&sb->s_pins);
down_write(&sb->s_umount);
if (!sb->s_root)
return 0;
if (sb->s_writers.frozen != SB_UNFROZEN)
return -EBUSY;
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
}
}
shrink_dcache_sb(sb);
/* If we are remounting RDONLY and current sb is read/write,
make sure there are no rw files opened */
if (remount_ro) {