diff options
| -rw-r--r-- | fs/nilfs2/super.c | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index c88e66417330..03b34b738993 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
| @@ -754,9 +754,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
| 754 | goto failed_sbi; | 754 | goto failed_sbi; |
| 755 | } | 755 | } |
| 756 | cno = sbi->s_snapshot_cno; | 756 | cno = sbi->s_snapshot_cno; |
| 757 | } else | 757 | } |
| 758 | /* Read-only mount */ | ||
| 759 | sbi->s_snapshot_cno = cno; | ||
| 760 | } | 758 | } |
| 761 | 759 | ||
| 762 | err = nilfs_attach_checkpoint(sbi, cno); | 760 | err = nilfs_attach_checkpoint(sbi, cno); |
| @@ -825,7 +823,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 825 | struct the_nilfs *nilfs = sbi->s_nilfs; | 823 | struct the_nilfs *nilfs = sbi->s_nilfs; |
| 826 | unsigned long old_sb_flags; | 824 | unsigned long old_sb_flags; |
| 827 | struct nilfs_mount_options old_opts; | 825 | struct nilfs_mount_options old_opts; |
| 828 | int err; | 826 | int was_snapshot, err; |
| 829 | 827 | ||
| 830 | lock_kernel(); | 828 | lock_kernel(); |
| 831 | 829 | ||
| @@ -833,6 +831,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 833 | old_sb_flags = sb->s_flags; | 831 | old_sb_flags = sb->s_flags; |
| 834 | old_opts.mount_opt = sbi->s_mount_opt; | 832 | old_opts.mount_opt = sbi->s_mount_opt; |
| 835 | old_opts.snapshot_cno = sbi->s_snapshot_cno; | 833 | old_opts.snapshot_cno = sbi->s_snapshot_cno; |
| 834 | was_snapshot = nilfs_test_opt(sbi, SNAPSHOT); | ||
| 836 | 835 | ||
| 837 | if (!parse_options(data, sb)) { | 836 | if (!parse_options(data, sb)) { |
| 838 | err = -EINVAL; | 837 | err = -EINVAL; |
| @@ -840,20 +839,32 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 840 | } | 839 | } |
| 841 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL); | 840 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL); |
| 842 | 841 | ||
| 843 | if ((*flags & MS_RDONLY) && | 842 | err = -EINVAL; |
| 844 | sbi->s_snapshot_cno != old_opts.snapshot_cno) { | 843 | if (was_snapshot) { |
| 845 | printk(KERN_WARNING "NILFS (device %s): couldn't " | 844 | if (!(*flags & MS_RDONLY)) { |
| 846 | "remount to a different snapshot.\n", | 845 | printk(KERN_ERR "NILFS (device %s): cannot remount " |
| 847 | sb->s_id); | 846 | "snapshot read/write.\n", |
| 848 | err = -EINVAL; | 847 | sb->s_id); |
| 849 | goto restore_opts; | 848 | goto restore_opts; |
| 849 | } else if (sbi->s_snapshot_cno != old_opts.snapshot_cno) { | ||
| 850 | printk(KERN_ERR "NILFS (device %s): cannot " | ||
| 851 | "remount to a different snapshot.\n", | ||
| 852 | sb->s_id); | ||
| 853 | goto restore_opts; | ||
| 854 | } | ||
| 855 | } else { | ||
| 856 | if (nilfs_test_opt(sbi, SNAPSHOT)) { | ||
| 857 | printk(KERN_ERR "NILFS (device %s): cannot change " | ||
| 858 | "a regular mount to a snapshot.\n", | ||
| 859 | sb->s_id); | ||
| 860 | goto restore_opts; | ||
| 861 | } | ||
| 850 | } | 862 | } |
| 851 | 863 | ||
| 852 | if (!nilfs_valid_fs(nilfs)) { | 864 | if (!nilfs_valid_fs(nilfs)) { |
| 853 | printk(KERN_WARNING "NILFS (device %s): couldn't " | 865 | printk(KERN_WARNING "NILFS (device %s): couldn't " |
| 854 | "remount because the filesystem is in an " | 866 | "remount because the filesystem is in an " |
| 855 | "incomplete recovery state.\n", sb->s_id); | 867 | "incomplete recovery state.\n", sb->s_id); |
| 856 | err = -EINVAL; | ||
| 857 | goto restore_opts; | 868 | goto restore_opts; |
| 858 | } | 869 | } |
| 859 | 870 | ||
| @@ -864,9 +875,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 864 | nilfs_detach_segment_constructor(sbi); | 875 | nilfs_detach_segment_constructor(sbi); |
| 865 | sb->s_flags |= MS_RDONLY; | 876 | sb->s_flags |= MS_RDONLY; |
| 866 | 877 | ||
| 867 | sbi->s_snapshot_cno = nilfs_last_cno(nilfs); | ||
| 868 | /* nilfs_set_opt(sbi, SNAPSHOT); */ | ||
| 869 | |||
| 870 | /* | 878 | /* |
| 871 | * Remounting a valid RW partition RDONLY, so set | 879 | * Remounting a valid RW partition RDONLY, so set |
| 872 | * the RDONLY flag and then mark the partition as valid again. | 880 | * the RDONLY flag and then mark the partition as valid again. |
| @@ -885,24 +893,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 885 | * store the current valid flag. (It may have been changed | 893 | * store the current valid flag. (It may have been changed |
| 886 | * by fsck since we originally mounted the partition.) | 894 | * by fsck since we originally mounted the partition.) |
| 887 | */ | 895 | */ |
| 888 | if (nilfs->ns_current && nilfs->ns_current != sbi) { | ||
| 889 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
| 890 | "remount because an RW-mount exists.\n", | ||
| 891 | sb->s_id); | ||
| 892 | err = -EBUSY; | ||
| 893 | goto restore_opts; | ||
| 894 | } | ||
| 895 | if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) { | ||
| 896 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
| 897 | "remount because the current RO-mount is not " | ||
| 898 | "the latest one.\n", | ||
| 899 | sb->s_id); | ||
| 900 | err = -EINVAL; | ||
| 901 | goto restore_opts; | ||
| 902 | } | ||
| 903 | sb->s_flags &= ~MS_RDONLY; | 896 | sb->s_flags &= ~MS_RDONLY; |
| 904 | nilfs_clear_opt(sbi, SNAPSHOT); | ||
| 905 | sbi->s_snapshot_cno = 0; | ||
| 906 | 897 | ||
| 907 | err = nilfs_attach_segment_constructor(sbi); | 898 | err = nilfs_attach_segment_constructor(sbi); |
| 908 | if (err) | 899 | if (err) |
| @@ -911,8 +902,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 911 | down_write(&nilfs->ns_sem); | 902 | down_write(&nilfs->ns_sem); |
| 912 | nilfs_setup_super(sbi); | 903 | nilfs_setup_super(sbi); |
| 913 | up_write(&nilfs->ns_sem); | 904 | up_write(&nilfs->ns_sem); |
| 914 | |||
| 915 | nilfs->ns_current = sbi; | ||
| 916 | } | 905 | } |
| 917 | out: | 906 | out: |
| 918 | up_write(&nilfs->ns_super_sem); | 907 | up_write(&nilfs->ns_super_sem); |
