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

[lvm-devel] [PATCH LVM2] (4/12) separate constraints checker from _find_parallel_space()



This patch moves the parts checking constraints out from
_find_parallel_space().

o is_pv_parallel() checks all parallel_areas if the allocation request
  is ALLOC_AVOID_ALL_PARALLEL. (e.g. for log device)

o Others are just moving location.


$ diffstat -p1 04.separate_constraints.patch
 lib/metadata/lv_manip.c |  147 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 112 insertions(+), 35 deletions(-)


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


diff -X dontdiff -urp LVM2.03.remove_ix_offset/lib/metadata/lv_manip.c LVM2.04.separate_constraints/lib/metadata/lv_manip.c
--- LVM2.03.remove_ix_offset/lib/metadata/lv_manip.c	2006-10-13 21:14:12.000000000 -0400
+++ LVM2.04.separate_constraints/lib/metadata/lv_manip.c	2006-10-13 21:14:37.000000000 -0400
@@ -1034,6 +1034,101 @@ static int _check_contiguous(struct cmd_
 }
 
 /*
+ * returns 1 if given pv is found in the list of pvs.
+ *
+ * The list of PVs can be given in either or both of 2 ways:
+ *    by parallel_areas list in allocation handle
+ * and/or
+ *    by list of struct pv_list
+ */
+static int is_pv_parallel(struct alloc_handle *ah,
+			  struct allocation_request *req,
+			  struct physical_volume* pv,
+			  struct list *list)
+{
+	struct seg_pvs *spvs;
+	struct pv_list *pvl;
+
+	if ((req->flags & ALLOC_AVOID_ALL_PARALLEL) &&
+	    ah && ah->parallel_areas) {
+		list_iterate_items(spvs, ah->parallel_areas)
+			list_iterate_items(pvl, &spvs->pvs)
+				if (pv == pvl->pv)
+					return 1;
+	}
+
+	if (list && !list_empty(list)) {
+		list_iterate_items(pvl, list)
+			if (pv == pvl->pv)
+				return 1;
+	}
+
+	return 0;
+}
+
+static int _check_pv_constraints(struct alloc_handle *ah,
+				alloc_policy_t alloc,
+				struct allocation_request *req,
+				struct physical_volume *pv,
+				struct list *parallel_pvs)
+{
+	if (alloc != ALLOC_ANYWHERE) {
+		/* Avoid PVs used by existing parallel areas */
+		if (is_pv_parallel(ah, req, pv, parallel_pvs))
+			return 0;
+	}
+
+	return 1;
+}
+
+/* return value of _check_area_constraints */
+enum {
+	READY_FOR_ALLOC,	/* the area can be used for allocation */
+	NEXT_AREA,		/* try next area in the pv */
+	NEXT_PV,		/* try other pv */
+	NEXT_AREA_ALLOCED,	/* the area is allocated, try next area */
+	NEXT_PV_ALLOCED,	/* the area is allocated, try next pv */
+};
+static int _check_area_constraints(struct alloc_handle *ah,
+				alloc_policy_t alloc,
+				struct allocation_request *req,
+				uint32_t req_len,
+				struct pv_area *pva,
+				struct lv_segment *prev_lvseg,
+				struct pv_area **areas,
+				uint32_t areas_size,
+				unsigned can_split,
+				uint32_t *preferred_index)
+{
+	if (prev_lvseg && alloc == ALLOC_CONTIGUOUS) {
+		if (_check_contiguous(ah->cmd, prev_lvseg, pva,
+				      req->index, req->index + req->area_count - 1,
+				      areas, areas_size)) {
+			return NEXT_PV_ALLOCED;
+		}
+		return NEXT_AREA;
+	}
+
+	if (prev_lvseg && alloc == ALLOC_CLING) {
+		if (_check_cling(ah->cmd, prev_lvseg, pva,
+				 req->index, req->index + req->area_count - 1,
+				 areas, areas_size)) {
+			return NEXT_PV_ALLOCED;
+		}
+		return NEXT_PV;
+	}
+
+	/* Is it big enough on its own? */
+	if (pva->count >= req_len)
+		return READY_FOR_ALLOC;
+
+	if (!can_split)
+		return NEXT_PV; 
+
+	return READY_FOR_ALLOC;
+}
+
+/*
  * Choose sets of parallel areas to use, respecting any constraints.
  */
 static int _find_parallel_space(struct alloc_handle *ah, 
@@ -1045,12 +1140,12 @@ static int _find_parallel_space(struct a
 {
 	struct pv_map *pvm;
 	struct pv_area *pva;
-	struct pv_list *pvl;
 	unsigned already_found_one = 0;
 	unsigned ix, areas_index;
 	uint32_t req_len, goal, current_le;
 	struct seg_pvs *spvs;
 	struct list *parallel_pvs;
+	int r;
 
 	/* ALLOC_CONTIGUOUS overrides can_split */
 	can_split = (alloc == ALLOC_CONTIGUOUS) ? 0 : can_split;
@@ -1091,48 +1186,30 @@ static int _find_parallel_space(struct a
 			if (list_empty(&pvm->areas))
 				continue;	/* Next PV */
 
-			if (alloc != ALLOC_ANYWHERE) {
-				/* Avoid PVs used by existing parallel areas */
-				if (parallel_pvs)
-					list_iterate_items(pvl, parallel_pvs)
-						if (pvm->pv == pvl->pv)
-							goto next_pv;
-			}
+			if (!_check_pv_constraints(ah, alloc, req, pvm->pv,
+						  parallel_pvs))
+				goto next_pv;
 
 			already_found_one = 0;
 			/* First area in each list is the largest */
 			list_iterate_items(pva, &pvm->areas) {
-				if (prev_lvseg && alloc == ALLOC_CONTIGUOUS) {
-					if (_check_contiguous(ah->cmd,
-							      prev_lvseg,
-							      pva, 
-							      req->index,
-							      req->index + req->area_count - 1,
-							      areas,
-							      areas_size)) {
-						ix++;
-						goto next_pv;
-					}
+				r = _check_area_constraints(ah, alloc, req,
+							    req_len, pva,
+							    prev_lvseg,
+							    areas, areas_size,
+							    can_split, NULL);
+				switch (r) {
+				case NEXT_AREA_ALLOCED:
+					ix++;
+				case NEXT_AREA:
 					continue;
-				}
-
-				if (prev_lvseg && alloc == ALLOC_CLING) {
-					if (_check_cling(ah->cmd,
-							   prev_lvseg,
-							   pva,
-							   req->index,
-							   req->index + req->area_count - 1,
-							   areas,
-							   areas_size)) {
-						ix++;
-					}
+				case NEXT_PV_ALLOCED:
+					ix++;
+				case NEXT_PV:
 					goto next_pv;
 				}
 
-				/* Is it big enough on its own? */
-				if (pva->count < req->len - req->allocated &&
-				    (!can_split || already_found_one))
-					goto next_pv;
+				/* r == READY_FOR_ALLOC */
 
 				if (!already_found_one) {
 					ix++;

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