diff options
Diffstat (limited to 'fs/super.c')
| -rw-r--r-- | fs/super.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/super.c b/fs/super.c index aff046b0fe78..f35ac6022109 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -568,7 +568,7 @@ out: | |||
| 568 | int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | 568 | int do_remount_sb(struct super_block *sb, int flags, void *data, int force) |
| 569 | { | 569 | { |
| 570 | int retval; | 570 | int retval; |
| 571 | int remount_rw; | 571 | int remount_rw, remount_ro; |
| 572 | 572 | ||
| 573 | if (sb->s_frozen != SB_UNFROZEN) | 573 | if (sb->s_frozen != SB_UNFROZEN) |
| 574 | return -EBUSY; | 574 | return -EBUSY; |
| @@ -583,9 +583,12 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
| 583 | shrink_dcache_sb(sb); | 583 | shrink_dcache_sb(sb); |
| 584 | sync_filesystem(sb); | 584 | sync_filesystem(sb); |
| 585 | 585 | ||
| 586 | remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); | ||
| 587 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); | ||
| 588 | |||
| 586 | /* If we are remounting RDONLY and current sb is read/write, | 589 | /* If we are remounting RDONLY and current sb is read/write, |
| 587 | make sure there are no rw files opened */ | 590 | make sure there are no rw files opened */ |
| 588 | if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) { | 591 | if (remount_ro) { |
| 589 | if (force) | 592 | if (force) |
| 590 | mark_files_ro(sb); | 593 | mark_files_ro(sb); |
| 591 | else if (!fs_may_remount_ro(sb)) | 594 | else if (!fs_may_remount_ro(sb)) |
| @@ -594,7 +597,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
| 594 | if (retval < 0 && retval != -ENOSYS) | 597 | if (retval < 0 && retval != -ENOSYS) |
| 595 | return -EBUSY; | 598 | return -EBUSY; |
| 596 | } | 599 | } |
| 597 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); | ||
| 598 | 600 | ||
| 599 | if (sb->s_op->remount_fs) { | 601 | if (sb->s_op->remount_fs) { |
| 600 | retval = sb->s_op->remount_fs(sb, &flags, data); | 602 | retval = sb->s_op->remount_fs(sb, &flags, data); |
| @@ -604,6 +606,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); | 606 | sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); |
| 605 | if (remount_rw) | 607 | if (remount_rw) |
| 606 | vfs_dq_quota_on_remount(sb); | 608 | vfs_dq_quota_on_remount(sb); |
| 609 | /* | ||
| 610 | * Some filesystems modify their metadata via some other path than the | ||
| 611 | * bdev buffer cache (eg. use a private mapping, or directories in | ||
| 612 | * pagecache, etc). Also file data modifications go via their own | ||
| 613 | * mappings. So If we try to mount readonly then copy the filesystem | ||
| 614 | * from bdev, we could get stale data, so invalidate it to give a best | ||
| 615 | * effort at coherency. | ||
| 616 | */ | ||
| 617 | if (remount_ro && sb->s_bdev) | ||
| 618 | invalidate_bdev(sb->s_bdev); | ||
| 607 | return 0; | 619 | return 0; |
| 608 | } | 620 | } |
| 609 | 621 | ||
| @@ -925,6 +937,9 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
| 925 | if (!mnt) | 937 | if (!mnt) |
| 926 | goto out; | 938 | goto out; |
| 927 | 939 | ||
| 940 | if (flags & MS_KERNMOUNT) | ||
| 941 | mnt->mnt_flags = MNT_INTERNAL; | ||
| 942 | |||
| 928 | if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { | 943 | if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { |
| 929 | secdata = alloc_secdata(); | 944 | secdata = alloc_secdata(); |
| 930 | if (!secdata) | 945 | if (!secdata) |
