1
0
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:
Alasdair Kergon 2003-09-01 19:55:16 +00:00
parent 914067a0d0
commit 102255757a

View File

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