[lvm-devel] master - lvconvert: add infrastructure for RaidLV reshaping support
Heinz Mauelshagen
mauelsha at fedoraproject.org
Fri Feb 24 06:32:09 UTC 2017
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7d39b4d5e7c38438b294469f74d437bdbb9a2632
Commit: 7d39b4d5e7c38438b294469f74d437bdbb9a2632
Parent: 92691e345d12515d61e6e7748e5b9ddc4eff49c0
Author: Heinz Mauelshagen <heinzm at redhat.com>
AuthorDate: Fri Feb 24 02:05:36 2017 +0100
Committer: Heinz Mauelshagen <heinzm at redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces more local infrastructure to raid_manip.c
used by followup patches.
Changes:
- add function providing state of a reshaped RaidLV
- add function to adjust the size of a RaidLV was
reshaped to add/remove stripes
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/metadata/raid_manip.c | 96 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index b2a5572..b82ec90 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1447,6 +1447,102 @@ static int _lv_free_reshape_space(struct logical_volume *lv)
return _lv_free_reshape_space_with_status(lv, NULL);
}
+/*
+ * HM
+ *
+ * Compares current raid disk count of active RAID set @lv to
+ * requested @dev_count returning number of disks as of healths
+ * string in @devs_health and synced disks in @devs_in_sync
+ *
+ * Returns:
+ *
+ * 0: error
+ * 1: kernel dev count = @dev_count
+ * 2: kernel dev count < @dev_count
+ * 3: kernel dev count > @dev_count
+ *
+ */
+__attribute__ ((__unused__))
+static int _reshaped_state(struct logical_volume *lv, const unsigned dev_count,
+ unsigned *devs_health, unsigned *devs_in_sync)
+{
+ uint32_t kernel_devs;
+
+ if (!devs_health || !devs_in_sync)
+ return_0;
+
+ if (!_get_dev_health(lv, &kernel_devs, devs_health, devs_in_sync, NULL))
+ return 0;
+
+ if (kernel_devs == dev_count)
+ return 1;
+
+ return kernel_devs < dev_count ? 2 : 3;
+}
+
+/*
+ * Return new length for @lv based on @old_image_count and @new_image_count in @*len
+ *
+ * Subtracts any reshape space and provide data length only!
+ */
+static int _lv_reshape_get_new_len(struct logical_volume *lv,
+ uint32_t old_image_count, uint32_t new_image_count,
+ uint32_t *len)
+{
+ struct lv_segment *seg = first_seg(lv);
+ uint32_t di_old = _data_rimages_count(seg, old_image_count);
+ uint32_t di_new = _data_rimages_count(seg, new_image_count);
+ uint32_t old_lv_reshape_len, new_lv_reshape_len;
+ uint64_t r;
+
+ if (!di_old || !di_new)
+ return_0;
+
+ old_lv_reshape_len = di_old * _reshape_len_per_dev(seg);
+ new_lv_reshape_len = di_new * _reshape_len_per_dev(seg);
+
+ r = (uint64_t) lv->le_count;
+ r -= old_lv_reshape_len;
+ if ((r = new_lv_reshape_len + r * di_new / di_old) > UINT_MAX) {
+ log_error("No proper new segment length for %s!", display_lvname(lv));
+ return 0;
+ }
+
+ *len = (uint32_t) r;
+
+ return 1;
+}
+
+/*
+ * Extend/reduce size of @lv and it's first segment during reshape to @extents
+ */
+__attribute__ ((__unused__))
+static int _reshape_adjust_to_size(struct logical_volume *lv,
+ uint32_t old_image_count, uint32_t new_image_count)
+{
+ struct lv_segment *seg = first_seg(lv);
+ uint32_t new_le_count;
+
+ if (!_lv_reshape_get_new_len(lv, old_image_count, new_image_count, &new_le_count))
+ return 0;
+
+ /* Externally visible LV size w/o reshape space */
+ lv->le_count = seg->len = new_le_count;
+ lv->size = (lv->le_count - new_image_count * _reshape_len_per_dev(seg)) * lv->vg->extent_size;
+ /* seg->area_len does not change */
+
+ if (old_image_count < new_image_count) {
+ /* Extend from raid1 mapping */
+ if (old_image_count == 2 &&
+ !seg->stripe_size)
+ seg->stripe_size = DEFAULT_STRIPESIZE;
+
+ /* Reduce to raid1 mapping */
+ } else if (new_image_count == 2)
+ seg->stripe_size = 0;
+
+ return 1;
+}
/*
* _alloc_rmeta_for_lv
More information about the lvm-devel
mailing list