diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/affs/super.c | 3 | ||||
| -rw-r--r-- | fs/afs/super.c | 4 | ||||
| -rw-r--r-- | fs/hpfs/super.c | 3 | ||||
| -rw-r--r-- | fs/namespace.c | 21 | ||||
| -rw-r--r-- | fs/reiserfs/super.c | 3 |
5 files changed, 23 insertions, 11 deletions
diff --git a/fs/affs/super.c b/fs/affs/super.c index 5ce695e707fe..63f5183f263b 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
| @@ -507,8 +507,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
| 507 | kfree(new_opts); | 507 | kfree(new_opts); |
| 508 | return -EINVAL; | 508 | return -EINVAL; |
| 509 | } | 509 | } |
| 510 | kfree(sb->s_options); | 510 | replace_mount_options(sb, new_opts); |
| 511 | sb->s_options = new_opts; | ||
| 512 | 511 | ||
| 513 | sbi->s_flags = mount_flags; | 512 | sbi->s_flags = mount_flags; |
| 514 | sbi->s_mode = mode; | 513 | sbi->s_mode = mode; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 2753f16dd315..76828e5f8a39 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
| @@ -408,17 +408,17 @@ static int afs_get_sb(struct file_system_type *fs_type, | |||
| 408 | deactivate_locked_super(sb); | 408 | deactivate_locked_super(sb); |
| 409 | goto error; | 409 | goto error; |
| 410 | } | 410 | } |
| 411 | sb->s_options = new_opts; | 411 | save_mount_options(sb, new_opts); |
| 412 | sb->s_flags |= MS_ACTIVE; | 412 | sb->s_flags |= MS_ACTIVE; |
| 413 | } else { | 413 | } else { |
| 414 | _debug("reuse"); | 414 | _debug("reuse"); |
| 415 | kfree(new_opts); | ||
| 416 | ASSERTCMP(sb->s_flags, &, MS_ACTIVE); | 415 | ASSERTCMP(sb->s_flags, &, MS_ACTIVE); |
| 417 | } | 416 | } |
| 418 | 417 | ||
| 419 | simple_set_mnt(mnt, sb); | 418 | simple_set_mnt(mnt, sb); |
| 420 | afs_put_volume(params.volume); | 419 | afs_put_volume(params.volume); |
| 421 | afs_put_cell(params.cell); | 420 | afs_put_cell(params.cell); |
| 421 | kfree(new_opts); | ||
| 422 | _leave(" = 0 [%p]", sb); | 422 | _leave(" = 0 [%p]", sb); |
| 423 | return 0; | 423 | return 0; |
| 424 | 424 | ||
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index fecf402d7b8a..fc77965be841 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
| @@ -423,8 +423,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) | |||
| 423 | 423 | ||
| 424 | if (!(*flags & MS_RDONLY)) mark_dirty(s); | 424 | if (!(*flags & MS_RDONLY)) mark_dirty(s); |
| 425 | 425 | ||
| 426 | kfree(s->s_options); | 426 | replace_mount_options(s, new_opts); |
| 427 | s->s_options = new_opts; | ||
| 428 | 427 | ||
| 429 | return 0; | 428 | return 0; |
| 430 | 429 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 0d2003fb4377..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) |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index d444fe0013a4..1215a4f50cd2 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -1316,8 +1316,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
| 1316 | } | 1316 | } |
| 1317 | 1317 | ||
| 1318 | out_ok: | 1318 | out_ok: |
| 1319 | kfree(s->s_options); | 1319 | replace_mount_options(s, new_opts); |
| 1320 | s->s_options = new_opts; | ||
| 1321 | return 0; | 1320 | return 0; |
| 1322 | 1321 | ||
| 1323 | out_err: | 1322 | out_err: |
