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

Do not traverse PV segment list twice.

In addition to previous patch, we really do not need
to search for segment which was just allocated in
split request.

Make pv_split_segment function return newly allocated
(split) segment also.

(So after this patch, there is only one user
of slow find_peg_by_pe).
This commit is contained in:
Milan Broz 2010-03-31 17:22:26 +00:00
parent 80b96a8974
commit 0423887528
3 changed files with 28 additions and 19 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.63 -
================================
Return newly allocated PV segment after segment split.
Optimise PV segments search for the most last segment search case.
Remove vg_validate call when parsing cached metadata.
Use hash table of LVs to speed up parsing of text metadata with many LVs.

View File

@ -20,7 +20,8 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv, uint32_t pe,
uint32_t area_len,
struct lv_segment *seg,
uint32_t area_num);
int pv_split_segment(struct physical_volume *pv, uint32_t pe);
int pv_split_segment(struct physical_volume *pv, uint32_t pe,
struct pv_segment **pvseg_allocated);
int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction);
int check_pv_segments(struct volume_group *vg);
void merge_pv_segments(struct pv_segment *peg1, struct pv_segment *peg2);

View File

@ -94,17 +94,18 @@ static struct pv_segment *find_peg_by_pe(const struct physical_volume *pv,
/*
* Split peg at given extent.
* Second part is always deallocated.
* Second part is always not allocated to a LV and returned.
*/
static int _pv_split_segment(struct physical_volume *pv, struct pv_segment *peg,
uint32_t pe)
static struct pv_segment *_pv_split_segment(struct physical_volume *pv,
struct pv_segment *peg,
uint32_t pe)
{
struct pv_segment *peg_new;
if (!(peg_new = _alloc_pv_segment(pv->fmt->cmd->mem, peg->pv, pe,
peg->len + peg->pe - pe,
NULL, 0)))
return_0;
return_NULL;
peg->len = peg->len - peg_new->len;
@ -115,31 +116,37 @@ static int _pv_split_segment(struct physical_volume *pv, struct pv_segment *peg,
peg->lvseg->lv->vg->free_count += peg_new->len;
}
return 1;
return peg_new;
}
/*
* Ensure there is a PV segment boundary at the given extent.
*/
int pv_split_segment(struct physical_volume *pv, uint32_t pe)
int pv_split_segment(struct physical_volume *pv, uint32_t pe,
struct pv_segment **pvseg_allocated)
{
struct pv_segment *peg;
struct pv_segment *pvseg, *pvseg_new = NULL;
if (pe == pv->pe_count)
return 1;
goto out;
if (!(peg = find_peg_by_pe(pv, pe))) {
if (!(pvseg = find_peg_by_pe(pv, pe))) {
log_error("Segment with extent %" PRIu32 " in PV %s not found",
pe, pv_dev_name(pv));
return 0;
}
/* This is a peg start already */
if (pe == peg->pe)
return 1;
if (pe == pvseg->pe) {
pvseg_new = pvseg;
goto out;
}
if (!_pv_split_segment(pv, peg, pe))
if (!(pvseg_new = _pv_split_segment(pv, pvseg, pe)))
return_0;
out:
if (pvseg_allocated)
*pvseg_allocated = pvseg_new;
return 1;
}
@ -154,17 +161,17 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
struct lv_segment *seg,
uint32_t area_num)
{
struct pv_segment *peg;
struct pv_segment *peg = NULL;
/* Missing format1 PV */
if (!pv)
return &null_pv_segment;
if (!pv_split_segment(pv, pe) ||
!pv_split_segment(pv, pe + area_len))
if (!pv_split_segment(pv, pe, &peg) ||
!pv_split_segment(pv, pe + area_len, NULL))
return_NULL;
if (!(peg = find_peg_by_pe(pv, pe))) {
if (!peg) {
log_error("Missing PV segment on %s at %u.",
pv_dev_name(pv), pe);
return NULL;
@ -200,7 +207,7 @@ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
}
if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len -
area_reduction))
area_reduction, NULL))
return_0;
return 1;
@ -373,7 +380,7 @@ static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint3
}
}
if (!pv_split_segment(pv, new_pe_count))
if (!pv_split_segment(pv, new_pe_count, NULL))
return_0;
dm_list_iterate_items_safe(peg, pegt, &pv->segments) {