mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
add cling allocation policy
This commit is contained in:
parent
4a2ca1b998
commit
de5c82a0d9
@ -1,5 +1,6 @@
|
||||
Version 2.02.11 -
|
||||
=====================================
|
||||
Add cling allocation policy.
|
||||
Change _check_contiguous() to use _for_each_pv().
|
||||
Extend _for_each_pv() to allow termination without error.
|
||||
Abstract _is_contiguous().
|
||||
|
@ -30,6 +30,7 @@ static struct {
|
||||
} _policies[] = {
|
||||
{
|
||||
ALLOC_CONTIGUOUS, "contiguous"}, {
|
||||
ALLOC_CLING, "cling"}, {
|
||||
ALLOC_NORMAL, "normal"}, {
|
||||
ALLOC_ANYWHERE, "anywhere"}, {
|
||||
ALLOC_INHERIT, "inherit"}
|
||||
|
@ -772,6 +772,17 @@ struct pv_match {
|
||||
int s; /* Area index of match */
|
||||
};
|
||||
|
||||
/*
|
||||
* Is PV area on the same PV?
|
||||
*/
|
||||
static int _is_same_pv(struct pv_segment *pvseg, struct pv_area *pva)
|
||||
{
|
||||
if (pvseg->pv != pva->map->pv)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is PV area contiguous to PV segment?
|
||||
*/
|
||||
@ -786,9 +797,9 @@ static int _is_contiguous(struct pv_segment *pvseg, struct pv_area *pva)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _is_contiguous_condition(struct cmd_context *cmd,
|
||||
struct pv_segment *pvseg, uint32_t s,
|
||||
void *data)
|
||||
static int _is_condition(struct cmd_context *cmd,
|
||||
struct pv_segment *pvseg, uint32_t s,
|
||||
void *data)
|
||||
{
|
||||
struct pv_match *pvmatch = data;
|
||||
|
||||
@ -803,6 +814,34 @@ static int _is_contiguous_condition(struct cmd_context *cmd,
|
||||
return 2; /* Finished */
|
||||
}
|
||||
|
||||
/*
|
||||
* Is pva on same PV as any existing areas?
|
||||
*/
|
||||
static int _check_cling(struct cmd_context *cmd,
|
||||
struct lv_segment *prev_lvseg, struct pv_area *pva,
|
||||
struct pv_area **areas, uint32_t areas_size)
|
||||
{
|
||||
struct pv_match pvmatch;
|
||||
int r;
|
||||
|
||||
pvmatch.condition = _is_same_pv;
|
||||
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_condition, &pvmatch)))
|
||||
stack;
|
||||
|
||||
if (r != 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is pva contiguous to any existing areas or on the same PV?
|
||||
*/
|
||||
@ -822,7 +861,7 @@ static int _check_contiguous(struct cmd_context *cmd,
|
||||
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)))
|
||||
_is_condition, &pvmatch)))
|
||||
stack;
|
||||
|
||||
if (r != 2)
|
||||
@ -844,9 +883,9 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
struct pv_area *pva;
|
||||
struct pv_list *pvl;
|
||||
unsigned already_found_one = 0;
|
||||
unsigned contiguous = 0, contiguous_count = 0;
|
||||
unsigned contiguous = 0, cling = 0, preferred_count = 0;
|
||||
unsigned ix;
|
||||
unsigned ix_offset = 0; /* Offset for non-contiguous allocations */
|
||||
unsigned ix_offset = 0; /* Offset for non-preferred allocations */
|
||||
uint32_t max_parallel; /* Maximum extents to allocate */
|
||||
uint32_t next_le;
|
||||
struct seg_pvs *spvs;
|
||||
@ -856,9 +895,14 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
/* FIXME Select log PV appropriately if there isn't one yet */
|
||||
|
||||
/* Are there any preceding segments we must follow on from? */
|
||||
if ((alloc == ALLOC_CONTIGUOUS) && prev_lvseg) {
|
||||
contiguous = 1;
|
||||
if (prev_lvseg) {
|
||||
ix_offset = prev_lvseg->area_count;
|
||||
if ((alloc == ALLOC_CONTIGUOUS))
|
||||
contiguous = 1;
|
||||
else if ((alloc == ALLOC_CLING))
|
||||
cling = 1;
|
||||
else
|
||||
ix_offset = 0;
|
||||
}
|
||||
|
||||
/* FIXME This algorithm needs a lot of cleaning up! */
|
||||
@ -867,6 +911,7 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
/* ix holds the number of areas found on other PVs */
|
||||
do {
|
||||
ix = 0;
|
||||
preferred_count = 0;
|
||||
|
||||
parallel_pvs = NULL;
|
||||
max_parallel = needed;
|
||||
@ -920,12 +965,23 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
prev_lvseg,
|
||||
pva, areas,
|
||||
areas_size)) {
|
||||
contiguous_count++;
|
||||
preferred_count++;
|
||||
goto next_pv;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cling) {
|
||||
if (prev_lvseg &&
|
||||
_check_cling(ah->cmd,
|
||||
prev_lvseg,
|
||||
pva, areas,
|
||||
areas_size)) {
|
||||
preferred_count++;
|
||||
}
|
||||
goto next_pv;
|
||||
}
|
||||
|
||||
/* Is it big enough on its own? */
|
||||
if (pva->count * ah->area_multiple <
|
||||
max_parallel - *allocated &&
|
||||
@ -949,7 +1005,7 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
break;
|
||||
}
|
||||
|
||||
if (contiguous && (contiguous_count < ix_offset))
|
||||
if ((contiguous || cling) && (preferred_count < ix_offset))
|
||||
break;
|
||||
|
||||
/* Only allocate log_area the first time around */
|
||||
@ -1058,6 +1114,18 @@ static int _allocate(struct alloc_handle *ah,
|
||||
(!can_split && (allocated != old_allocated)))
|
||||
goto finished;
|
||||
|
||||
old_allocated = allocated;
|
||||
if (!_find_parallel_space(ah, ALLOC_CLING, pvms, areas,
|
||||
areas_size, can_split,
|
||||
prev_lvseg, &allocated, new_extents)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((allocated == new_extents) || (ah->alloc == ALLOC_CLING) ||
|
||||
(!can_split && (allocated != old_allocated)))
|
||||
goto finished;
|
||||
|
||||
old_allocated = allocated;
|
||||
if (!_find_parallel_space(ah, ALLOC_NORMAL, pvms, areas,
|
||||
areas_size, can_split,
|
||||
|
@ -82,6 +82,7 @@ typedef enum {
|
||||
ALLOC_INVALID = 0,
|
||||
ALLOC_INHERIT,
|
||||
ALLOC_CONTIGUOUS,
|
||||
ALLOC_CLING,
|
||||
ALLOC_NORMAL,
|
||||
ALLOC_ANYWHERE
|
||||
} alloc_policy_t;
|
||||
|
@ -104,6 +104,8 @@ static char _alloc_policy_char(alloc_policy_t alloc)
|
||||
switch (alloc) {
|
||||
case ALLOC_CONTIGUOUS:
|
||||
return 'c';
|
||||
case ALLOC_CLING:
|
||||
return 'C';
|
||||
case ALLOC_NORMAL:
|
||||
return 'n';
|
||||
case ALLOC_ANYWHERE:
|
||||
|
13
man/lvm.8
13
man/lvm.8
@ -136,7 +136,7 @@ Characters allowed in tags are: A-Z a-z 0-9 _ + . -
|
||||
Delete the tag \fBtag\fP from a PV, VG or LV, if it's present.
|
||||
.TP
|
||||
\fB--alloc AllocationPolicy\fP
|
||||
The allocation policy to use: \fBcontiguous\fP, \fBnormal\fP, \fBanywhere\fP or \fBinherit\fP.
|
||||
The allocation policy to use: \fBcontiguous\fP, \fBcling\fP, \fBnormal\fP, \fBanywhere\fP or \fBinherit\fP.
|
||||
When a command needs to allocate physical extents from the volume group,
|
||||
the allocation policy controls how they are chosen.
|
||||
Each volume group and logical volume has an allocation policy.
|
||||
@ -146,15 +146,18 @@ physical volume. The default for a logical volume is \fBinherit\fP
|
||||
which applies the same policy as for the volume group. These policies can
|
||||
be changed using \fBlvchange\fP (8) and \fBvgchange\fP (8) or over-ridden
|
||||
on the command line of any command that performs allocation.
|
||||
The \fBcontiguous\fP policy requires that new extents are adjacent to
|
||||
existing extents. If there are sufficient free extents to satisfy
|
||||
The \fBcontiguous\fP policy requires that new extents be placed adjacent
|
||||
to existing extents.
|
||||
The \fBcling\fP policy places new extents on the same physical
|
||||
volume as existing extents in the same stripe of the Logical Volume.
|
||||
If there are sufficient free extents to satisfy
|
||||
an allocation request but \fBnormal\fP doesn't use them,
|
||||
\fBanywhere\fP will - even if that reduces performance by
|
||||
placing two stripes on the same physical volume.
|
||||
.IP
|
||||
N.B. The policies described above are not implemented fully yet.
|
||||
In particular, \fBcontiguous\fP does not place new extents adjacent to existing
|
||||
extents and \fBanywhere\fP is not implemented at all.
|
||||
In particular, contiguous free space cannot be broken up to
|
||||
satisfy allocation attempts.
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
.TP
|
||||
\fBLVM_SYSTEM_DIR\fP
|
||||
|
Loading…
Reference in New Issue
Block a user