[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [LVM2 PATCH] (5/5) Remove pvmove special casing from lv_extend/allocate_extents



This patch removes pvmove special parameters from lv_extend() and
allocate_extents().

These special parameters are passed to them so that lv_extend()
can use them as the 1st area (i.e. master mirror).
However, without this parameter, pvmove can do allocate_extents()
and then call lv_add_segment() by itself.

We could further eliminate the special parameters from lv_add_segment()
by splitting the parts to something like lv_add_pvmove_segment(),
if it's preferred.

Thanks,
-- 
Jun'ichi Nomura, NEC Corporation of America
Remove pvmove special casing from lv_extend()/allocate_extents().

pvmove specific 'mirrored_pv'/'mirrored_pe' parameters have been passed
around from lv_extend() to the core allocation functions.
The parameters point to the source PV segment of the pvmove and:
  1. telling the allocation cannot be splitted
  2. checking mixture of pvmove allocation and striped/mirrored allocation
  3. passed to lv_add_segment(), where the PV segment is attached to the
    1st area (i.e. source of mirror resync) of the mirror segment.

For 1. and 2., they can be done in pvmove function, if it calls
allocate_extents(), instead of lv_extend().
For 3., pvmove function can call lv_add_segment() directly after
allocate_extents().

What the patch does:
  - Added add_area_to_pvmove(), which allocates pvmove destination PEs,
    add a mirror segment, update affected LVs references.
  - Removed mirrored_pv/mirrored_pe from struct alloc_handle
  - Removed them from most of the allocation functions.
    (They remain in lv_add_segment() and its subcomponent.)
  - Removed the "Can't mix" checks for mirrored_pv in _alloc_init.
    (These checks are already done in _set_up_pvmove_lv().)
  - Changed insert_pvmove_mirrors() to use newly added add_area_to_pvmove()
    instead of lv_extend().

Index: LVM2.work/lib/metadata/lv_manip.c
===================================================================
--- LVM2.work.orig/lib/metadata/lv_manip.c
+++ LVM2.work/lib/metadata/lv_manip.c
@@ -422,8 +422,6 @@ struct alloc_handle {
 	uint32_t log_count;		/* Number of parallel 1-extent logs */
 	uint32_t total_area_len;	/* Total number of parallel extents */
 
-	struct physical_volume *mirrored_pv;	/* FIXME Remove this */
-	uint32_t mirrored_pe;			/* FIXME Remove this */
 	struct list *parallel_areas;	/* PVs to avoid */
 
 	struct alloced_area log_area;	/* Extent used for log */
@@ -449,36 +447,20 @@ static struct alloc_handle *_alloc_init(
 					uint32_t mirrors,
 					uint32_t stripes,
 					uint32_t log_count,
-					struct physical_volume *mirrored_pv,
-					uint32_t mirrored_pe,
 					struct list *parallel_areas)
 {
 	struct alloc_handle *ah;
 	uint32_t s, area_count;
 
-	if (stripes > 1 && mirrors > 1) {
+	if (stripes > 1 && (mirrors > 1 || log_count)) {
 		log_error("Striped mirrors are not supported yet");
 		return NULL;
 	}
 
-	if ((stripes > 1 || mirrors > 1) && mirrored_pv) {
-		log_error("Can't mix striping or mirroring with "
-			  "creation of a mirrored PV yet");
-		return NULL;
-	}
-
-	if (log_count && (stripes > 1 || mirrored_pv)) {
-		log_error("Can't mix striping or pvmove with "
-			  "a mirror log yet.");
-		return NULL;
-	}
-
 	if (segtype_is_virtual(segtype))
 		area_count = 0;
 	else if (mirrors > 1)
 		area_count = mirrors;
-	else if (mirrored_pv)
-		area_count = 1;
 	else
 		area_count = stripes;
 
@@ -505,8 +487,6 @@ static struct alloc_handle *_alloc_init(
 	for (s = 0; s < ah->area_count; s++)
 		list_init(&ah->alloced_areas[s]);
 
-	ah->mirrored_pv = mirrored_pv;
-	ah->mirrored_pe = mirrored_pe;
 	ah->parallel_areas = parallel_areas;
 
 	return ah;
@@ -1095,7 +1075,7 @@ static int _allocate(struct alloc_handle
 		return 1;
 	}
 
-	if (ah->mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
+	if (ah->alloc == ALLOC_CONTIGUOUS)
 		can_split = 0;
 
 	if (lv && !list_empty(&lv->segments))
@@ -1201,8 +1181,6 @@ struct alloc_handle *allocate_extents(st
 				      uint32_t stripes,
 				      uint32_t mirrors, uint32_t log_count,
 				      uint32_t extents,
-				      struct physical_volume *mirrored_pv,
-				      uint32_t mirrored_pe,
 				      struct list *allocatable_pvs,
 				      alloc_policy_t alloc,
 				      struct list *parallel_areas)
@@ -1228,8 +1206,7 @@ struct alloc_handle *allocate_extents(st
 		alloc = vg->alloc;
 
 	if (!(ah = _alloc_init(vg->cmd, vg->cmd->mem, segtype, alloc, mirrors,
-			       stripes, log_count, mirrored_pv,
-			       mirrored_pe, parallel_areas))) {
+			       stripes, log_count, parallel_areas))) {
 		stack;
 		return NULL;
 	}
@@ -1423,7 +1400,6 @@ int lv_extend(struct logical_volume *lv,
 	      const struct segment_type *segtype,
 	      uint32_t stripes, uint32_t stripe_size,
 	      uint32_t mirrors, uint32_t extents,
-	      struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
 	      uint32_t status, struct list *allocatable_pvs,
 	      alloc_policy_t alloc)
 {
@@ -1436,15 +1412,14 @@ int lv_extend(struct logical_volume *lv,
 		return lv_add_virtual_segment(lv, status, extents, segtype);
 
 	if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
-				    extents, mirrored_pv, mirrored_pe,
-				    allocatable_pvs, alloc, NULL))) {
+				    extents, allocatable_pvs, alloc, NULL))) {
 		stack;
 		return 0;
 	}
 
 	if (mirrors < 2) {
 		if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
-			    mirrored_pv, mirrored_pe, status, 0, NULL)) {
+			    NULL, 0, status, 0, NULL)) {
 			stack;
 			goto out;
 		}
