diff options
author | Mike Snitzer <snitzer@redhat.com> | 2012-07-27 15:08:13 +0100 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 15:08:13 +0100 |
commit | d73ec52538041f29a8ae22bc72521222279439b9 (patch) | |
tree | 2bd99685c1e5b67f7486920d97d65295e4d61508 /drivers/md/dm-thin-metadata.c | |
parent | b79399510888998778ea6a3a281e30cbe59fdb37 (diff) | |
download | linux-d73ec52538041f29a8ae22bc72521222279439b9.tar.gz linux-d73ec52538041f29a8ae22bc72521222279439b9.tar.bz2 linux-d73ec52538041f29a8ae22bc72521222279439b9.zip |
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: return r; } +static int __check_incompat_features(struct thin_disk_superblock *disk_super, + struct dm_pool_metadata *pmd) +{ + uint32_t features; + + features = le32_to_cpu(disk_super->incompat_flags) & ~THIN_FEATURE_INCOMPAT_SUPP; + if (features) { + DMERR("could not access metadata due to unsupported optional features (%lx).", + (unsigned long)features); + return -EINVAL; + } + + /* + * Check for read-only metadata to skip the following RDWR checks. + */ + if (get_disk_ro(pmd->bdev->bd_disk)) + return 0; + + features = le32_to_cpu(disk_super->compat_ro_flags) & ~THIN_FEATURE_COMPAT_RO_SUPP; + if (features) { + DMERR("could not access metadata RDWR due to unsupported optional features (%lx).", + (unsigned long)features); + return -EINVAL; + } + + return 0; +} + static int __open_metadata(struct dm_pool_metadata *pmd) { int r; @@ -551,6 +579,13 @@ static int __open_metadata(struct dm_pool_metadata *pmd) } disk_super = dm_block_data(sblock); + + r = __check_incompat_features(disk_super, pmd); + if (r < 0) { + dm_bm_unlock(sblock); + return r; + } + r = dm_tm_open_with_sm(pmd->bm, THIN_SUPERBLOCK_LOCATION, disk_super->metadata_space_map_root, sizeof(disk_super->metadata_space_map_root), @@ -635,7 +670,6 @@ static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd) static int __begin_transaction(struct dm_pool_metadata *pmd) { int r; - u32 features; struct thin_disk_superblock *disk_super; struct dm_block *sblock; @@ -656,32 +690,8 @@ static int __begin_transaction(struct dm_pool_metadata *pmd) pmd->flags = le32_to_cpu(disk_super->flags); pmd->data_block_size = le32_to_cpu(disk_super->data_block_size); - features = le32_to_cpu(disk_super->incompat_flags) & ~THIN_FEATURE_INCOMPAT_SUPP; - if (features) { - DMERR("could not access metadata due to " - "unsupported optional features (%lx).", - (unsigned long)features); - r = -EINVAL; - goto out; - } - - /* - * Check for read-only metadata to skip the following RDWR checks. - */ - if (get_disk_ro(pmd->bdev->bd_disk)) - goto out; - - features = le32_to_cpu(disk_super->compat_ro_flags) & ~THIN_FEATURE_COMPAT_RO_SUPP; - if (features) { - DMERR("could not access metadata RDWR due to " - "unsupported optional features (%lx).", - (unsigned long)features); - r = -EINVAL; - } - -out: dm_bm_unlock(sblock); - return r; + return 0; } static int __write_changed_details(struct dm_pool_metadata *pmd) |