aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/device-mapper/thin-provisioning.txt8
-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
4 files changed, 25 insertions, 18 deletions
diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt
index da50347c005..a119fbdd060 100644
--- a/Documentation/device-mapper/thin-provisioning.txt
+++ b/Documentation/device-mapper/thin-provisioning.txt
@@ -75,10 +75,12 @@ less sharing than average you'll need a larger-than-average metadata device.
75 75
76As a guide, we suggest you calculate the number of bytes to use in the 76As a guide, we suggest you calculate the number of bytes to use in the
77metadata device as 48 * $data_dev_size / $data_block_size but round it up 77metadata device as 48 * $data_dev_size / $data_block_size but round it up
78to 2MB if the answer is smaller. The largest size supported is 16GB. 78to 2MB if the answer is smaller. If you're creating large numbers of
79snapshots which are recording large amounts of change, you may find you
80need to increase this.
79 81
80If you're creating large numbers of snapshots which are recording large 82The largest size supported is 16GB: If the device is larger,
81amounts of change, you may need find you need to increase this. 83a warning will be issued and the excess space will not be used.
82 84
83Reloading a pool table 85Reloading a pool table
84---------------------- 86----------------------
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index a680c761341..737d38865b6 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 859c1689687..ed4725e67c9 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 bcb143396fe..2378ee88b1e 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) {