diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/super.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 33 |
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: | |||
568 | int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | 569 | int 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 |