aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/fs/super.c b/fs/super.c
index 19eb70b374bc..1527e6a0ee35 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -37,6 +37,7 @@
37#include <linux/kobject.h> 37#include <linux/kobject.h>
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <linux/file.h> 39#include <linux/file.h>
40#include <linux/backing-dev.h>
40#include <asm/uaccess.h> 41#include <asm/uaccess.h>
41#include "internal.h" 42#include "internal.h"
42 43
@@ -568,7 +569,7 @@ out:
568int do_remount_sb(struct super_block *sb, int flags, void *data, int force) 569int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
569{ 570{
570 int retval; 571 int retval;
571 int remount_rw; 572 int remount_rw, remount_ro;
572 573
573 if (sb->s_frozen != SB_UNFROZEN) 574 if (sb->s_frozen != SB_UNFROZEN)
574 return -EBUSY; 575 return -EBUSY;
@@ -583,9 +584,12 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
583 shrink_dcache_sb(sb); 584 shrink_dcache_sb(sb);
584 sync_filesystem(sb); 585 sync_filesystem(sb);
585 586
587 remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
588 remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
589
586 /* If we are remounting RDONLY and current sb is read/write, 590 /* If we are remounting RDONLY and current sb is read/write,
587 make sure there are no rw files opened */ 591 make sure there are no rw files opened */
588 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) { 592 if (remount_ro) {
589 if (force) 593 if (force)
590 mark_files_ro(sb); 594 mark_files_ro(sb);
591 else if (!fs_may_remount_ro(sb)) 595 else if (!fs_may_remount_ro(sb))
@@ -594,7 +598,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
594 if (retval < 0 && retval != -ENOSYS) 598 if (retval < 0 && retval != -ENOSYS)
595 return -EBUSY; 599 return -EBUSY;
596 } 600 }
597 remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
598 601
599 if (sb->s_op->remount_fs) { 602 if (sb->s_op->remount_fs) {
600 retval = sb->s_op->remount_fs(sb, &flags, data); 603 retval = sb->s_op->remount_fs(sb, &flags, data);
@@ -604,6 +607,16 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
604 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); 607 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
605 if (remount_rw) 608 if (remount_rw)
606 vfs_dq_quota_on_remount(sb); 609 vfs_dq_quota_on_remount(sb);
610 /*
611 * Some filesystems modify their metadata via some other path than the
612 * bdev buffer cache (eg. use a private mapping, or directories in
613 * pagecache, etc). Also file data modifications go via their own
614 * mappings. So If we try to mount readonly then copy the filesystem
615 * from bdev, we could get stale data, so invalidate it to give a best
616 * effort at coherency.
617 */
618 if (remount_ro && sb->s_bdev)
619 invalidate_bdev(sb->s_bdev);
607 return 0; 620 return 0;
608} 621}
609 622
@@ -681,6 +694,7 @@ int set_anon_super(struct super_block *s, void *data)
681 return -EMFILE; 694 return -EMFILE;
682 } 695 }
683 s->s_dev = MKDEV(0, dev & MINORMASK); 696 s->s_dev = MKDEV(0, dev & MINORMASK);
697 s->s_bdi = &noop_backing_dev_info;
684 return 0; 698 return 0;
685} 699}
686 700
@@ -901,8 +915,9 @@ int get_sb_single(struct file_system_type *fs_type,
901 return error; 915 return error;
902 } 916 }
903 s->s_flags |= MS_ACTIVE; 917 s->s_flags |= MS_ACTIVE;
918 } else {
919 do_remount_sb(s, flags, data, 0);
904 } 920 }
905 do_remount_sb(s, flags, data, 0);
906 simple_set_mnt(mnt, s); 921 simple_set_mnt(mnt, s);
907 return 0; 922 return 0;
908} 923}
@@ -924,6 +939,9 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
924 if (!mnt) 939 if (!mnt)
925 goto out; 940 goto out;
926 941
942 if (flags & MS_KERNMOUNT)
943 mnt->mnt_flags = MNT_INTERNAL;
944
927 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 945 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
928 secdata = alloc_secdata(); 946 secdata = alloc_secdata();
929 if (!secdata) 947 if (!secdata)
@@ -938,10 +956,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
938 if (error < 0) 956 if (error < 0)
939 goto out_free_secdata; 957 goto out_free_secdata;
940 BUG_ON(!mnt->mnt_sb); 958 BUG_ON(!mnt->mnt_sb);
959 WARN_ON(!mnt->mnt_sb->s_bdi);
941 960
942 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); 961 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
943 if (error) 962 if (error)
944 goto out_sb; 963 goto out_sb;
945 964
946 /* 965 /*
947 * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE 966 * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE