1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

discards: don't discard reconfigured extents

Update release_lv_segment_area not to discard any PV extents,
as it also gets used when moving extents between LVs.
Instead, call a new function release_and_discard_lv_segment_area() in
the two places where data should be discarded - lv_reduce() and
remove_mirrors_from_segments().
This commit is contained in:
Alasdair G Kergon 2012-06-27 21:53:02 +01:00
parent e59f6981e6
commit 07a25c249b
4 changed files with 21 additions and 4 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
Never issue discards when LV extents are being reconfigured, not deleted.
Allow release_lv_segment_area to fail as functions it calls can fail.
Open device read-only to obtain readahead value.
Fix lvconvert error path NULL pointer dereference.

View File

@ -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,

View File

@ -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;

View File

@ -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;