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>
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) {