1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-09 12:58:41 +03:00

The latest attempt at making extended striped LVs work portably with LVM1.

This commit is contained in:
Alasdair Kergon 2002-01-25 20:24:14 +00:00
parent e1c24bd5a2
commit 74ccfe851b
2 changed files with 59 additions and 42 deletions

View File

@ -298,8 +298,8 @@ int export_extents(struct disk_list *dl, int lv_num,
for (pe = 0; pe < (seg->len / seg->stripes); pe++) {
ped = &dl->extents[pe + seg->area[s].pe];
ped->lv_num = lv_num;
ped->le_num = seg->le + pe +
s * (seg->len / seg->stripes);
ped->le_num = (seg->le / seg->stripes) + pe +
s * (lv->le_count / seg->stripes);
}
}
}

View File

@ -236,56 +236,73 @@ static int _read_linear(struct pool *mem, struct lv_map *lvm)
return 1;
}
static int _check_stripe(struct lv_map *lvm, struct stripe_segment *seg,
uint32_t base_le, uint32_t len)
{
uint32_t le, st;
le = base_le + seg->len;
/*
* Is the next physical extent in every stripe adjacent to the last?
*/
for (st = 0; st < seg->stripes; st++)
if ((lvm->map[le + st * len].pv != seg->area[st].pv) ||
(lvm->map[le + st * len].pe != seg->area[st].pe + seg->len))
return 0;
return 1;
}
static int _read_stripes(struct pool *mem, struct lv_map *lvm)
{
const char *too_many_segments =
"Logical volume appears to contain more than one segment, "
"which is not allowed in format1.";
uint32_t st, le = 0, len;
struct stripe_segment *seg;
struct pe_specifier *ps;
uint32_t len, i, s;
if (!(seg = _alloc_seg(mem, lvm->stripes))) {
stack;
return 0;
}
seg->lv = lvm->lv;
seg->le = 0;
seg->len = lvm->lv->le_count;
seg->stripes = lvm->stripes;
seg->stripe_size = lvm->stripe_size;
/*
* There can only be a single segment for format1.
* Work out overall striped length
*/
if (seg->len % seg->stripes) {
log_err(too_many_segments);
return 0;
if (lvm->lv->le_count % lvm->stripes) {
log_error("Number of stripes (%u) incompatible "
"with logical extent count (%u) for %s",
lvm->stripes, lvm->lv->le_count,
lvm->lv->name);
}
len = lvm->lv->le_count / lvm->stripes;
len = seg->len / seg->stripes;
for (s = 0; s < lvm->stripes; s++) {
seg->area[s].pv = lvm->map[s * len].pv;
seg->area[s].pe = lvm->map[s * len].pe;
}
/*
* Check this assumption was correct.
*/
for (i = 1; i < len; i++)
for (s = 0; s < lvm->stripes; s++) {
ps = lvm->map + i + (s * len);
if ((seg->area[s].pv != ps->pv) ||
((seg->area[s].pe + i) != ps->pe)) {
log_err(too_many_segments);
return 0;
}
while (le < len) {
if (!(seg = _alloc_seg(mem, lvm->stripes))) {
stack;
return 0;
}
list_add(&lvm->lv->segments, &seg->list);
seg->lv = lvm->lv;
seg->stripe_size = lvm->stripe_size;
seg->stripes = lvm->stripes;
seg->le = seg->stripes * le;
seg->len = 1;
/*
* Set up start positions of each stripe in this segment
*/
for (st = 0; st < seg->stripes; st++) {
seg->area[st].pv = lvm->map[le + st * len].pv;
seg->area[st].pe = lvm->map[le + st * len].pe;
}
/*
* Find how many blocks are contiguous in all stripes
* and so can form part of this segment
*/
while (_check_stripe(lvm, seg, le, len))
seg->len++;
le += seg->len;
seg->len *= seg->stripes;
list_add(&lvm->lv->segments, &seg->list);
}
return 1;
}