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>
This commit is contained in:
Mike Snitzer 2012-07-27 15:08:13 +01:00 committed by Alasdair G Kergon
parent b793995108
commit d73ec52538
1 changed files with 36 additions and 26 deletions

View File

@ -537,6 +537,34 @@ static int __format_metadata(struct dm_pool_metadata *pmd)
return r; 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) static int __open_metadata(struct dm_pool_metadata *pmd)
{ {
int r; int r;
@ -551,6 +579,13 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
} }
disk_super = dm_block_data(sblock); 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, r = dm_tm_open_with_sm(pmd->bm, THIN_SUPERBLOCK_LOCATION,
disk_super->metadata_space_map_root, disk_super->metadata_space_map_root,
sizeof(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) static int __begin_transaction(struct dm_pool_metadata *pmd)
{ {
int r; int r;
u32 features;
struct thin_disk_superblock *disk_super; struct thin_disk_superblock *disk_super;
struct dm_block *sblock; 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->flags = le32_to_cpu(disk_super->flags);
pmd->data_block_size = le32_to_cpu(disk_super->data_block_size); 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); dm_bm_unlock(sblock);
return r; return 0;
} }
static int __write_changed_details(struct dm_pool_metadata *pmd) static int __write_changed_details(struct dm_pool_metadata *pmd)