1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

check_contiguous to use for_each_pv

This commit is contained in:
Alasdair Kergon 2006-10-07 23:40:36 +00:00
parent ab507e894c
commit b4e2a0e179
2 changed files with 72 additions and 40 deletions

View File

@ -7,6 +7,7 @@ Version 2.02.11 -
Add report columns with underscore before field names ending 'size'. Add report columns with underscore before field names ending 'size'.
Correct regionsize default on lvcreate man page (MB). Correct regionsize default on lvcreate man page (MB).
Fix clvmd bug that could cause it to die when a node with a long name crashed. Fix clvmd bug that could cause it to die when a node with a long name crashed.
Add device size to text metadata.
Fix format_text mda_setup pv->size and pv_setup pe_count calculations. Fix format_text mda_setup pv->size and pv_setup pe_count calculations.
Fix _for_each_pv() for mirror with core log. Fix _for_each_pv() for mirror with core log.
Add lvm_dump.sh script to create a tarball of debugging info from a system. Add lvm_dump.sh script to create a tarball of debugging info from a system.

View File

@ -398,6 +398,7 @@ struct alloced_area {
* Details of an allocation attempt * Details of an allocation attempt
*/ */
struct alloc_handle { struct alloc_handle {
struct cmd_context *cmd;
struct dm_pool *mem; struct dm_pool *mem;
alloc_policy_t alloc; /* Overall policy */ alloc_policy_t alloc; /* Overall policy */
@ -417,7 +418,8 @@ struct alloc_handle {
/* /*
* Preparation for a specific allocation attempt * Preparation for a specific allocation attempt
*/ */
static struct alloc_handle *_alloc_init(struct dm_pool *mem, static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
struct dm_pool *mem,
const struct segment_type *segtype, const struct segment_type *segtype,
alloc_policy_t alloc, alloc_policy_t alloc,
uint32_t mirrors, uint32_t mirrors,
@ -464,6 +466,8 @@ static struct alloc_handle *_alloc_init(struct dm_pool *mem,
if (segtype_is_virtual(segtype)) if (segtype_is_virtual(segtype))
return ah; return ah;
ah->cmd = cmd;
if (!(ah->mem = dm_pool_create("allocation", 1024))) { if (!(ah->mem = dm_pool_create("allocation", 1024))) {
log_error("allocation pool creation failed"); log_error("allocation pool creation failed");
return NULL; return NULL;
@ -675,7 +679,12 @@ static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
*/ */
static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv, static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t le, uint32_t len, uint32_t *max_seg_len, uint32_t le, uint32_t len, uint32_t *max_seg_len,
int (*fn)(struct cmd_context *cmd, struct pv_segment *peg, void *data), uint32_t first_area, uint32_t max_areas,
int top_level_area_index,
int only_single_area_segments,
int (*fn)(struct cmd_context *cmd,
struct pv_segment *peg, uint32_t s,
void *data),
void *data) void *data)
{ {
struct lv_segment *seg; struct lv_segment *seg;
@ -701,24 +710,32 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1; area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
area_len = remaining_seg_len / area_multiple ? : 1; area_len = remaining_seg_len / area_multiple ? : 1;
for (s = 0; s < seg->area_count; s++) { for (s = first_area;
s < seg->area_count && (!max_areas || s <= max_areas);
s++) {
if (seg_type(seg, s) == AREA_LV) { if (seg_type(seg, s) == AREA_LV) {
if (!(r = _for_each_pv(cmd, seg_lv(seg, s), if (!(r = _for_each_pv(cmd, seg_lv(seg, s),
seg_le(seg, s) + seg_le(seg, s) +
(le - seg->le) / area_multiple, (le - seg->le) / area_multiple,
area_len, max_seg_len, fn, area_len, max_seg_len,
only_single_area_segments ? 0 : 0,
only_single_area_segments ? 1 : 0,
top_level_area_index != -1 ? top_level_area_index : s,
only_single_area_segments, fn,
data))) data)))
stack; stack;
} else if (seg_type(seg, s) == AREA_PV) } else if (seg_type(seg, s) == AREA_PV)
if (!(r = fn(cmd, seg_pvseg(seg, s), data))) if (!(r = fn(cmd, seg_pvseg(seg, s), top_level_area_index != -1 ? top_level_area_index : s, data)))
stack; stack;
if (r != 1) if (r != 1)
return r; return r;
} }
if (seg_is_mirrored(seg) && seg->log_lv) { /* FIXME only_single_area_segments used as workaround to skip log LV - needs new param? */
if (!only_single_area_segments && seg_is_mirrored(seg) && seg->log_lv) {
if (!(r = _for_each_pv(cmd, seg->log_lv, 0, MIRROR_LOG_SIZE, if (!(r = _for_each_pv(cmd, seg->log_lv, 0, MIRROR_LOG_SIZE,
NULL, fn, data))) NULL, 0, 0, 0, only_single_area_segments,
fn, data)))
stack; stack;
if (r != 1) if (r != 1)
return r; return r;
@ -743,6 +760,18 @@ static int _comp_area(const void *l, const void *r)
return 0; return 0;
} }
/*
* Search for pvseg that matches condition
*/
struct pv_match {
int (*condition)(struct pv_segment *pvseg, struct pv_area *pva);
struct pv_area **areas;
struct pv_area *pva;
uint32_t areas_size;
int s; /* Area index of match */
};
/* /*
* Is PV area contiguous to PV segment? * Is PV area contiguous to PV segment?
*/ */
@ -757,50 +786,49 @@ static int _is_contiguous(struct pv_segment *pvseg, struct pv_area *pva)
return 1; return 1;
} }
static int _check_pv_contiguous(struct logical_volume *prev_lv, uint32_t prev_le, struct pv_area *pva, static int _is_contiguous_condition(struct cmd_context *cmd,
struct pv_area **areas, uint32_t areas_size) struct pv_segment *pvseg, uint32_t s,
void *data)
{ {
struct lv_segment *seg; struct pv_match *pvmatch = data;
uint32_t s;
int r;
if (!(seg = find_seg_by_le(prev_lv, prev_le))) { if (!pvmatch->condition(pvseg, pvmatch->pva))
log_error("Failed to find segment for %s extent %" PRIu32, return 1; /* Continue */
prev_lv->name, prev_le);
return 0;
}
for (s = 0; s < seg->area_count && s < areas_size; s++) { if (s >= pvmatch->areas_size)
if (seg_type(seg, s) == AREA_LV) { return 1;
/* FIXME For more areas supply flattened seg to ensure consistency */
if (seg->area_count == 1) {
if (!(r = _check_pv_contiguous(seg->lv, seg->le + seg->len - 1, pva, &areas[s], 1)))
stack;
if (r != 1)
return r;
}
} else if (seg_type(seg, s) == AREA_PV)
if (_is_contiguous(seg_pvseg(seg, s), pva)) {
areas[s] = pva;
return 2; /* Finished */
}
}
return 1; /* Continue search */ pvmatch->areas[s] = pvmatch->pva;
return 2; /* Finished */
} }
/* /*
* Is pva contiguous to any existing areas or on the same PV? * Is pva contiguous to any existing areas or on the same PV?
*/ */
static int _check_contiguous(struct lv_segment *prev_lvseg, struct pv_area *pva, static int _check_contiguous(struct cmd_context *cmd,
struct lv_segment *prev_lvseg, struct pv_area *pva,
struct pv_area **areas, uint32_t areas_size) struct pv_area **areas, uint32_t areas_size)
{ {
struct pv_match pvmatch;
int r; int r;
if (!(r = _check_pv_contiguous(prev_lvseg->lv, prev_lvseg->le + prev_lvseg->len - 1, pva, areas, areas_size))) pvmatch.condition = _is_contiguous;
pvmatch.areas = areas;
pvmatch.areas_size = areas_size;
pvmatch.pva = pva;
/* FIXME Cope with stacks by flattening */
if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
prev_lvseg->le + prev_lvseg->len - 1, 1, NULL,
0, 0, -1, 1,
_is_contiguous_condition, &pvmatch)))
stack; stack;
return r ? 1 : 0; if (r != 2)
return 0;
return 1;
} }
/* /*
@ -888,7 +916,8 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
list_iterate_items(pva, &pvm->areas) { list_iterate_items(pva, &pvm->areas) {
if (contiguous) { if (contiguous) {
if (prev_lvseg && if (prev_lvseg &&
_check_contiguous(prev_lvseg, _check_contiguous(ah->cmd,
prev_lvseg,
pva, areas, pva, areas,
areas_size)) { areas_size)) {
contiguous_count++; contiguous_count++;
@ -1124,7 +1153,7 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
if (alloc == ALLOC_INHERIT) if (alloc == ALLOC_INHERIT)
alloc = vg->alloc; alloc = vg->alloc;
if (!(ah = _alloc_init(vg->cmd->mem, segtype, alloc, mirrors, if (!(ah = _alloc_init(vg->cmd, vg->cmd->mem, segtype, alloc, mirrors,
stripes, log_count, mirrored_pv, stripes, log_count, mirrored_pv,
mirrored_pe, parallel_areas))) { mirrored_pe, parallel_areas))) {
stack; stack;
@ -1468,7 +1497,8 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
return lv; return lv;
} }
static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, void *data) static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg,
uint32_t s __attribute((unused)), void *data)
{ {
struct seg_pvs *spvs = (struct seg_pvs *) data; struct seg_pvs *spvs = (struct seg_pvs *) data;
struct pv_list *pvl; struct pv_list *pvl;
@ -1522,7 +1552,8 @@ struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
/* Find next segment end */ /* Find next segment end */
/* FIXME Unnecessary nesting! */ /* FIXME Unnecessary nesting! */
if (!_for_each_pv(cmd, lv, current_le, spvs->len, &spvs->len, _add_pvs, (void *) spvs)) { if (!_for_each_pv(cmd, lv, current_le, spvs->len, &spvs->len,
0, 0, -1, 0, _add_pvs, (void *) spvs)) {
stack; stack;
return NULL; return NULL;
} }