mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									71fd5ae25d
								
							
						
					
					
						commit
						c4a69ecdb4
					
				
					 4 changed files with 25 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -75,10 +75,12 @@ less sharing than average you'll need a larger-than-average metadata device.
 | 
			
		|||
 | 
			
		||||
As a guide, we suggest you calculate the number of bytes to use in the
 | 
			
		||||
metadata device as 48 * $data_dev_size / $data_block_size but round it up
 | 
			
		||||
to 2MB if the answer is smaller.  The largest size supported is 16GB.
 | 
			
		||||
to 2MB if the answer is smaller.  If you're creating large numbers of
 | 
			
		||||
snapshots which are recording large amounts of change, you may find you
 | 
			
		||||
need to increase this.
 | 
			
		||||
 | 
			
		||||
If you're creating large numbers of snapshots which are recording large
 | 
			
		||||
amounts of change, you may need find you need to increase this.
 | 
			
		||||
The largest size supported is 16GB: If the device is larger,
 | 
			
		||||
a warning will be issued and the excess space will not be used.
 | 
			
		||||
 | 
			
		||||
Reloading a pool table
 | 
			
		||||
----------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -713,6 +713,9 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
 | 
			
		|||
	if (r)
 | 
			
		||||
		goto bad;
 | 
			
		||||
 | 
			
		||||
	if (bdev_size > THIN_METADATA_MAX_SECTORS)
 | 
			
		||||
		bdev_size = THIN_METADATA_MAX_SECTORS;
 | 
			
		||||
 | 
			
		||||
	disk_super = dm_block_data(sblock);
 | 
			
		||||
	disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC);
 | 
			
		||||
	disk_super->version = cpu_to_le32(THIN_VERSION);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,19 @@
 | 
			
		|||
 | 
			
		||||
#define THIN_METADATA_BLOCK_SIZE 4096
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The metadata device is currently limited in size.
 | 
			
		||||
 *
 | 
			
		||||
 * We have one block of index, which can hold 255 index entries.  Each
 | 
			
		||||
 * index entry contains allocation info about 16k metadata blocks.
 | 
			
		||||
 */
 | 
			
		||||
#define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT)))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A metadata device larger than 16GB triggers a warning.
 | 
			
		||||
 */
 | 
			
		||||
#define THIN_METADATA_MAX_SECTORS_WARNING (16 * (1024 * 1024 * 1024 >> SECTOR_SHIFT))
 | 
			
		||||
 | 
			
		||||
/*----------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
struct dm_pool_metadata;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue