File improve-mirror-legs-on-different-tag-pvs.patch of Package lvm2.openSUSE_Leap_42.1_Update

From 69092b1179f4fbd0fae7e054665ad049dffd9966 Mon Sep 17 00:00:00 2001
From: Guangliang Zhao <gzhao@suse.com>
Date: Wed, 5 Dec 2012 18:25:04 +0800
Subject: [PATCH 2/2] mirror: improve mirror legs on different tag pvs
References: FATE#312248

This patch will find the biggest eligible area every time,
and add it to the parallel areas.

The previous just find the different tag pv area with all
found ones, if the new area's tag has appeared, just throw
it. The new will compare the length, and choose the longer
one.

Signed-off-by: Guangliang Zhao <gzhao@suse.com>
---
 lib/metadata/lv_manip.c |   34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -2455,6 +2455,25 @@ static uint32_t _calc_required_extents(s
 	return required;
 }
 
+static void _replace_required_area(struct alloc_handle *ah,
+				   uint32_t max_to_allocate,
+				   unsigned ix_pva, struct pv_area *pva,
+				   struct alloc_state *alloc_state,
+				   alloc_policy_t alloc)
+{
+	uint32_t required = _calc_required_extents(ah, pva, ix_pva,
+						   max_to_allocate, alloc);
+
+	/*
+	 * We don't worry about the area replaced, because _clear_areas() and
+	 * _reset_unreserved() called by _find_some_parallel_space() will clear
+	 * the alloc_state and reserved areas every time.
+	 */
+	if (required > alloc_state->areas[ix_pva - 1].used)
+		_reserve_area(ah, alloc_state, pva, required, ix_pva - 1,
+			      pva->unreserved);
+}
+
 static void _clear_areas(struct alloc_state *alloc_state)
 {
 	uint32_t s;
@@ -2580,6 +2599,7 @@ static int _find_some_parallel_space(str
 	const struct alloc_parms *alloc_parms = alloc_state->alloc_parms;
 	unsigned ix = 0;
 	unsigned last_ix;
+	int ret;
 	struct pv_map *pvm;
 	struct pv_area *pva;
 	unsigned preferred_count = 0;
@@ -2700,9 +2720,17 @@ static int _find_some_parallel_space(str
 					continue;
 
 				case USE_AREA:
-					if(check_areas_separate_tags(ah, alloc_state, ix_offset,
-								     ix + ix_offset, pva) >= 0)
-						goto next_pv;
+					ret = check_areas_separate_tags(ah,
+							alloc_state, ix_offset,
+							ix + ix_offset, pva);
+					if (ret >= 0) {
+						_replace_required_area(ah,
+							max_to_allocate,
+							ret + 1, pva,
+							alloc_state,
+							alloc_parms->alloc);
+						continue;
+					}
 
 					/*
 					 * Except with ALLOC_ANYWHERE, replace first area with this