diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-21 14:22:20 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-22 21:02:16 -0400 |
commit | c5ca48aabe8b11674bf1102abe52d17ecc053f9c (patch) | |
tree | 18c7647b42981d457c59cd4a842ca342a239770d /fs/nilfs2/super.c | |
parent | 1a80a1763fb760b3a84a28df87515f7cdc07a4f4 (diff) |
nilfs2: reject incompatible filesystem
This forces nilfs to check compatibility of feature flags so as to
reject a filesystem with unknown features when it mounts or remounts
the filesystem.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 164457316df1..26078b3407c9 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -790,6 +790,30 @@ int nilfs_store_magic_and_option(struct super_block *sb, | |||
790 | return !parse_options(data, sb, 0) ? -EINVAL : 0 ; | 790 | return !parse_options(data, sb, 0) ? -EINVAL : 0 ; |
791 | } | 791 | } |
792 | 792 | ||
793 | int nilfs_check_feature_compatibility(struct super_block *sb, | ||
794 | struct nilfs_super_block *sbp) | ||
795 | { | ||
796 | __u64 features; | ||
797 | |||
798 | features = le64_to_cpu(sbp->s_feature_incompat) & | ||
799 | ~NILFS_FEATURE_INCOMPAT_SUPP; | ||
800 | if (features) { | ||
801 | printk(KERN_ERR "NILFS: couldn't mount because of unsupported " | ||
802 | "optional features (%llx)\n", | ||
803 | (unsigned long long)features); | ||
804 | return -EINVAL; | ||
805 | } | ||
806 | features = le64_to_cpu(sbp->s_feature_compat_ro) & | ||
807 | ~NILFS_FEATURE_COMPAT_RO_SUPP; | ||
808 | if (!(sb->s_flags & MS_RDONLY) && features) { | ||
809 | printk(KERN_ERR "NILFS: couldn't mount RDWR because of " | ||
810 | "unsupported optional features (%llx)\n", | ||
811 | (unsigned long long)features); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | return 0; | ||
815 | } | ||
816 | |||
793 | /** | 817 | /** |
794 | * nilfs_fill_super() - initialize a super block instance | 818 | * nilfs_fill_super() - initialize a super block instance |
795 | * @sb: super_block | 819 | * @sb: super_block |
@@ -984,11 +1008,26 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
984 | nilfs_cleanup_super(sbi); | 1008 | nilfs_cleanup_super(sbi); |
985 | up_write(&nilfs->ns_sem); | 1009 | up_write(&nilfs->ns_sem); |
986 | } else { | 1010 | } else { |
1011 | __u64 features; | ||
1012 | |||
987 | /* | 1013 | /* |
988 | * Mounting a RDONLY partition read-write, so reread and | 1014 | * Mounting a RDONLY partition read-write, so reread and |
989 | * store the current valid flag. (It may have been changed | 1015 | * store the current valid flag. (It may have been changed |
990 | * by fsck since we originally mounted the partition.) | 1016 | * by fsck since we originally mounted the partition.) |
991 | */ | 1017 | */ |
1018 | down_read(&nilfs->ns_sem); | ||
1019 | features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) & | ||
1020 | ~NILFS_FEATURE_COMPAT_RO_SUPP; | ||
1021 | up_read(&nilfs->ns_sem); | ||
1022 | if (features) { | ||
1023 | printk(KERN_WARNING "NILFS (device %s): couldn't " | ||
1024 | "remount RDWR because of unsupported optional " | ||
1025 | "features (%llx)\n", | ||
1026 | sb->s_id, (unsigned long long)features); | ||
1027 | err = -EROFS; | ||
1028 | goto restore_opts; | ||
1029 | } | ||
1030 | |||
992 | sb->s_flags &= ~MS_RDONLY; | 1031 | sb->s_flags &= ~MS_RDONLY; |
993 | 1032 | ||
994 | err = nilfs_attach_segment_constructor(sbi); | 1033 | err = nilfs_attach_segment_constructor(sbi); |