Index: LVM2.work/lib/metadata/mirror.c
===================================================================
--- LVM2.work.orig/lib/metadata/mirror.c
+++ LVM2.work/lib/metadata/mirror.c
@@ -530,6 +530,66 @@ int add_mirror_layers(struct alloc_handl
 	return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors, 0);
 }
 
+/*
+ * Add given segment area (source area) to the pvmove LV.
+ *   1. disconnect the source area from its current LV segment
+ *   2. allocate destination PEs
+ *   3. add the disconnected source area and allocated PEs to pvmove_lv
+ *   4. direct the original LV segment area to the pvmove segment
+ */
+static int add_area_to_pvmove(struct logical_volume *pvmove_lv,
+			      struct lv_segment *seg, uint32_t area,
+			      struct list *allocatable_pvs,
+			      alloc_policy_t alloc)
+{
+	const struct segment_type *segtype;
+	uint32_t start_le = pvmove_lv->le_count;
+	struct physical_volume *src_pv = seg_pv(seg, area);
+	uint32_t src_pe = seg_pe(seg, area);
+	struct alloc_handle *ah;
+
+	if (!(segtype = get_segtype_from_string(seg->lv->vg->cmd, "mirror"))) {
+		stack;
+		return 0;
+	}
+
+        if (activation() && segtype->ops->target_present &&
+            !segtype->ops->target_present(NULL)) {
+                log_error("%s: Required device-mapper target(s) not "
+                          "detected in your kernel", segtype->name);
+                return 0;
+        }
+
+	log_very_verbose("Moving %s:%u-%u of %s/%s", dev_name(src_pv->dev),
+			 src_pe, src_pe + seg->area_len - 1,
+			 seg->lv->vg->name, seg->lv->name);
+
+	/* remove source area from its lvsegment */
+	release_lv_segment_area(seg, area, seg->area_len);
+
+	/* FIXME: pvmove cannot split the original segment */
+	alloc = ALLOC_CONTIGUOUS;
+
+	/* allocate destination extents */
+	ah = allocate_extents(pvmove_lv->vg, NULL, segtype,
+			      1, 0, 0, seg->area_len,
+			      allocatable_pvs, alloc, NULL);
+	if (!ah) {
+		log_error("Unable to allocate temporary LV for pvmove.");
+		return 0;
+	}
+
+	/* add a new segment with the source and destination extents */
+	if (!lv_add_segment(ah, 0, 1, pvmove_lv, segtype,
+			    seg->area_len, src_pv, src_pe,
+			    PVMOVE, 0, NULL))
+		return_0;
+
+	set_lv_segment_area_lv(seg, area, pvmove_lv, start_le, 0);
+
+	return 1;
+}
+	
 /* 
  * Replace any LV segments on given PV with temporary mirror.
  * Returns list of LVs changed.
@@ -545,29 +605,14 @@ int insert_pvmove_mirrors(struct cmd_con
 	struct lv_segment *seg;
 	struct lv_list *lvl;
 	struct pv_list *pvl;
-	struct physical_volume *pv;
-	uint32_t pe;
 	int lv_used = 0;
-	uint32_t s, start_le, extent_count = 0u;
-	const struct segment_type *segtype;
+	uint32_t s, extent_count = 0u;
 	struct pe_range *per;
 	uint32_t pe_start, pe_end, per_end, stripe_multiplier;
 
 	/* Only 1 PV may feature in source_pvl */
 	pvl = list_item(source_pvl->n, struct pv_list);
 
