summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/metadata/lv_alloc.h1
-rw-r--r--lib/metadata/lv_manip.c21
-rw-r--r--lib/metadata/mirror.c2
3 files changed, 20 insertions, 4 deletions
diff --git a/lib/metadata/lv_alloc.h b/lib/metadata/lv_alloc.h
index 71ca1abd..9f8e0e3a 100644
--- a/lib/metadata/lv_alloc.h
+++ b/lib/metadata/lv_alloc.h
@@ -42,6 +42,7 @@ int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
struct lv_segment *seg_from, uint32_t area_from);
int release_lv_segment_area(struct lv_segment *seg, uint32_t s,
uint32_t area_reduction);
+int release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s, uint32_t area_reduction);
struct alloc_handle;
struct alloc_handle *allocate_extents(struct volume_group *vg,
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index bdcc925b..a0be8875 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -299,17 +299,22 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
return seg;
}
-int release_lv_segment_area(struct lv_segment *seg, uint32_t s,
- uint32_t area_reduction)
+static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s,
+ uint32_t area_reduction, int with_discard)
{
if (seg_type(seg, s) == AREA_UNASSIGNED)
return 1;
if (seg_type(seg, s) == AREA_PV) {
+ if (with_discard && !discard_pv_segment(seg_pvseg(seg, s), area_reduction))
+ return_0;
+
if (!release_pv_segment(seg_pvseg(seg, s), area_reduction))
return_0;
+
if (seg->area_len == area_reduction)
seg_type(seg, s) = AREA_UNASSIGNED;
+
return 1;
}
@@ -365,6 +370,16 @@ int release_lv_segment_area(struct lv_segment *seg, uint32_t s,
return 1;
}
+int release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t s, uint32_t area_reduction)
+{
+ return _release_and_discard_lv_segment_area(seg, s, area_reduction, 1);
+}
+
+int release_lv_segment_area(struct lv_segment *seg, uint32_t s, uint32_t area_reduction)
+{
+ return _release_and_discard_lv_segment_area(seg, s, area_reduction, 0);
+}
+
/*
* Move a segment area from one segment to another
*/
@@ -501,7 +516,7 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
area_reduction = reduction;
for (s = 0; s < seg->area_count; s++)
- if (!release_lv_segment_area(seg, s, area_reduction))
+ if (!release_and_discard_lv_segment_area(seg, s, area_reduction))
return_0;
seg->len -= reduction;
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index d943175e..61e4b471 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -1469,7 +1469,7 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
}
for (s = new_mirrors + 1; s < seg->area_count; s++)
- if (!release_lv_segment_area(seg, s, seg->area_len))
+ if (!release_and_discard_lv_segment_area(seg, s, seg->area_len))
return_0;
seg->area_count = new_mirrors + 1;