aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-08-07 07:32:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-08-07 14:40:08 -0400
commit0aec09d049d7e994eba54bad4376dd8f58eab797 (patch)
tree220068a33da8eadd95e3006f626f3d80b8822f6b /fs/super.c
parent2798d4ce61601808b965253d60624bbf201b51b0 (diff)
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>
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/super.c b/fs/super.c
index 52ed93eb63df..a369f8964dc1 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -702,12 +702,22 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
702 return -EACCES; 702 return -EACCES;
703#endif 703#endif
704 704
705 if (flags & MS_RDONLY)
706 acct_auto_close(&sb->s_pins);
707 shrink_dcache_sb(sb);
708
709 remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); 705 remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
710 706
707 if (remount_ro) {
708 if (sb->s_pins.first) {
709 up_write(&sb->s_umount);
710 acct_auto_close(&sb->s_pins);
711 down_write(&sb->s_umount);
712 if (!sb->s_root)
713 return 0;
714 if (sb->s_writers.frozen != SB_UNFROZEN)
715 return -EBUSY;
716 remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
717 }
718 }
719 shrink_dcache_sb(sb);
720
711 /* If we are remounting RDONLY and current sb is read/write, 721 /* If we are remounting RDONLY and current sb is read/write,
712 make sure there are no rw files opened */ 722 make sure there are no rw files opened */
713 if (remount_ro) { 723 if (remount_ro) {