diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2009-06-08 12:21:27 +0100 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-06-08 12:21:27 +0100 |
| commit | e635a01ea0a16cf7cd31ecd2305870385dca9be6 (patch) | |
| tree | c7153e7dee5caf6ac90d85694ff27e4d0b606290 /fs/namespace.c | |
| parent | 143070e74630b9557e1bb64d899ff2cc5a1dcb48 (diff) | |
| parent | 947391cfbaa3b08558844c0b187bcd0223c3f660 (diff) | |
Merge branch 'next-mtd' of git://aeryn.fluff.org.uk/bjdooks/linux
Diffstat (limited to 'fs/namespace.c')
| -rw-r--r-- | fs/namespace.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 41196209a906..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) */ int generic_show_options(struct seq_file *m, struct vfsmount *mnt) { - const char *options = mnt->mnt_sb->s_options; + const char *options; + + rcu_read_lock(); + options = rcu_dereference(mnt->mnt_sb->s_options); if (options != NULL && options[0]) { seq_putc(m, ','); mangle(m, options); } + rcu_read_unlock(); return 0; } @@ -721,11 +725,22 @@ EXPORT_SYMBOL(generic_show_options); */ void save_mount_options(struct super_block *sb, char *options) { - kfree(sb->s_options); - sb->s_options = kstrdup(options, GFP_KERNEL); + BUG_ON(sb->s_options); + rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL)); } EXPORT_SYMBOL(save_mount_options); +void replace_mount_options(struct super_block *sb, char *options) +{ + char *old = sb->s_options; + rcu_assign_pointer(sb->s_options, options); + if (old) { + synchronize_rcu(); + kfree(old); + } +} +EXPORT_SYMBOL(replace_mount_options); + #ifdef CONFIG_PROC_FS /* iterator */ static void *m_start(struct seq_file *m, loff_t *pos) @@ -1073,9 +1088,7 @@ static int do_umount(struct vfsmount *mnt, int flags) */ if (flags & MNT_FORCE && sb->s_op->umount_begin) { - lock_kernel(); sb->s_op->umount_begin(sb); - unlock_kernel(); } /* |
