aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2012-03-28 13:41:28 -0400
committerAlasdair G Kergon <agk@redhat.com>2012-03-28 13:41:28 -0400
commitc4a69ecdb463a901b4645230613961e134e897cd (patch)
treec53e0a569f3d390ea2a97f964225d5383c6401ec /drivers/md
parent71fd5ae25d88841c08d5bbea90c0f0a12ca05509 (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.c3
-rw-r--r--drivers/md/dm-thin-metadata.h13
-rw-r--r--drivers/md/dm-thin.c19
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
16struct dm_pool_metadata; 29struct 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) {