dm thin: relax hard limit on the maximum size of a metadata device

The thin metadata format can only make use of a device that is <=
THIN_METADATA_MAX_SECTORS (currently 15.9375 GB).  Therefore, there is no
practical benefit to using a larger device.

However, it may be that other factors impose a certain granularity for
the space that is allocated to a device (E.g. lvm2 can impose a coarse
granularity through the use of large, >= 1 GB, physical extents).

Rather than reject a larger metadata device, during thin-pool device
construction, switch to allowing it but issue a warning if a device
larger than THIN_METADATA_MAX_SECTORS_WARNING (16 GB) is
provided.  Any space over 15.9375 GB will not be used.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
Mike Snitzer
2012-03-28 18:41:28 +01:00
committed by Alasdair G Kergon
parent 71fd5ae25d
commit c4a69ecdb4
4 changed files with 25 additions and 18 deletions

View File

@@ -32,16 +32,6 @@
#define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (64 * 1024 >> SECTOR_SHIFT)
#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
/*
* The metadata device is currently limited in size. The limitation is
* checked lower down in dm-space-map-metadata, but we also check it here
* so we can fail early.
*
* We have one block of index, which can hold 255 index entries. Each
* index entry contains allocation info about 16k metadata blocks.
*/
#define METADATA_DEV_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT)))
/*
* Device id is restricted to 24 bits.
*/
@@ -1736,6 +1726,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
dm_block_t low_water_blocks;
struct dm_dev *metadata_dev;
sector_t metadata_dev_size;
char b[BDEVNAME_SIZE];
/*
* FIXME Remove validation from scope of lock.
@@ -1757,11 +1748,9 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
}
metadata_dev_size = i_size_read(metadata_dev->bdev->bd_inode) >> SECTOR_SHIFT;
if (metadata_dev_size > METADATA_DEV_MAX_SECTORS) {
ti->error = "Metadata device is too large";
r = -EINVAL;
goto out_metadata;
}
if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING)
DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.",
bdevname(metadata_dev->bdev, b), THIN_METADATA_MAX_SECTORS);
r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev);
if (r) {