Skip to content

Commit c4a69ec

Browse files
snitmkergon
authored andcommitted
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 <[email protected]> Signed-off-by: Alasdair G Kergon <[email protected]>
1 parent 71fd5ae commit c4a69ec

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

Documentation/device-mapper/thin-provisioning.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,12 @@ less sharing than average you'll need a larger-than-average metadata device.
7575

7676
As a guide, we suggest you calculate the number of bytes to use in the
7777
metadata device as 48 * $data_dev_size / $data_block_size but round it up
78-
to 2MB if the answer is smaller. The largest size supported is 16GB.
78+
to 2MB if the answer is smaller. If you're creating large numbers of
79+
snapshots which are recording large amounts of change, you may find you
80+
need to increase this.
7981

80-
If you're creating large numbers of snapshots which are recording large
81-
amounts of change, you may need find you need to increase this.
82+
The largest size supported is 16GB: If the device is larger,
83+
a warning will be issued and the excess space will not be used.
8284

8385
Reloading a pool table
8486
----------------------

drivers/md/dm-thin-metadata.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,9 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
713713
if (r)
714714
goto bad;
715715

716+
if (bdev_size > THIN_METADATA_MAX_SECTORS)
717+
bdev_size = THIN_METADATA_MAX_SECTORS;
718+
716719
disk_super = dm_block_data(sblock);
717720
disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC);
718721
disk_super->version = cpu_to_le32(THIN_VERSION);

drivers/md/dm-thin-metadata.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@
1111

1212
#define THIN_METADATA_BLOCK_SIZE 4096
1313

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+
1427
/*----------------------------------------------------------------*/
1528

1629
struct dm_pool_metadata;

drivers/md/dm-thin.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@
3232
#define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (64 * 1024 >> SECTOR_SHIFT)
3333
#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
3434

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-
4535
/*
4636
* Device id is restricted to 24 bits.
4737
*/
@@ -1736,6 +1726,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
17361726
dm_block_t low_water_blocks;
17371727
struct dm_dev *metadata_dev;
17381728
sector_t metadata_dev_size;
1729+
char b[BDEVNAME_SIZE];
17391730

17401731
/*
17411732
* FIXME Remove validation from scope of lock.
@@ -1757,11 +1748,9 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
17571748
}
17581749

17591750
metadata_dev_size = i_size_read(metadata_dev->bdev->bd_inode) >> SECTOR_SHIFT;
1760-
if (metadata_dev_size > METADATA_DEV_MAX_SECTORS) {
1761-
ti->error = "Metadata device is too large";
1762-
r = -EINVAL;
1763-
goto out_metadata;
1764-
}
1751+
if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING)
1752+
DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.",
1753+
bdevname(metadata_dev->bdev, b), THIN_METADATA_MAX_SECTORS);
17651754

17661755
r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev);
17671756
if (r) {

0 commit comments

Comments
 (0)