nilfs2: reject incompatible filesystem
[deliverable/linux.git] / fs / nilfs2 / the_nilfs.c
index f2efc8c5be7fbd6a75f7f4773b095ec9c63037d3..da67b560f3c3f31d05ecf025ad1271c5ce197626 100644 (file)
@@ -385,11 +385,23 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
                goto skip_recovery;
 
        if (s_flags & MS_RDONLY) {
+               __u64 features;
+
                if (nilfs_test_opt(sbi, NORECOVERY)) {
                        printk(KERN_INFO "NILFS: norecovery option specified. "
                               "skipping roll-forward recovery\n");
                        goto skip_recovery;
                }
+               features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
+                       ~NILFS_FEATURE_COMPAT_RO_SUPP;
+               if (features) {
+                       printk(KERN_ERR "NILFS: couldn't proceed with "
+                              "recovery because of unsupported optional "
+                              "features (%llx)\n",
+                              (unsigned long long)features);
+                       err = -EROFS;
+                       goto failed_unload;
+               }
                if (really_read_only) {
                        printk(KERN_ERR "NILFS: write access "
                               "unavailable, cannot proceed.\n");
@@ -644,6 +656,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
                if (err)
                        goto out;
 
+               err = nilfs_check_feature_compatibility(sb, sbp);
+               if (err)
+                       goto out;
+
                blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
                if (sb->s_blocksize != blocksize &&
                    !sb_set_blocksize(sb, blocksize)) {
@@ -669,6 +685,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
        if (err)
                goto failed_sbh;
 
+       err = nilfs_check_feature_compatibility(sb, sbp);
+       if (err)
+               goto failed_sbh;
+
        blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
        if (sb->s_blocksize != blocksize) {
                int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
This page took 0.026495 seconds and 5 git commands to generate.