diff options
| author | Mike Snitzer <snitzer@redhat.com> | 2014-02-12 23:58:15 -0500 | 
|---|---|---|
| committer | Mike Snitzer <snitzer@redhat.com> | 2014-02-27 11:49:08 -0500 | 
| commit | 7d48935eff401bb7970e73e822871a10e3643df1 (patch) | |
| tree | cc7523512553a162b66e37d022da2c2e8acfee22 /drivers/md/persistent-data | |
| parent | a1989b330093578ea5470bea0a00f940c444c466 (diff) | |
dm thin: allow metadata space larger than supported to go unused
It was always intended that a user could provide a thin metadata device
that is larger than the max supported by the on-disk format.  The extra
space would just go unused.
Unfortunately that never worked.  If the user attempted to use a larger
metadata device on creation they would get an error like the following:
 device-mapper: space map common: space map too large
 device-mapper: transaction manager: couldn't create metadata space map
 device-mapper: thin metadata: tm_create_with_sm failed
 device-mapper: table: 252:17: thin-pool: Error creating metadata object
 device-mapper: ioctl: error adding target to table
Fix this by allowing the initial metadata space map creation to cap its
size at the max number of blocks supported (DM_SM_METADATA_MAX_BLOCKS).
get_metadata_dev_size() must also impose DM_SM_METADATA_MAX_BLOCKS (via
THIN_METADATA_MAX_SECTORS), otherwise extending metadata would cap at
THIN_METADATA_MAX_SECTORS_WARNING (which is larger than supported).
Also, the calculation for THIN_METADATA_MAX_SECTORS didn't account for
the sizeof the disk_bitmap_header.  So the supported maximum metadata
size is a bit smaller (reduced from 33423360 to 33292800 sectors).
Lastly, remove the "excess space will not be used" warning message from
get_metadata_dev_size(); it resulted in printing the warning multiple
times.  Factor out warn_if_metadata_device_too_big(), call it from
pool_ctr() and maybe_resize_metadata_dev().
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Acked-by: Joe Thornber <ejt@redhat.com>
Diffstat (limited to 'drivers/md/persistent-data')
| -rw-r--r-- | drivers/md/persistent-data/dm-space-map-metadata.c | 2 | ||||
| -rw-r--r-- | drivers/md/persistent-data/dm-space-map-metadata.h | 11 | 
2 files changed, 13 insertions, 0 deletions
| diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c index 536782e3bcb7..e9bdd462f4f5 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c @@ -680,6 +680,8 @@ int dm_sm_metadata_create(struct dm_space_map *sm,  	if (r)  		return r; +	if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS) +		nr_blocks = DM_SM_METADATA_MAX_BLOCKS;  	r = sm_ll_extend(&smm->ll, nr_blocks);  	if (r)  		return r; diff --git a/drivers/md/persistent-data/dm-space-map-metadata.h b/drivers/md/persistent-data/dm-space-map-metadata.h index 39bba0801cf2..64df923974d8 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.h +++ b/drivers/md/persistent-data/dm-space-map-metadata.h @@ -9,6 +9,17 @@  #include "dm-transaction-manager.h" +#define DM_SM_METADATA_BLOCK_SIZE (4096 >> SECTOR_SHIFT) + +/* + * The metadata device is currently limited in size. + * + * We have one block of index, which can hold 255 index entries.  Each + * index entry contains allocation info about ~16k metadata blocks. + */ +#define DM_SM_METADATA_MAX_BLOCKS (255 * ((1 << 14) - 64)) +#define DM_SM_METADATA_MAX_SECTORS (DM_SM_METADATA_MAX_BLOCKS * DM_SM_METADATA_BLOCK_SIZE) +  /*   * Unfortunately we have to use two-phase construction due to the cycle   * between the tm and sm. | 
