Merging device is loaded with "-cow" suffix and with base name of the origin. This is required, so that "-cow" device can be found and removed when lvremove is performed. Signed-off-by: Mikulas Patocka --- lib/activate/dev_manager.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) Index: LVM2.2.02.45/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.45.orig/lib/activate/dev_manager.c 2009-05-11 13:08:40.000000000 +0200 +++ LVM2.2.02.45/lib/activate/dev_manager.c 2009-05-11 13:08:59.000000000 +0200 @@ -907,7 +907,8 @@ static int _add_target_to_dtree(struct d } static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, - struct logical_volume *lv, const char *layer); + struct logical_volume *lv, const char *lv_name, + const char *layer); static int _add_segment_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, @@ -936,7 +937,7 @@ static int _add_segment_to_dtree(struct /* Add mirror log */ if (seg->log_lv && - !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL)) + !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL, NULL)) return_0; /* If this is a snapshot origin, add real LV */ @@ -946,19 +947,22 @@ static int _add_segment_to_dtree(struct return 0; } if (seg->lv->merging_snapshot) { - if (!_add_new_lv_to_dtree(dm, dtree, seg->lv->merging_snapshot->cow, "cow")) + if (!_add_new_lv_to_dtree(dm, dtree, + seg->lv->merging_snapshot->cow, + seg->lv->merging_snapshot->origin->name, "cow")) return_0; } - if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "real")) + if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, NULL, "real")) return_0; } else if (lv_is_cow(seg->lv) && !layer) { - if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "cow")) + if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, NULL, "cow")) return_0; } else { /* Add any LVs used by this segment */ for (s = 0; s < seg->area_count; s++) if ((seg_type(seg, s) == AREA_LV) && - (!_add_new_lv_to_dtree(dm, dtree, seg_lv(seg, s), NULL))) + (!_add_new_lv_to_dtree(dm, dtree, seg_lv(seg, s), + NULL, NULL))) return_0; } @@ -975,14 +979,17 @@ static int _add_segment_to_dtree(struct if (lv_is_origin(seg->lv) && !layer) /* Add any snapshots of this LV */ dm_list_iterate(snh, &seg->lv->snapshot_segs) - if (!_add_new_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow, NULL)) + if (!_add_new_lv_to_dtree(dm, dtree, + dm_list_struct_base(snh, struct lv_segment, + origin_list)->cow, NULL, NULL)) return_0; return 1; } static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, - struct logical_volume *lv, const char *layer) + struct logical_volume *lv, const char *lv_name, + const char *layer) { struct lv_segment *seg; struct lv_layer *lvlayer; @@ -992,10 +999,12 @@ static int _add_new_lv_to_dtree(struct d uint32_t read_ahead = lv->read_ahead; uint32_t read_ahead_flags = UINT32_C(0); + if (!lv_name) lv_name = lv->name; + if (lv_is_cow(lv) && find_cow(lv)->status & SNAPSHOT_MERGE && !layer) return 1; - if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer))) + if (!(name = build_dm_name(dm->mem, lv->vg->name, lv_name, layer))) return_0; if (!(dlid = build_dlid(dm, lv->lvid.s, layer))) @@ -1007,7 +1016,7 @@ static int _add_new_lv_to_dtree(struct d return 1; if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) { - log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv->name, layer); + log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv_name, layer); return 0; } @@ -1199,7 +1208,7 @@ static int _tree_action(struct dev_manag case PRELOAD: case ACTIVATE: /* Add all required new devices to tree */ - if (!_add_new_lv_to_dtree(dm, dtree, lv, NULL)) + if (!_add_new_lv_to_dtree(dm, dtree, lv, NULL, NULL)) goto_out; /* Preload any devices required before any suspensions */