-	if (!(segtype = get_segtype_from_string(lv->vg->cmd, "mirror"))) {
-		stack;
-		return 0;
-	}
-
-        if (activation() && segtype->ops->target_present &&
-            !segtype->ops->target_present(NULL)) {
-                log_error("%s: Required device-mapper target(s) not "
-                          "detected in your kernel", segtype->name);
-                return 0;
-        }
-
 	/* Split LV segments to match PE ranges */
 	list_iterate_items(seg, &lv->segments) {
 		for (s = 0; s < seg->area_count; s++) {
@@ -646,27 +691,11 @@ int insert_pvmove_mirrors(struct cmd_con
 					lv_used = 1;
 				}
 	
-				pv = seg_pv(seg, s);
-				pe = seg_pe(seg, s);
-				log_very_verbose("Moving %s:%u-%u of %s/%s",
-						 dev_name(pvl->pv->dev),
-						 pe, pe + seg->area_len - 1,
-						 lv->vg->name, lv->name);
-
-				start_le = lv_mirr->le_count;
 				/* FIXME Clean this up */
-				release_lv_segment_area(seg, s, seg->area_len);
-				if (!lv_extend(lv_mirr, segtype, 1,
-				       	seg->area_len, 0u, seg->area_len,
-				       	pv, pe,
-				       	PVMOVE, allocatable_pvs,
-				       	alloc)) {
-					log_error("Unable to allocate "
-						  "temporary LV for pvmove.");
+				if (!add_area_to_pvmove(lv_mirr, seg, s,
+							allocatable_pvs, alloc))
 					return 0;
-				}
-				set_lv_segment_area_lv(seg, s, lv_mirr, start_le, 0);
-	
+
 				extent_count += seg->area_len;
 	
 				lv->status |= LOCKED;
Index: LVM2.work/lib/metadata/lv_alloc.h
===================================================================
--- LVM2.work.orig/lib/metadata/lv_alloc.h
+++ LVM2.work/lib/metadata/lv_alloc.h
@@ -48,8 +48,6 @@ struct alloc_handle *allocate_extents(st
                                       uint32_t stripes,
                                       uint32_t mirrors, uint32_t log_count,
 				      uint32_t extents,
-                                      struct physical_volume *mirrored_pv,
-                                      uint32_t mirrored_pe,
                                       struct list *allocatable_pvs,
 				      alloc_policy_t alloc,
 				      struct list *parallel_areas);
Index: LVM2.work/lib/metadata/metadata-exported.h
===================================================================
--- LVM2.work.orig/lib/metadata/metadata-exported.h
+++ LVM2.work/lib/metadata/metadata-exported.h
@@ -361,7 +361,6 @@ int lv_extend(struct logical_volume *lv,
 	      const struct segment_type *segtype,
 	      uint32_t stripes, uint32_t stripe_size,
 	      uint32_t mirrors, uint32_t extents,
-	      struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
 	      uint32_t status, struct list *allocatable_pvs,
 	      alloc_policy_t alloc);
 
Index: LVM2.work/tools/lvconvert.c
===================================================================
--- LVM2.work.orig/tools/lvconvert.c
+++ LVM2.work/tools/lvconvert.c
@@ -339,7 +339,7 @@ static int lvconvert_mirrors(struct cmd_
 					    1, lp->mirrors - 1,
 					    corelog ? 0 : 1,
 					    lv->le_count,
-					    NULL, 0, lp->pvh,
+					    lp->pvh,
 					    lp->alloc,
 					    parallel_areas)))
 			return_0;
@@ -387,7 +387,7 @@ static int lvconvert_mirrors(struct cmd_
 
 			if (!(ah = allocate_extents(lv->vg, NULL, lp->segtype, 0,
 						    0, 1, 0,
-						    NULL, 0, lp->pvh,
+						    lp->pvh,
 						    lp->alloc,
 						    parallel_areas))) {
 				stack;
Index: LVM2.work/tools/lvcreate.c
===================================================================
--- LVM2.work.orig/tools/lvcreate.c
+++ LVM2.work/tools/lvcreate.c
@@ -708,7 +708,7 @@ static int _lvcreate(struct cmd_context 
 
 		if (!(ah = allocate_extents(vg, NULL, lp->segtype, lp->stripes,
 					    lp->mirrors, lp->corelog ? 0 : 1,
-					    lp->extents, NULL, 0,
+					    lp->extents,
 					    pvh, lp->alloc, NULL))) {
 			stack;
 			return 0;
@@ -774,7 +774,7 @@ static int _lvcreate(struct cmd_context 
 		alloc_destroy(ah);
 		ah = NULL;
 	} else if (!lv_extend(lv, lp->segtype, lp->stripes, lp->stripe_size,
-		       lp->mirrors, lp->extents, NULL, 0u, 0u, pvh, lp->alloc)) {
+			      lp->mirrors, lp->extents, 0u, pvh, lp->alloc)) {
 		stack;
 		return 0;
 	}
Index: LVM2.work/tools/lvresize.c
===================================================================
--- LVM2.work.orig/tools/lvresize.c
+++ LVM2.work/tools/lvresize.c
@@ -544,7 +544,7 @@ static int _lvresize(struct cmd_context 
 	} else if (!lv_extend(lv, lp->segtype, lp->stripes,
 			      lp->stripe_size, lp->mirrors,
 			      lp->extents - lv->le_count,
-			      NULL, 0u, 0u, pvh, alloc)) {
+			      0u, pvh, alloc)) {
 		stack;
 		return ECMD_FAILED;
 	}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]