mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-23 21:35:29 +03:00
Additional validation of LV segments read from metadata. [HM]
This commit is contained in:
parent
914067a0d0
commit
102255757a
@ -8,36 +8,51 @@
|
||||
#include "metadata.h"
|
||||
|
||||
/*
|
||||
* Returns success if the segments were
|
||||
* successfully merged. If the do merge, 'first'
|
||||
* will be adjusted to contain both areas.
|
||||
* Test whether two segments could be merged by the current merging code
|
||||
*/
|
||||
static int _merge(struct lv_segment *first, struct lv_segment *second)
|
||||
static int _segments_compatible(struct lv_segment *first,
|
||||
struct lv_segment *second)
|
||||
{
|
||||
unsigned int s;
|
||||
uint32_t width;
|
||||
unsigned s;
|
||||
|
||||
if (!first ||
|
||||
(first->type != SEG_STRIPED) ||
|
||||
(first->type != second->type) ||
|
||||
/* FIXME Relax the seg type restriction */
|
||||
if (!first || !second ||
|
||||
(first->type != SEG_STRIPED) || (second->type != first->type) ||
|
||||
(first->area_count != second->area_count) ||
|
||||
(first->stripe_size != second->stripe_size))
|
||||
return 0;
|
||||
|
||||
for (s = 0; s < first->area_count; s++) {
|
||||
width = first->area_len;
|
||||
|
||||
/* FIXME Relax this to first type != second type ? */
|
||||
if (first->area[s].type != AREA_PV ||
|
||||
second->area[s].type != AREA_PV)
|
||||
/* FIXME Relax this to first area type != second area type */
|
||||
/* plus the additional AREA_LV checks needed */
|
||||
if ((first->area[s].type != AREA_PV) ||
|
||||
(second->area[s].type != AREA_PV))
|
||||
return 0;
|
||||
|
||||
width = first->area_len;
|
||||
|
||||
if ((first->area[s].u.pv.pv != second->area[s].u.pv.pv) ||
|
||||
(first->area[s].u.pv.pe + width != second->area[s].u.pv.pe))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we should merge */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to merge two adjacent segments.
|
||||
* Currently only supports SEG_STRIPED on AREA_PV.
|
||||
* Returns success if successful, in which case 'first'
|
||||
* gets adjusted to contain both areas.
|
||||
*/
|
||||
static int _merge(struct lv_segment *first, struct lv_segment *second)
|
||||
{
|
||||
|
||||
if (!_segments_compatible(first, second))
|
||||
return 0;
|
||||
|
||||
first->len += second->len;
|
||||
first->area_len += second->area_len;
|
||||
|
||||
@ -61,7 +76,27 @@ int lv_merge_segments(struct logical_volume *lv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that an LV's segments are consecutive, complete and don't overlap.
|
||||
*/
|
||||
int lv_check_segments(struct logical_volume *lv)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
uint32_t le = 0;
|
||||
unsigned seg_count = 0;
|
||||
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
seg_count++;
|
||||
if (seg->le != le) {
|
||||
log_error("LV %s invalid: segment %u should begin at "
|
||||
"LE %" PRIu32 " (found %" PRIu32 ").",
|
||||
lv->name, seg_count, le, seg->le);
|
||||
return 0;
|
||||
}
|
||||
|
||||
le += seg->len;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user