diff options
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 49 |
1 files changed, 26 insertions, 23 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 6a11243ebc51..952f4ccb18de 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -621,7 +621,7 @@ static match_table_t tokens = { | |||
621 | {Opt_err, NULL} | 621 | {Opt_err, NULL} |
622 | }; | 622 | }; |
623 | 623 | ||
624 | static int parse_options(char *options, struct super_block *sb) | 624 | static int parse_options(char *options, struct super_block *sb, int is_remount) |
625 | { | 625 | { |
626 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 626 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
627 | char *p; | 627 | char *p; |
@@ -666,8 +666,26 @@ static int parse_options(char *options, struct super_block *sb) | |||
666 | case Opt_snapshot: | 666 | case Opt_snapshot: |
667 | if (match_int(&args[0], &option) || option <= 0) | 667 | if (match_int(&args[0], &option) || option <= 0) |
668 | return 0; | 668 | return 0; |
669 | if (!(sb->s_flags & MS_RDONLY)) | 669 | if (is_remount) { |
670 | if (!nilfs_test_opt(sbi, SNAPSHOT)) { | ||
671 | printk(KERN_ERR | ||
672 | "NILFS: cannot change regular " | ||
673 | "mount to snapshot.\n"); | ||
674 | return 0; | ||
675 | } else if (option != sbi->s_snapshot_cno) { | ||
676 | printk(KERN_ERR | ||
677 | "NILFS: cannot remount to a " | ||
678 | "different snapshot.\n"); | ||
679 | return 0; | ||
680 | } | ||
681 | break; | ||
682 | } | ||
683 | if (!(sb->s_flags & MS_RDONLY)) { | ||
684 | printk(KERN_ERR "NILFS: cannot mount snapshot " | ||
685 | "read/write. A read-only option is " | ||
686 | "required.\n"); | ||
670 | return 0; | 687 | return 0; |
688 | } | ||
671 | sbi->s_snapshot_cno = option; | 689 | sbi->s_snapshot_cno = option; |
672 | nilfs_set_opt(sbi, SNAPSHOT); | 690 | nilfs_set_opt(sbi, SNAPSHOT); |
673 | break; | 691 | break; |
@@ -767,7 +785,7 @@ int nilfs_store_magic_and_option(struct super_block *sb, | |||
767 | sbi->s_interval = le32_to_cpu(sbp->s_c_interval); | 785 | sbi->s_interval = le32_to_cpu(sbp->s_c_interval); |
768 | sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max); | 786 | sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max); |
769 | 787 | ||
770 | return !parse_options(data, sb) ? -EINVAL : 0 ; | 788 | return !parse_options(data, sb, 0) ? -EINVAL : 0 ; |
771 | } | 789 | } |
772 | 790 | ||
773 | /** | 791 | /** |
@@ -929,32 +947,17 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
929 | old_opts.snapshot_cno = sbi->s_snapshot_cno; | 947 | old_opts.snapshot_cno = sbi->s_snapshot_cno; |
930 | was_snapshot = nilfs_test_opt(sbi, SNAPSHOT); | 948 | was_snapshot = nilfs_test_opt(sbi, SNAPSHOT); |
931 | 949 | ||
932 | if (!parse_options(data, sb)) { | 950 | if (!parse_options(data, sb, 1)) { |
933 | err = -EINVAL; | 951 | err = -EINVAL; |
934 | goto restore_opts; | 952 | goto restore_opts; |
935 | } | 953 | } |
936 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL); | 954 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL); |
937 | 955 | ||
938 | err = -EINVAL; | 956 | err = -EINVAL; |
939 | if (was_snapshot) { | 957 | if (was_snapshot && !(*flags & MS_RDONLY)) { |
940 | if (!(*flags & MS_RDONLY)) { | 958 | printk(KERN_ERR "NILFS (device %s): cannot remount snapshot " |
941 | printk(KERN_ERR "NILFS (device %s): cannot remount " | 959 | "read/write.\n", sb->s_id); |
942 | "snapshot read/write.\n", | 960 | goto restore_opts; |
943 | sb->s_id); | ||
944 | goto restore_opts; | ||
945 | } else if (sbi->s_snapshot_cno != old_opts.snapshot_cno) { | ||
946 | printk(KERN_ERR "NILFS (device %s): cannot " | ||
947 | "remount to a different snapshot.\n", | ||
948 | sb->s_id); | ||
949 | goto restore_opts; | ||
950 | } | ||
951 | } else { | ||
952 | if (nilfs_test_opt(sbi, SNAPSHOT)) { | ||
953 | printk(KERN_ERR "NILFS (device %s): cannot change " | ||
954 | "a regular mount to a snapshot.\n", | ||
955 | sb->s_id); | ||
956 | goto restore_opts; | ||
957 | } | ||
958 | } | 961 | } |
959 | 962 | ||
960 | if (!nilfs_valid_fs(nilfs)) { | 963 | if (!nilfs_valid_fs(nilfs)) { |