diff options
Diffstat (limited to 'fs/nilfs2/the_nilfs.c')
-rw-r--r-- | fs/nilfs2/the_nilfs.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index f2efc8c5be7f..da67b560f3c3 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -385,11 +385,23 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | |||
385 | goto skip_recovery; | 385 | goto skip_recovery; |
386 | 386 | ||
387 | if (s_flags & MS_RDONLY) { | 387 | if (s_flags & MS_RDONLY) { |
388 | __u64 features; | ||
389 | |||
388 | if (nilfs_test_opt(sbi, NORECOVERY)) { | 390 | if (nilfs_test_opt(sbi, NORECOVERY)) { |
389 | printk(KERN_INFO "NILFS: norecovery option specified. " | 391 | printk(KERN_INFO "NILFS: norecovery option specified. " |
390 | "skipping roll-forward recovery\n"); | 392 | "skipping roll-forward recovery\n"); |
391 | goto skip_recovery; | 393 | goto skip_recovery; |
392 | } | 394 | } |
395 | features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) & | ||
396 | ~NILFS_FEATURE_COMPAT_RO_SUPP; | ||
397 | if (features) { | ||
398 | printk(KERN_ERR "NILFS: couldn't proceed with " | ||
399 | "recovery because of unsupported optional " | ||
400 | "features (%llx)\n", | ||
401 | (unsigned long long)features); | ||
402 | err = -EROFS; | ||
403 | goto failed_unload; | ||
404 | } | ||
393 | if (really_read_only) { | 405 | if (really_read_only) { |
394 | printk(KERN_ERR "NILFS: write access " | 406 | printk(KERN_ERR "NILFS: write access " |
395 | "unavailable, cannot proceed.\n"); | 407 | "unavailable, cannot proceed.\n"); |
@@ -644,6 +656,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) | |||
644 | if (err) | 656 | if (err) |
645 | goto out; | 657 | goto out; |
646 | 658 | ||
659 | err = nilfs_check_feature_compatibility(sb, sbp); | ||
660 | if (err) | ||
661 | goto out; | ||
662 | |||
647 | blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); | 663 | blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); |
648 | if (sb->s_blocksize != blocksize && | 664 | if (sb->s_blocksize != blocksize && |
649 | !sb_set_blocksize(sb, blocksize)) { | 665 | !sb_set_blocksize(sb, blocksize)) { |
@@ -669,6 +685,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) | |||
669 | if (err) | 685 | if (err) |
670 | goto failed_sbh; | 686 | goto failed_sbh; |
671 | 687 | ||
688 | err = nilfs_check_feature_compatibility(sb, sbp); | ||
689 | if (err) | ||
690 | goto failed_sbh; | ||
691 | |||
672 | blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); | 692 | blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); |
673 | if (sb->s_blocksize != blocksize) { | 693 | if (sb->s_blocksize != blocksize) { |
674 | int hw_blocksize = bdev_logical_block_size(sb->s_bdev); | 694 | int hw_blocksize = bdev_logical_block_size(sb->s_bdev); |