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

[lvm-devel] [PATCH mirror 3/13] Enable layer specification in remove_layer_from_lv()



Added layer_lv argument to remove_layer_from_lv().

remove_layer_from_lv() has implicitly removed the top-most layer.
It won't work if the layer can be stacked.
The caller knows which layer it wants to remove.

find_parent_for_layer() will help find a parent LV for specified layer LV.

Thanks,
-- 
Jun'ichi Nomura, NEC Corporation of America
Added layer_lv argument to remove_layer_from_lv().

remove_layer_from_lv() has implicitly removed the top-most layer.
It won't work if the layer can be stacked.
The caller knows which layer it wants to remove.

find_parent_for_layer() will help find a parent LV for specified layer LV.

Index: LVM2.work/lib/metadata/lv_manip.c
===================================================================
--- LVM2.work.orig/lib/metadata/lv_manip.c
+++ LVM2.work/lib/metadata/lv_manip.c
@@ -2181,23 +2181,62 @@ static void _move_lv_segments(struct log
 	lv_from->size = 0;
 }
 
+/*
+ * Find a parent LV for the layer_lv in the lv
+ */
+struct logical_volume *find_parent_for_layer(struct logical_volume *lv,
+                                            struct logical_volume *layer_lv)
+{
+	struct logical_volume *parent;
+	struct lv_segment *seg;
+	uint32_t s;
+
+	list_iterate_items(seg, &lv->segments) {
+		for (s = 0; s < seg->area_count; s++) {
+			if (seg_type(seg, s) != AREA_LV)
+				continue;
+			if (seg_lv(seg, s) == layer_lv)
+				return lv;
+			parent = find_parent_for_layer(seg_lv(seg, s),
+						       layer_lv);
+			if (parent)
+				return parent;
+		}
+	}
+	return NULL;
+}
+
 /* Remove a layer from the LV */
-/* FIXME: how to specify what should be removed if multiple layers stacked? */
-int remove_layer_from_lv(struct logical_volume *lv)
+int remove_layer_from_lv(struct logical_volume *lv,
+			 struct logical_volume *layer_lv)
 {
-	struct logical_volume *orig_lv;
+	struct logical_volume *parent;
+	struct segment_type *segtype;
+
+	parent = find_parent_for_layer(lv, layer_lv);
+	if (!parent) {
+		log_error("Failed to find layer %s in %s",
+		layer_lv->name, lv->name);
+		return 0;
+	}
 
 	/*
 	 * Before removal, the layer should be cleaned up,
 	 * i.e. additional segments and areas should have been removed.
 	 */
-	if (list_size(&lv->segments) != 1 ||
-	    first_seg(lv)->area_count != 1 ||
-	    seg_type(first_seg(lv), 0) != AREA_LV)
-		return 0;
+	if (list_size(&parent->segments) != 1 ||
+	    first_seg(parent)->area_count != 1 ||
+	    seg_type(first_seg(parent), 0) != AREA_LV ||
+	    layer_lv != seg_lv(first_seg(parent), 0) ||
+	    parent->le_count != layer_lv->le_count)
+		return_0;
 
-	orig_lv = seg_lv(first_seg(lv), 0);
-	_move_lv_segments(lv, orig_lv, 0, 0);
+	_move_lv_segments(parent, layer_lv, 0, 0);
+
+	/* Replace the empty layer with error segment */
+	segtype = get_segtype_from_string(lv->vg->cmd, "error");
+	if (!lv_add_virtual_segment(layer_lv, 0, parent->le_count, segtype))
+		return_0;
 
 	return 1;
 }
Index: LVM2.work/lib/metadata/metadata-exported.h
===================================================================
--- LVM2.work.orig/lib/metadata/metadata-exported.h
+++ LVM2.work/lib/metadata/metadata-exported.h
@@ -398,7 +398,10 @@ int remove_layers_for_segments_all(struc
 				   struct list *lvs_changed);
 int split_parent_segments_for_layer(struct cmd_context *cmd,
 				    struct logical_volume *layer_lv);
-int remove_layer_from_lv(struct logical_volume *lv);
+struct logical_volume *find_parent_for_layer(struct logical_volume *lv,
+					     struct logical_volume *layer_lv);
+int remove_layer_from_lv(struct logical_volume *lv,
+			 struct logical_volume *layer_lv);
 struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
 					   struct logical_volume *lv_where,
 					   uint32_t status,
Index: LVM2.work/lib/metadata/mirror.c
===================================================================
--- LVM2.work.orig/lib/metadata/mirror.c
+++ LVM2.work/lib/metadata/mirror.c
@@ -182,7 +182,7 @@ int remove_mirror_images(struct lv_segme
 	if (num_mirrors == 1) {
 		lv1 = seg_lv(mirrored_seg, 0);
 		extents = lv1->le_count;
-		remove_layer_from_lv(mirrored_seg->lv);
+		remove_layer_from_lv(mirrored_seg->lv, lv1);
 		mirrored_seg->lv->status &= ~MIRRORED;
 		mirrored_seg->lv->status &= ~MIRROR_NOTSYNCED;
 		remove_log = 1;

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