diff options
author | Mike Snitzer <snitzer@redhat.com> | 2012-03-28 13:41:28 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-03-28 13:41:28 -0400 |
commit | c4a69ecdb463a901b4645230613961e134e897cd (patch) | |
tree | c53e0a569f3d390ea2a97f964225d5383c6401ec /drivers/md | |
parent | 71fd5ae25d88841c08d5bbea90c0f0a12ca05509 (diff) |
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>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-thin-metadata.c | 3 | ||||
-rw-r--r-- | drivers/md/dm-thin-metadata.h | 13 | ||||
-rw-r--r-- | drivers/md/dm-thin.c | 19 |
3 files changed, 20 insertions, 15 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index a680c761341f..737d38865b69 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -713,6 +713,9 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, | |||
713 | if (r) | 713 | if (r) |
714 | goto bad; | 714 | goto bad; |
715 | 715 | ||
716 | if (bdev_size > THIN_METADATA_MAX_SECTORS) | ||
717 | bdev_size = THIN_METADATA_MAX_SECTORS; | ||
718 | |||
716 | disk_super = dm_block_data(sblock); | 719 | disk_super = dm_block_data(sblock); |
717 | disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC); | 720 | disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC); |
718 | disk_super->version = cpu_to_le32(THIN_VERSION); | 721 | disk_super->version = cpu_to_le32(THIN_VERSION); |
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index 859c16896877..ed4725e67c96 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h | |||
@@ -11,6 +11,19 @@ | |||
11 | 11 | ||
12 | #define THIN_METADATA_BLOCK_SIZE 4096 | 12 | #define THIN_METADATA_BLOCK_SIZE 4096 |
13 | 13 | ||
14 | /* | ||
15 | * The metadata device is currently limited in size. | ||
16 | * | ||
17 | * We have one block of index, which can hold 255 index entries. Each | ||
18 | * index entry contains allocation info about 16k metadata blocks. | ||
19 | */ | ||
20 | #define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT))) | ||
21 | |||
22 | /* | ||
23 | * A metadata device larger than 16GB triggers a warning. | ||
24 | */ | ||
25 | #define THIN_METADATA_MAX_SECTORS_WARNING (16 * (1024 * 1024 * 1024 >> SECTOR_SHIFT)) | ||
26 | |||
14 | /*----------------------------------------------------------------*/ | 27 | /*----------------------------------------------------------------*/ |
15 | 28 | ||
16 | struct dm_pool_metadata; | 29 | struct dm_pool_metadata; |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index bcb143396fe0..2378ee88b1e8 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -33,16 +33,6 @@ | |||
33 | #define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT) | 33 | #define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT) |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * The metadata device is currently limited in size. The limitation is | ||
37 | * checked lower down in dm-space-map-metadata, but we also check it here | ||
38 | * so we can fail early. | ||
39 | * | ||
40 | * We have one block of index, which can hold 255 index entries. Each | ||
41 | * index entry contains allocation info about 16k metadata blocks. | ||
42 | */ | ||
43 | #define METADATA_DEV_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT))) | ||
44 | |||
45 | /* | ||
46 | * Device id is restricted to 24 bits. | 36 | * Device id is restricted to 24 bits. |
47 | */ | 37 | */ |
48 | #define MAX_DEV_ID ((1 << 24) - 1) | 38 | #define MAX_DEV_ID ((1 << 24) - 1) |
@@ -1736,6 +1726,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
1736 | dm_block_t low_water_blocks; | 1726 | dm_block_t low_water_blocks; |
1737 | struct dm_dev *metadata_dev; | 1727 | struct dm_dev *metadata_dev; |
1738 | sector_t metadata_dev_size; | 1728 | sector_t metadata_dev_size; |
1729 | char b[BDEVNAME_SIZE]; | ||
1739 | 1730 | ||
1740 | /* | 1731 | /* |
1741 | * FIXME Remove validation from scope of lock. | 1732 | * FIXME Remove validation from scope of lock. |
@@ -1757,11 +1748,9 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
1757 | } | 1748 | } |
1758 | 1749 | ||
1759 | metadata_dev_size = i_size_read(metadata_dev->bdev->bd_inode) >> SECTOR_SHIFT; | 1750 | metadata_dev_size = i_size_read(metadata_dev->bdev->bd_inode) >> SECTOR_SHIFT; |
1760 | if (metadata_dev_size > METADATA_DEV_MAX_SECTORS) { | 1751 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) |
1761 | ti->error = "Metadata device is too large"; | 1752 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", |
1762 | r = -EINVAL; | 1753 | bdevname(metadata_dev->bdev, b), THIN_METADATA_MAX_SECTORS); |
1763 | goto out_metadata; | ||
1764 | } | ||
1765 | 1754 | ||
1766 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); | 1755 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); |
1767 | if (r) { | 1756 | if (r) { |