[dm-devel] [PATCH 3 of 10] LVM: build log_area list

Jonathan Brassow jbrassow at redhat.com
Thu Oct 8 21:18:46 UTC 2009


Patch name: lvm-build-log_area-list.patch

Now that we have change the allocation handle structure to be
able to store a list of log areas, fill them in and utilize
them based on the 'log_count' parameter.  (log_count will
be generalized in subsequent patches, but it is still just
'1' or '0' for now... meaning nothing has changed at this
point.)

RFC: Jonathan Brassow <jbrassow at redhat.com>

Index: LVM2/lib/metadata/lv_manip.c
===================================================================
--- LVM2.orig/lib/metadata/lv_manip.c
+++ LVM2/lib/metadata/lv_manip.c
@@ -730,11 +730,11 @@ static uint32_t mirror_log_extents(uint3
  */
 static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
 				struct pv_area **areas,
-				uint32_t *ix, struct pv_area *log_area,
+				uint32_t *ix, struct pv_area **log_areas,
 				uint32_t log_len)
 {
 	uint32_t area_len, remaining;
-	uint32_t s;
+	uint32_t i,s;
 	struct alloced_area *aa;
 
 	remaining = needed - *ix;
@@ -745,8 +745,8 @@ static int _alloc_parallel_area(struct a
 		if (area_len > areas[s]->count)
 			area_len = areas[s]->count;
 
-	if (!(aa = dm_pool_alloc(ah->mem, sizeof(*aa) *
-			      (ah->area_count + (log_area ? 1 : 0))))) {
+	s = sizeof(*aa) * (ah->area_count + ah->log_count);
+	if (!(aa = dm_pool_alloc(ah->mem, s))) {
 		log_error("alloced_area allocation failed");
 		return 0;
 	}
@@ -763,12 +763,14 @@ static int _alloc_parallel_area(struct a
 	for (s = 0; s < ah->area_count; s++)
 		consume_pv_area(areas[s], area_len);
 
-	if (log_area) {
-		aa[s].pv = log_area->map->pv;
-		aa[s].pe = log_area->start;
+	for (i = 0, s = ah->area_count;
+	     log_areas && (s < ah->area_count + ah->log_count);
+	     s++, i++) {
+		aa[s].pv = log_areas[i]->map->pv;
+		aa[s].pe = log_areas[i]->start;
 		aa[s].len = log_len;
 		dm_list_add(&ah->log_areas, &aa[s].list);
-		consume_pv_area(log_area, log_len);
+		consume_pv_area(log_areas[i], log_len);
 	}
 
 	*ix += area_len * ah->area_multiple;
@@ -985,7 +987,7 @@ static int _find_parallel_space(struct a
 				struct lv_segment *prev_lvseg,
 				uint32_t *allocated, uint32_t needed)
 {
-	int skip = 0;
+	int i, j, skip = 0;
 	struct pv_map *pvm;
 	struct pv_area *pva;
 	struct pv_list *pvl;
@@ -1000,7 +1002,7 @@ static int _find_parallel_space(struct a
 	struct dm_list *parallel_pvs;
 	uint32_t free_pes;
 	uint32_t log_len;
-	struct pv_area *log_area;
+	struct pv_area **log_areas;
 	unsigned log_needs_allocating;
 	struct alloced_area *aa;
 
@@ -1137,8 +1139,13 @@ static int _find_parallel_space(struct a
 		if (ah->log_count && dm_list_empty(&ah->log_areas))
 			log_needs_allocating = 1;
 
+		/*
+		 * Note:  If we allow logs on the same devices as mirror
+		 * images, then that shouldn't factor into the equation.
+		 */
 		if (ix + ix_offset < ah->area_count +
-		   (log_needs_allocating ? ah->log_count : 0))
+		    ((log_needs_allocating && (alloc != ALLOC_ANYWHERE)) ?
+		     ah->log_count : 0))
 			break;
 
 		/* sort the areas so we allocate from the biggest */
@@ -1157,8 +1164,12 @@ static int _find_parallel_space(struct a
 
 		if (!log_needs_allocating) {
 			log_len = 0;
-			log_area = NULL;
+			log_areas = NULL;
 		} else {
+			log_areas = dm_pool_alloc(ah->mem,
+						  sizeof(struct pv_area) *
+						  ah->log_count);
+
 			log_len = mirror_log_extents(ah->log_region_size,
 			    pv_pe_size((*areas)->map->pv),
 			    (max_parallel - *allocated) / ah->area_multiple);
@@ -1169,18 +1180,25 @@ static int _find_parallel_space(struct a
 				  too_small_for_log_count))->count < log_len)
 				too_small_for_log_count++;
 
-			log_area = *(areas + ix_offset + ix - 1 -
-				     too_small_for_log_count);
+			i = ah->log_count - 1;
+			j = ix_offset + ix - 1 - too_small_for_log_count;
+			for (; (i >= 0) && (j >= 0); i--) {
+				log_areas[i] = *(areas + j);
+
+				/* Advance to next PV */
+				for (; ((j >= 0) &&
+					(log_areas[i]->map->pv == (*(areas + j))->map->pv)); j--);
+			}
 		}
 
 		if (ix + ix_offset < ah->area_count +
-		    (log_needs_allocating ? ah->log_count +
-					    too_small_for_log_count : 0))
+		    ((log_needs_allocating  && (alloc != ALLOC_ANYWHERE)) ?
+		     ah->log_count + too_small_for_log_count : 0))
 			/* FIXME With ALLOC_ANYWHERE, need to split areas */
 			break;
 
 		if (!_alloc_parallel_area(ah, max_parallel, areas, allocated,
-					  log_area, log_len))
+					  log_areas, log_len))
 			return_0;
 
 	} while (!contiguous && *allocated != needed && can_split);




More information about the dm-devel mailing list