mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
![Mike Snitzer](/assets/img/avatar_default.png)
It was always intended that a user could provide a thin metadata device that is larger than the max supported by the on-disk format. The extra space would just go unused. Unfortunately that never worked. If the user attempted to use a larger metadata device on creation they would get an error like the following: device-mapper: space map common: space map too large device-mapper: transaction manager: couldn't create metadata space map device-mapper: thin metadata: tm_create_with_sm failed device-mapper: table: 252:17: thin-pool: Error creating metadata object device-mapper: ioctl: error adding target to table Fix this by allowing the initial metadata space map creation to cap its size at the max number of blocks supported (DM_SM_METADATA_MAX_BLOCKS). get_metadata_dev_size() must also impose DM_SM_METADATA_MAX_BLOCKS (via THIN_METADATA_MAX_SECTORS), otherwise extending metadata would cap at THIN_METADATA_MAX_SECTORS_WARNING (which is larger than supported). Also, the calculation for THIN_METADATA_MAX_SECTORS didn't account for the sizeof the disk_bitmap_header. So the supported maximum metadata size is a bit smaller (reduced from 33423360 to 33292800 sectors). Lastly, remove the "excess space will not be used" warning message from get_metadata_dev_size(); it resulted in printing the warning multiple times. Factor out warn_if_metadata_device_too_big(), call it from pool_ctr() and maybe_resize_metadata_dev(). Signed-off-by: Mike Snitzer <snitzer@redhat.com> Acked-by: Joe Thornber <ejt@redhat.com>
44 lines
1.1 KiB
C
44 lines
1.1 KiB
C
/*
|
|
* Copyright (C) 2011 Red Hat, Inc.
|
|
*
|
|
* This file is released under the GPL.
|
|
*/
|
|
|
|
#ifndef DM_SPACE_MAP_METADATA_H
|
|
#define DM_SPACE_MAP_METADATA_H
|
|
|
|
#include "dm-transaction-manager.h"
|
|
|
|
#define DM_SM_METADATA_BLOCK_SIZE (4096 >> SECTOR_SHIFT)
|
|
|
|
/*
|
|
* 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 DM_SM_METADATA_MAX_BLOCKS (255 * ((1 << 14) - 64))
|
|
#define DM_SM_METADATA_MAX_SECTORS (DM_SM_METADATA_MAX_BLOCKS * DM_SM_METADATA_BLOCK_SIZE)
|
|
|
|
/*
|
|
* Unfortunately we have to use two-phase construction due to the cycle
|
|
* between the tm and sm.
|
|
*/
|
|
struct dm_space_map *dm_sm_metadata_init(void);
|
|
|
|
/*
|
|
* Create a fresh space map.
|
|
*/
|
|
int dm_sm_metadata_create(struct dm_space_map *sm,
|
|
struct dm_transaction_manager *tm,
|
|
dm_block_t nr_blocks,
|
|
dm_block_t superblock);
|
|
|
|
/*
|
|
* Open from a previously-recorded root.
|
|
*/
|
|
int dm_sm_metadata_open(struct dm_space_map *sm,
|
|
struct dm_transaction_manager *tm,
|
|
void *root_le, size_t len);
|
|
|
|
#endif /* DM_SPACE_MAP_METADATA_H */
|