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

[lvm-devel] [PATCH LVM2] (8/12) 'anywhere' policy implementation



This patch implements 'anywhere' policy.

o relax_allocation_requests() is added to split the allocation requests
  into smallest possible pieces so that they can fit into any number of PVs.

o _setup_alloced_segment() needed to be changed because it assumed
  the list items in ah->alloced_areas[0] can be used as array.
  It's no longer true.

o dm_pool_free() in relax_allocation_requests() seems to free whole
  alloc_handle and not usable. I might be using it in wrong way.


$ diffstat -p1 08.anywhere.patch
 lib/metadata/lv_manip.c |  108 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 89 insertions(+), 19 deletions(-)


Thanks,
-- 
Jun'ichi Nomura, NEC Corporation of America



diff -X dontdiff -urp LVM2.07.update_parallel/lib/metadata/lv_manip.c LVM2.08.anywhere/lib/metadata/lv_manip.c
--- LVM2.07.update_parallel/lib/metadata/lv_manip.c	2006-10-13 22:28:22.000000000 -0400
+++ LVM2.08.anywhere/lib/metadata/lv_manip.c	2006-10-13 22:28:26.000000000 -0400
@@ -617,6 +617,41 @@ void alloc_destroy(struct alloc_handle *
 		dm_pool_destroy(ah->mem);
 }
 
+/*
+ * split multi-area request into single-area request
+ */
+static int relax_allocation_requests(struct alloc_handle *ah)
+{
+	int nr_requests = ah->area_count;
+	struct allocation_request *req;
+	int i, j, k;
+
+	if (nr_requests == ah->nr_requests)
+		/* No more relaxation possible */
+		return 0;
+
+	if (!(req = dm_pool_zalloc(ah->cmd->mem, sizeof(struct allocation_request) * nr_requests))) {
+		log_error("allocation handle allocation failed");
+		return 0;
+	}
+
+	k = 0;
+	for (i = 0; i < ah->nr_requests; i++) {
+		for (j = 0; j < ah->requests[i].area_count; j++, k++) {
+			req[k] = ah->requests[i];
+			req[k].area_count = 1;
+			req[k].index = ah->requests[i].index + j;
+		}
+	}
+
+	// FIXME: freeing cause corruption, why?
+	//dm_pool_free(ah->cmd->mem, ah->requests);
+	ah->nr_requests = nr_requests;
+	ah->requests = req;
+
+	return 1;
+}
+
 static int _log_parallel_areas(struct dm_pool *mem, struct list *parallel_areas)
 {
 	struct seg_pvs *spvs;
@@ -660,7 +695,12 @@ static int _log_parallel_areas(struct dm
 	return 1;
 }
 
-static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
+/*
+ * set up lv_segment for alloced_area (first area of the parallel allocation)
+ */
+static struct lv_segment* _setup_alloced_segment_first(
+				  struct logical_volume *lv,
+				  uint32_t status,
 				  uint32_t area_count,
 				  uint32_t stripe_size,
 				  const struct segment_type *segtype,
@@ -670,7 +710,7 @@ static int _setup_alloced_segment(struct
 				  uint32_t region_size,
 				  struct logical_volume *log_lv __attribute((unused)))
 {
-	uint32_t s, extents, area_multiple, extra_areas = 0;
+	uint32_t extents, area_multiple, extra_areas = 0;
 	struct lv_segment *seg;
 
 	if (mirrored_pv)
@@ -681,39 +721,36 @@ static int _setup_alloced_segment(struct
 	/* log_lv gets set up elsehere */
 	if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
 				     lv->le_count,
-				     aa[0].len * area_multiple,
+				     aa->len * area_multiple,
 				     status, stripe_size, NULL,
 				     area_count + extra_areas,
-				     aa[0].len, 0u, region_size, 0u))) {
+				     aa->len, 0u, region_size, 0u))) {
 		log_error("Couldn't allocate new LV segment.");
-		return 0;
+		return NULL;
 	}
 
 	if (extra_areas) {
 		if (!set_lv_segment_area_pv(seg, 0, mirrored_pv, mirrored_pe)) {
 			stack;
-			return 0;
+			return NULL;
 		}
 	}
 
-	for (s = 0; s < area_count; s++) {
-		if (!set_lv_segment_area_pv(seg, s + extra_areas, aa[s].pv,
-					    aa[s].pe)) {
-			stack;
-			return 0;
-		}
+	if (!set_lv_segment_area_pv(seg, extra_areas, aa->pv, aa->pe)) {
+		stack;
+		return 0;
 	}
 
 	list_add(&lv->segments, &seg->list);
 
-	extents = aa[0].len * area_multiple;
+	extents = aa->len * area_multiple;
 	lv->le_count += extents;
 	lv->size += (uint64_t) extents *lv->vg->extent_size;
 
 	if (segtype_is_mirrored(segtype))
 		lv->status |= MIRRORED;
 
-	return 1;
+	return seg;
 }
 
 static int _setup_alloced_segments(struct logical_volume *lv,
@@ -727,16 +764,38 @@ static int _setup_alloced_segments(struc
 				   uint32_t region_size,
 				   struct logical_volume *log_lv)
 {
-	struct alloced_area *aa;
+	struct alloced_area *aa, *aa2;
+	uint32_t s, extra_areas = 0;
+	struct lv_segment *seg;
 
 	list_iterate_items(aa, &alloced_areas[0]) {
-		if (!_setup_alloced_segment(lv, status, area_count,
-					    stripe_size, segtype, aa,
-					    mirrored_pv, mirrored_pe,
-					    region_size, log_lv)) {
+		if (mirrored_pv)
+			extra_areas = 1;
+
+		if (!(seg = _setup_alloced_segment_first(lv, status,
+						  area_count,
+						  stripe_size, segtype, aa,
+						  mirrored_pv, mirrored_pe,
+						  region_size, log_lv))) {
 			stack;
 			return 0;
 		}
+
+		/*
+		 * set up for 2nd or later areas
+		 * ('aa' may not be an array)
+		 */
+		for (s = 1; s < area_count; s++) {
+			aa2 = list_item(list_first(&alloced_areas[s]),
+					struct alloced_area);
+			if (!set_lv_segment_area_pv(seg, s + extra_areas,
+						    aa2->pv, aa2->pe)) {
+				stack;
+				return 0;
+			}
+			/* the entry is no longer used */
+			list_del(&aa2->list);
+		}
 	}
 
 	return 1;
@@ -1521,6 +1580,7 @@ static int _allocate(struct alloc_handle
 		return 0;
 	}
 
+      retry:
 	old_allocated = ah->allocated;
 	if (!_handle_allocation_requests(ah, ALLOC_CONTIGUOUS, pvms, areas,
 				  areas_size, can_split, prev_lvseg)) {
@@ -1560,6 +1620,16 @@ static int _allocate(struct alloc_handle
 		goto out;
 	}
 
+	if (ah->allocated == ah->requested)
+		goto finished;
+
+	/*
+	 * attempt failed with any policies even ALLOC_ANYWHERE.
+	 * If the allocation requests can be relaxed, try again.
+	 */
+	if (relax_allocation_requests(ah))
+		goto retry;
+
       finished:
 	if (ah->allocated != ah->requested) {
 		log_error("Insufficient suitable %sallocatable extents "

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