diff options
Diffstat (limited to 'lib/raid/raid.c')
-rw-r--r-- | lib/raid/raid.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/raid/raid.c b/lib/raid/raid.c index e88a15408..48b63a31a 100644 --- a/lib/raid/raid.c +++ b/lib/raid/raid.c @@ -240,6 +240,26 @@ static int _raid_text_export(const struct lv_segment *seg, struct formatter *f) return _raid_text_export_raid(seg, f); } +static int _image_integrity_data_sectors(struct lv_segment *seg, uint64_t *data_sectors) +{ + struct logical_volume *lv_image; + struct lv_segment *seg_image; + int s; + + *data_sectors = 0; + + for (s = 0; s < seg->area_count; s++) { + lv_image = seg_lv(seg, s); + + if (lv_is_integrity(lv_image)) { + seg_image = first_seg(lv_image); + *data_sectors = seg_image->integrity_data_sectors; + return 1; + } + } + return 1; +} + static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)), struct dm_pool *mem __attribute__((unused)), struct cmd_context *cmd __attribute__((unused)), @@ -256,6 +276,7 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)), uint64_t writemostly[RAID_BITMAP_SIZE] = { 0 }; struct dm_tree_node_raid_params_v2 params = { 0 }; unsigned attrs; + uint64_t integrity_data_sectors = 0; if (seg_is_raid4(seg)) { if (!_raid_target_present(cmd, NULL, &attrs) || @@ -351,6 +372,21 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)), params.stripe_size = seg->stripe_size; params.flags = flags; + /* + * The len needs to be reduced only when the raid images are using + * integrity with internal metadata, which reduces the usable + * size of the image, and needs to be reflected in the dm table + * that's loaded. (internal metadata is not currently allowed + * with raid, so this is unused.) + */ + if (!_image_integrity_data_sectors(seg, &integrity_data_sectors)) + return_0; + if (integrity_data_sectors) { + log_debug("Reducing raid size from %llu to integrity_data_sectors %llu", + (unsigned long long)len, (unsigned long long)integrity_data_sectors); + len = integrity_data_sectors; + } + if (!dm_tree_node_add_raid_target_with_params_v2(node, len, ¶ms)) return_0; |