diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index c6f54e4c4290..134d494158d9 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -695,12 +695,16 @@ static inline void mangle(struct seq_file *m, const char *s) | |||
695 | */ | 695 | */ |
696 | int generic_show_options(struct seq_file *m, struct vfsmount *mnt) | 696 | int generic_show_options(struct seq_file *m, struct vfsmount *mnt) |
697 | { | 697 | { |
698 | const char *options = mnt->mnt_sb->s_options; | 698 | const char *options; |
699 | |||
700 | rcu_read_lock(); | ||
701 | options = rcu_dereference(mnt->mnt_sb->s_options); | ||
699 | 702 | ||
700 | if (options != NULL && options[0]) { | 703 | if (options != NULL && options[0]) { |
701 | seq_putc(m, ','); | 704 | seq_putc(m, ','); |
702 | mangle(m, options); | 705 | mangle(m, options); |
703 | } | 706 | } |
707 | rcu_read_unlock(); | ||
704 | 708 | ||
705 | return 0; | 709 | return 0; |
706 | } | 710 | } |
@@ -721,11 +725,22 @@ EXPORT_SYMBOL(generic_show_options); | |||
721 | */ | 725 | */ |
722 | void save_mount_options(struct super_block *sb, char *options) | 726 | void save_mount_options(struct super_block *sb, char *options) |
723 | { | 727 | { |
724 | kfree(sb->s_options); | 728 | BUG_ON(sb->s_options); |
725 | sb->s_options = kstrdup(options, GFP_KERNEL); | 729 | rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL)); |
726 | } | 730 | } |
727 | EXPORT_SYMBOL(save_mount_options); | 731 | EXPORT_SYMBOL(save_mount_options); |
728 | 732 | ||
733 | void replace_mount_options(struct super_block *sb, char *options) | ||
734 | { | ||
735 | char *old = sb->s_options; | ||
736 | rcu_assign_pointer(sb->s_options, options); | ||
737 | if (old) { | ||
738 | synchronize_rcu(); | ||
739 | kfree(old); | ||
740 | } | ||
741 | } | ||
742 | EXPORT_SYMBOL(replace_mount_options); | ||
743 | |||
729 | #ifdef CONFIG_PROC_FS | 744 | #ifdef CONFIG_PROC_FS |
730 | /* iterator */ | 745 | /* iterator */ |
731 | static void *m_start(struct seq_file *m, loff_t *pos) | 746 | static void *m_start(struct seq_file *m, loff_t *pos) |
@@ -1073,9 +1088,7 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
1073 | */ | 1088 | */ |
1074 | 1089 | ||
1075 | if (flags & MNT_FORCE && sb->s_op->umount_begin) { | 1090 | if (flags & MNT_FORCE && sb->s_op->umount_begin) { |
1076 | lock_kernel(); | ||
1077 | sb->s_op->umount_begin(sb); | 1091 | sb->s_op->umount_begin(sb); |
1078 | unlock_kernel(); | ||
1079 | } | 1092 | } |
1080 | 1093 | ||
1081 | /* | 1094 | /* |
@@ -1377,7 +1390,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, | |||
1377 | if (parent_path) { | 1390 | if (parent_path) { |
1378 | detach_mnt(source_mnt, parent_path); | 1391 | detach_mnt(source_mnt, parent_path); |
1379 | attach_mnt(source_mnt, path); | 1392 | attach_mnt(source_mnt, path); |
1380 | touch_mnt_namespace(current->nsproxy->mnt_ns); | 1393 | touch_mnt_namespace(parent_path->mnt->mnt_ns); |
1381 | } else { | 1394 | } else { |
1382 | mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); | 1395 | mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); |
1383 | commit_tree(source_mnt); | 1396 | commit_tree(source_mnt); |
@@ -1920,8 +1933,9 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1920 | if (data_page) | 1933 | if (data_page) |
1921 | ((char *)data_page)[PAGE_SIZE - 1] = 0; | 1934 | ((char *)data_page)[PAGE_SIZE - 1] = 0; |
1922 | 1935 | ||
1923 | /* Default to relatime */ | 1936 | /* Default to relatime unless overriden */ |
1924 | mnt_flags |= MNT_RELATIME; | 1937 | if (!(flags & MS_NOATIME)) |
1938 | mnt_flags |= MNT_RELATIME; | ||
1925 | 1939 | ||
1926 | /* Separate the per-mountpoint flags */ | 1940 | /* Separate the per-mountpoint flags */ |
1927 | if (flags & MS_NOSUID) | 1941 | if (flags & MS_NOSUID) |