diff options
author | Mike Snitzer <snitzer@redhat.com> | 2012-07-27 10:08:13 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 10:08:13 -0400 |
commit | d73ec52538041f29a8ae22bc72521222279439b9 (patch) | |
tree | 2bd99685c1e5b67f7486920d97d65295e4d61508 /drivers/md/dm-thin-metadata.c | |
parent | b79399510888998778ea6a3a281e30cbe59fdb37 (diff) |
dm thin metadata: only check incompat features on open
Factor out __check_incompat_features and only call it once when we open
the metadata device rather than at the beginning of every transaction.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-thin-metadata.c')
-rw-r--r-- | drivers/md/dm-thin-metadata.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 51b97f07aca3..867ee52121d4 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -537,6 +537,34 @@ bad: | |||
537 | return r; | 537 | return r; |
538 | } | 538 | } |
539 | 539 | ||
540 | static int __check_incompat_features(struct thin_disk_superblock *disk_super, | ||
541 | struct dm_pool_metadata *pmd) | ||
542 | { | ||
543 | uint32_t features; | ||
544 | |||
545 | features = le32_to_cpu(disk_super->incompat_flags) & ~THIN_FEATURE_INCOMPAT_SUPP; | ||
546 | if (features) { | ||
547 | DMERR("could not access metadata due to unsupported optional features (%lx).", | ||
548 | (unsigned long)features); | ||
549 | return -EINVAL; | ||
550 | } | ||
551 | |||
552 | /* | ||
553 | * Check for read-only metadata to skip the following RDWR checks. | ||
554 | */ | ||
555 | if (get_disk_ro(pmd->bdev->bd_disk)) | ||
556 | return 0; | ||
557 | |||
558 | features = le32_to_cpu(disk_super->compat_ro_flags) & ~THIN_FEATURE_COMPAT_RO_SUPP; | ||
559 | if (features) { | ||
560 | DMERR("could not access metadata RDWR due to unsupported optional features (%lx).", | ||
561 | (unsigned long)features); | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
540 | static int __open_metadata(struct dm_pool_metadata *pmd) | 568 | static int __open_metadata(struct dm_pool_metadata *pmd) |
541 | { | 569 | { |
542 | int r; | 570 | int r; |
@@ -551,6 +579,13 @@ static int __open_metadata(struct dm_pool_metadata *pmd) | |||
551 | } | 579 | } |
552 | 580 | ||
553 | disk_super = dm_block_data(sblock); | 581 | disk_super = dm_block_data(sblock); |
582 | |||
583 | r = __check_incompat_features(disk_super, pmd); | ||
584 | if (r < 0) { | ||
585 | dm_bm_unlock(sblock); | ||
586 | return r; | ||
587 | } | ||
588 | |||
554 | r = dm_tm_open_with_sm(pmd->bm, THIN_SUPERBLOCK_LOCATION, | 589 | r = dm_tm_open_with_sm(pmd->bm, THIN_SUPERBLOCK_LOCATION, |
555 | disk_super->metadata_space_map_root, | 590 | disk_super->metadata_space_map_root, |
556 | sizeof(disk_super->metadata_space_map_root), | 591 | sizeof(disk_super->metadata_space_map_root), |
@@ -635,7 +670,6 @@ static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd) | |||
635 | static int __begin_transaction(struct dm_pool_metadata *pmd) | 670 | static int __begin_transaction(struct dm_pool_metadata *pmd) |
636 | { | 671 | { |
637 | int r; | 672 | int r; |
638 | u32 features; | ||
639 | struct thin_disk_superblock *disk_super; | 673 | struct thin_disk_superblock *disk_super; |
640 | struct dm_block *sblock; | 674 | struct dm_block *sblock; |
641 | 675 | ||
@@ -656,32 +690,8 @@ static int __begin_transaction(struct dm_pool_metadata *pmd) | |||
656 | pmd->flags = le32_to_cpu(disk_super->flags); | 690 | pmd->flags = le32_to_cpu(disk_super->flags); |
657 | pmd->data_block_size = le32_to_cpu(disk_super->data_block_size); | 691 | pmd->data_block_size = le32_to_cpu(disk_super->data_block_size); |
658 | 692 | ||
659 | features = le32_to_cpu(disk_super->incompat_flags) & ~THIN_FEATURE_INCOMPAT_SUPP; | ||
660 | if (features) { | ||
661 | DMERR("could not access metadata due to " | ||
662 | "unsupported optional features (%lx).", | ||
663 | (unsigned long)features); | ||
664 | r = -EINVAL; | ||
665 | goto out; | ||
666 | } | ||
667 | |||
668 | /* | ||
669 | * Check for read-only metadata to skip the following RDWR checks. | ||
670 | */ | ||
671 | if (get_disk_ro(pmd->bdev->bd_disk)) | ||
672 | goto out; | ||
673 | |||
674 | features = le32_to_cpu(disk_super->compat_ro_flags) & ~THIN_FEATURE_COMPAT_RO_SUPP; | ||
675 | if (features) { | ||
676 | DMERR("could not access metadata RDWR due to " | ||
677 | "unsupported optional features (%lx).", | ||
678 | (unsigned long)features); | ||
679 | r = -EINVAL; | ||
680 | } | ||
681 | |||
682 | out: | ||
683 | dm_bm_unlock(sblock); | 693 | dm_bm_unlock(sblock); |
684 | return r; | 694 | return 0; |
685 | } | 695 | } |
686 | 696 | ||
687 | static int __write_changed_details(struct dm_pool_metadata *pmd) | 697 | static int __write_changed_details(struct dm_pool_metadata *pmd) |