summaryrefslogtreecommitdiff
path: root/device_mapper/libdm-deptree.c
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2021-01-12 17:59:29 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2021-02-01 12:06:13 +0100
commitb4212be2e7e8797bbf8f9a166347659cc39ba075 (patch)
treeb5db3667aa0bcb03d48d793870873d633ea48145 /device_mapper/libdm-deptree.c
parentb218a7cfe7179ced64047374af51a883c1611c4d (diff)
downloadlvm2-b4212be2e7e8797bbf8f9a166347659cc39ba075.tar.gz
thin: improve 16g support for thin pool metadata
Initial support for thin-pool used slightly smaller max size 15.81GiB for thin-pool metadata. However the real limit later settled at 15.88GiB (difference is ~64MiB - 16448 4K blocks). lvm2 could not simply increase the size as it has been using hard cropping of the loaded metadata device to avoid warnings printing warning of kernel when the size was bigger (i.e. due to bigger extent_size). This patch adds the new lvm.conf configurable setting: allocation/thin_pool_crop_metadata which defaults to 0 -> no crop of metadata beyond 15.81GiB. Only user with these sizes of metadata will be affected. Without cropping lvm2 now limits metadata allocation size to 15.88GiB. Any space beyond is currently not used by thin-pool target. Even if i.e. bigger LV is used for metadata via lvconvert, or allocated bigger because of to large extent size. With cropping enabled (=1) lvm2 preserves the old limitation 15.81GiB and should allow to work in the evironement with older lvm2 tools (i.e. older distribution). Thin-pool metadata with size bigger then 15.81G is now using CROP_METADATA flag within lvm2 metadata, so older lvm2 recognizes an incompatible thin-pool and cannot activate such pool! Users should use uncropped version as it is not suffering from various issues between thin_repair results and allocated metadata LV as thin_repair limit is 15.88GiB Users should use cropping only when really needed! Patch also better handles resize of thin-pool metadata and prevents resize beoyond usable size 15.88GiB. Resize beyond 15.81GiB automatically switches pool to no-crop version. Even with existing bigger thin-pool metadata command 'lvextend -l+1 vg/pool_tmeta' does the change. Patch gives better controls 'coverted' metadata LV and reports less confusing message during conversion. Patch set also moves the code for updating min/max into pool_manip.c for better sharing with cache_pool code.
Diffstat (limited to 'device_mapper/libdm-deptree.c')
-rw-r--r--device_mapper/libdm-deptree.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
index 6ce956fa2..5b60dc91a 100644
--- a/device_mapper/libdm-deptree.c
+++ b/device_mapper/libdm-deptree.c
@@ -3979,6 +3979,24 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
uint64_t low_water_mark,
unsigned skip_block_zeroing)
{
+ return dm_tree_node_add_thin_pool_target_v1(node, size, transaction_id,
+ metadata_uuid, pool_uuid,
+ data_block_size,
+ low_water_mark,
+ skip_block_zeroing,
+ 1);
+}
+
+int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
+ uint64_t size,
+ uint64_t transaction_id,
+ const char *metadata_uuid,
+ const char *pool_uuid,
+ uint32_t data_block_size,
+ uint64_t low_water_mark,
+ unsigned skip_block_zeroing,
+ unsigned crop_metadata)
+{
struct load_segment *seg, *mseg;
uint64_t devsize = 0;
@@ -4005,17 +4023,18 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
if (!_link_tree_nodes(node, seg->metadata))
return_0;
- /* FIXME: more complex target may need more tweaks */
- dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
- devsize += mseg->size;
- if (devsize > DM_THIN_MAX_METADATA_SIZE) {
- log_debug_activation("Ignoring %" PRIu64 " of device.",
- devsize - DM_THIN_MAX_METADATA_SIZE);
- mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
- devsize = DM_THIN_MAX_METADATA_SIZE;
- /* FIXME: drop remaining segs */
+ if (crop_metadata)
+ /* FIXME: more complex target may need more tweaks */
+ dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
+ devsize += mseg->size;
+ if (devsize > DM_THIN_MAX_METADATA_SIZE) {
+ log_debug_activation("Ignoring %" PRIu64 " of device.",
+ devsize - DM_THIN_MAX_METADATA_SIZE);
+ mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
+ devsize = DM_THIN_MAX_METADATA_SIZE;
+ /* FIXME: drop remaining segs */
+ }
}
- }
if (!(seg->pool = dm_tree_find_node_by_uuid(node->dtree, pool_uuid))) {
log_error("Missing pool uuid %s.", pool_uuid);