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

lv_reduce tidying.

Remove some unnecessary parameters.
Introduce seg_is macros.
This commit is contained in:
Alasdair Kergon 2005-05-09 16:59:01 +00:00
parent b8e2ad3db9
commit 32469fb25c
13 changed files with 116 additions and 89 deletions

View File

@ -1,5 +1,8 @@
Version 2.01.11 -
==============================
lv_reduce tidying.
Remove some unnecessary parameters.
Introduce seg_is macros.
Version 2.01.10 - 3rd May 2005
==============================

View File

@ -317,10 +317,10 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
*/
_insert_segment(lv, seg);
if (seg->segtype->flags & SEG_AREAS_MIRRORED)
if (seg_is_mirrored(seg))
lv->status |= MIRRORED;
if (seg->segtype->flags & SEG_VIRTUAL)
if (seg_is_virtual(seg))
lv->status |= VIRTUAL;
return 1;

View File

@ -140,7 +140,7 @@ static int _alloc_parallel_area(struct logical_volume *lv, uint32_t area_count,
int striped = 0;
/* Striped or mirrored? */
if (segtype->flags & SEG_AREAS_STRIPED)
if (seg_is_striped(seg))
striped = 1;
count = lv->le_count - *ix;
@ -505,7 +505,7 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
/*
* Chooses a correct allocation policy.
*/
static int _allocate(struct volume_group *vg, struct logical_volume *lv,
static int _allocate(struct logical_volume *lv,
struct list *allocatable_pvs, uint32_t allocated,
alloc_policy_t alloc, struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size, uint32_t mirrors,
@ -526,12 +526,12 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
}
if (alloc == ALLOC_INHERIT)
alloc = vg->alloc;
alloc = lv->vg->alloc;
/*
* Build the sets of available areas on the pv's.
*/
if (!(pvms = create_pv_maps(scratch, vg, allocatable_pvs)))
if (!(pvms = create_pv_maps(scratch, lv->vg, allocatable_pvs)))
goto out;
if (stripes > 1 || mirrors > 1)
@ -555,7 +555,7 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
}
if (r) {
vg->free_count -= lv->le_count - allocated;
lv->vg->free_count -= lv->le_count - allocated;
/*
* Iterate through the new segments, updating pe
@ -680,8 +680,10 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
return lv;
}
int lv_extend(struct format_instance *fid,
struct logical_volume *lv,
/*
* Entry point for all extent allocations
*/
int lv_extend(struct logical_volume *lv,
struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size,
uint32_t mirrors, uint32_t extents,
@ -695,17 +697,17 @@ int lv_extend(struct format_instance *fid,
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
if (fid->fmt->ops->segtype_supported &&
!fid->fmt->ops->segtype_supported(fid, segtype)) {
if (lv->vg->fid->fmt->ops->segtype_supported &&
!lv->vg->fid->fmt->ops->segtype_supported(lv->vg->fid, segtype)) {
log_error("Metadata format (%s) does not support required "
"LV segment type (%s).", fid->fmt->name,
"LV segment type (%s).", lv->vg->fid->fmt->name,
segtype->name);
log_error("Consider changing the metadata format by running "
"vgconvert.");
return 0;
}
if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count, alloc,
if (!_allocate(lv, allocatable_pvs, old_le_count, alloc,
segtype, stripes, stripe_size, mirrors, mirrored_pv,
mirrored_pe, status)) {
lv->le_count = old_le_count;
@ -720,7 +722,8 @@ int lv_extend(struct format_instance *fid,
return 0;
}
if (fid->fmt->ops->lv_setup && !fid->fmt->ops->lv_setup(fid, lv)) {
if (lv->vg->fid->fmt->ops->lv_setup &&
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
stack;
return 0;
}
@ -728,50 +731,65 @@ int lv_extend(struct format_instance *fid,
return 1;
}
int lv_reduce(struct format_instance *fi,
struct logical_volume *lv, uint32_t extents)
static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
{
_put_extents(seg);
seg->len -= reduction;
/* Caller must ensure exact divisibility */
if (seg_is_striped(seg)) {
if (reduction % seg->area_count) {
log_error("Segment extent reduction %" PRIu32
"not divisible by #stripes %" PRIu32,
reduction, seg->area_count);
return 0;
}
seg->area_len -= (reduction / seg->area_count);
} else
seg->area_len -= reduction;
_shrink_lv_segment(seg);
_get_extents(seg);
return 1;
}
/*
* Entry point for all extent reductions
*/
int lv_reduce(struct logical_volume *lv, uint32_t extents)
{
struct list *segh;
struct lv_segment *seg;
uint32_t count = extents;
int striped;
uint32_t reduction;
for (segh = lv->segments.p;
(segh != &lv->segments) && count; segh = segh->p) {
list_uniterate(segh, &lv->segments, &lv->segments) {
seg = list_item(segh, struct lv_segment);
if (!count)
break;
if (seg->len <= count) {
/* remove this segment completely */
count -= seg->len;
_put_extents(seg);
seg->area_len = 0;
_shrink_lv_segment(seg);
list_del(segh);
} else {
/* reduce this segment */
_put_extents(seg);
seg->len -= count;
striped = seg->segtype->flags & SEG_AREAS_STRIPED;
/* Caller must ensure exact divisibility */
if (striped && (count % seg->area_count)) {
log_error("Segment extent reduction %" PRIu32
"not divisible by #stripes %" PRIu32,
count, seg->area_count);
return 0;
}
seg->area_len -=
count / (striped ? seg->area_count : 1);
_shrink_lv_segment(seg);
_get_extents(seg);
count = 0;
reduction = seg->len;
} else
reduction = count;
if (!_lv_segment_reduce(seg, reduction)) {
stack;
return 0;
}
count -= reduction;
}
lv->le_count -= extents;
lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
lv->vg->free_count += extents;
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
if (lv->le_count && lv->vg->fid->fmt->ops->lv_setup &&
!lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
stack;
return 0;
}
@ -779,26 +797,25 @@ int lv_reduce(struct format_instance *fi,
return 1;
}
int lv_remove(struct volume_group *vg, struct logical_volume *lv)
int lv_remove(struct logical_volume *lv)
{
struct lv_segment *seg;
struct lv_list *lvl;
/* find the lv list */
if (!(lvl = find_lv_in_vg(vg, lv->name))) {
if (!lv_reduce(lv, lv->le_count)) {
stack;
return 0;
}
/* iterate through the lv's segments freeing off the pe's */
list_iterate_items(seg, &lv->segments)
_put_extents(seg);
vg->lv_count--;
vg->free_count += lv->le_count;
/* find the lv list */
if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) {
stack;
return 0;
}
list_del(&lvl->list);
lv->vg->lv_count--;
return 1;
}

View File

@ -91,7 +91,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
uint32_t offset = le - seg->le;
uint32_t area_offset;
if (!(seg->segtype->flags & SEG_CAN_SPLIT)) {
if (!seg_can_split(seg)) {
log_error("Unable to split the %s segment at LE %" PRIu32
" in LV %s", seg->segtype->name, le, lv->name);
return 0;
@ -115,7 +115,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
/* In case of a striped segment, the offset has to be / stripes */
area_offset = offset;
if (seg->segtype->flags & SEG_AREAS_STRIPED)
if (seg_is_striped(seg))
area_offset /= seg->area_count;
split_seg->area_len -= area_offset;

View File

@ -435,11 +435,11 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
int import,
struct volume_group *vg);
int lv_reduce(struct format_instance *fi,
struct logical_volume *lv, uint32_t extents);
/* Entry point for all LV extent reductions */
int lv_reduce(struct logical_volume *lv, uint32_t extents);
int lv_extend(struct format_instance *fid,
struct logical_volume *lv,
/* Entry point for all LV extent allocations */
int lv_extend(struct logical_volume *lv,
struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size,
uint32_t mirrors, uint32_t extents,
@ -447,8 +447,8 @@ int lv_extend(struct format_instance *fid,
uint32_t status, struct list *allocatable_pvs,
alloc_policy_t alloc);
/* lv must be part of vg->lvs */
int lv_remove(struct volume_group *vg, struct logical_volume *lv);
/* lv must be part of lv->vg->lvs */
int lv_remove(struct logical_volume *lv);
/* Manipulate PV structures */
int pv_add(struct volume_group *vg, struct physical_volume *pv);
@ -524,7 +524,7 @@ int vg_add_snapshot(struct format_instance *fid, const char *name,
union lvid *lvid, uint32_t extent_count,
uint32_t chunk_size);
int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow);
int vg_remove_snapshot(struct logical_volume *cow);
/*
* Mirroring functions
@ -534,6 +534,7 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
struct list *source_pvl,
struct logical_volume *lv,
struct list *allocatable_pvs,
alloc_policy_t alloc,
struct list *lvs_changed);
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr);

View File

@ -30,6 +30,7 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
struct list *source_pvl,
struct logical_volume *lv,
struct list *allocatable_pvs,
alloc_policy_t alloc,
struct list *lvs_changed)
{
struct list *segh;
@ -76,7 +77,7 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
(pe_start > per_end))
continue;
if (seg->segtype->flags & SEG_AREAS_STRIPED)
if (seg_is_striped(seg))
stripe_multiplier = seg->area_count;
else
stripe_multiplier = 1;
@ -146,12 +147,12 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
lv->vg->name, lv->name);
start_le = lv_mirr->le_count;
if (!lv_extend(lv->vg->fid, lv_mirr, segtype, 1,
if (!lv_extend(lv_mirr, segtype, 1,
seg->area_len, 0u, seg->area_len,
seg->area[s].u.pv.pvseg->pv,
seg->area[s].u.pv.pvseg->pe,
PVMOVE, allocatable_pvs,
lv->alloc)) {
alloc)) {
log_error("Unable to allocate "
"temporary LV for pvmove.");
return 0;
@ -207,8 +208,7 @@ int remove_pvmove_mirrors(struct volume_group *vg,
/* Check the segment params are compatible */
/* FIXME Improve error mesg & remove restrcn */
if ((!(mir_seg->segtype->flags
& SEG_AREAS_MIRRORED)) ||
if (!seg_is_mirrored(mir_seg) ||
!(mir_seg->status & PVMOVE) ||
mir_seg->le != seg->area[s].u.lv.le ||
mir_seg->area_count != 2 ||
@ -263,7 +263,7 @@ const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
list_iterate(segh, &lv_mirr->segments) {
seg = list_item(segh, struct lv_segment);
if (!(seg->segtype->flags & SEG_AREAS_MIRRORED))
if (!seg_is_mirrored(seg))
continue;
if (seg->area[0].type != AREA_PV)
continue;
@ -391,7 +391,7 @@ float copy_percent(struct logical_volume *lv_mirr)
denominator += seg->area_len;
if (seg->segtype->flags & SEG_AREAS_MIRRORED)
if (seg_is_mirrored(seg))
numerator += seg->extents_copied;
else
numerator += seg->area_len;

View File

@ -33,6 +33,12 @@ struct dev_manager;
#define SEG_FORMAT1_SUPPORT 0x00000010
#define SEG_VIRTUAL 0x00000020
#define seg_is_mirrored(seg) ((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0)
#define seg_is_striped(seg) ((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0)
#define seg_is_snapshot(seg) ((seg)->segtype->flags & SEG_SNAPSHOT ? 1 : 0)
#define seg_is_virtual(seg) ((seg)->segtype->flags & SEG_VIRTUAL ? 1 : 0)
#define seg_can_split(seg) ((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
struct segment_type {
struct list list;
struct cmd_context *cmd;

View File

@ -81,12 +81,12 @@ int vg_add_snapshot(struct format_instance *fid, const char *name,
return 1;
}
int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow)
int vg_remove_snapshot(struct logical_volume *cow)
{
list_del(&cow->snapshot->origin_list);
cow->snapshot->origin->origin_count--;
if (!lv_remove(vg, cow->snapshot->lv)) {
if (!lv_remove(cow->snapshot->lv)) {
log_error("Failed to remove internal snapshot LV %s",
cow->snapshot->lv->name);
return 0;
@ -94,8 +94,8 @@ int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow)
cow->snapshot = NULL;
vg->snapshot_count--;
vg->lv_count++;
cow->vg->snapshot_count--;
cow->vg->lv_count++;
cow->status |= VISIBLE_LV;
return 1;

View File

@ -246,7 +246,7 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
if (arg_count(cmd, stripes_ARG) && lp->stripes == 1)
log_print("Redundant stripes argument: default is 1");
if (arg_count(cmd, snapshot_ARG) || (lp->segtype->flags & SEG_SNAPSHOT))
if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp))
lp->snapshot = 1;
if (lp->snapshot) {
@ -498,7 +498,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
return 0;
}
if (!(lp->segtype->flags & SEG_VIRTUAL) &&
if (!seg_is_virtual(lp) &&
vg->free_count < lp->extents) {
log_error("Insufficient free extents (%u) in volume group %s: "
"%u required", vg->free_count, vg->name, lp->extents);
@ -518,7 +518,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
return 0;
}
if (!lv_extend(vg->fid, lv, lp->segtype, lp->stripes, lp->stripe_size,
if (!lv_extend(lv, lp->segtype, lp->stripes, lp->stripe_size,
lp->mirrors, lp->extents, NULL, 0u, 0u, pvh, lp->alloc)) {
stack;
return 0;

View File

@ -70,14 +70,14 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_cow(lv)) {
log_verbose("Removing snapshot %s", lv->name);
if (!vg_remove_snapshot(lv->vg, lv)) {
if (!vg_remove_snapshot(lv)) {
stack;
return ECMD_FAILED;
}
}
log_verbose("Releasing logical volume \"%s\"", lv->name);
if (!lv_remove(vg, lv)) {
if (!lv_remove(lv)) {
log_error("Error releasing logical volume \"%s\"", lv->name);
return ECMD_FAILED;
}

View File

@ -240,7 +240,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
if ((lp->extents > lv->le_count) &&
!(lp->stripes == 1 || (lp->stripes > 1 && lp->stripe_size))) {
list_iterate_items(seg, &lv->segments) {
if (!(seg->segtype->flags & SEG_AREAS_STRIPED))
if (!seg_is_striped(seg))
continue;
sz = seg->stripe_size;
@ -288,7 +288,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
list_iterate_items(seg, &lv->segments) {
seg_extents = seg->len;
if (seg->segtype->flags & SEG_AREAS_STRIPED) {
if (seg_is_striped(seg)) {
seg_stripesize = seg->stripe_size;
seg_stripes = seg->area_count;
}
@ -451,14 +451,14 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
SIZE_SHORT));
if (lp->resize == LV_REDUCE) {
if (!lv_reduce(vg->fid, lv, lv->le_count - lp->extents)) {
if (!lv_reduce(lv, lv->le_count - lp->extents)) {
stack;
return ECMD_FAILED;
}
} else if (!lv_extend(vg->fid, lv, lp->segtype, lp->stripes,
lp->stripe_size, 0u,
lp->extents - lv->le_count,
NULL, 0u, 0u, pvh, alloc)) {
} else if (!lv_extend(lv, lp->segtype, lp->stripes,
lp->stripe_size, 0u,
lp->extents - lv->le_count,
NULL, 0u, 0u, pvh, alloc)) {
stack;
return ECMD_FAILED;
}

View File

@ -140,7 +140,6 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
struct lv_list *lvl;
/* FIXME Cope with non-contiguous => splitting existing segments */
/* FIXME Pass 'alloc' down to lv_extend */
if (!(lv_mirr = lv_create_empty(vg->fid, NULL, "pvmove%d", NULL,
LVM_READ | LVM_WRITE,
ALLOC_CONTIGUOUS, 0, vg))) {
@ -176,7 +175,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
continue;
}
if (!insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
allocatable_pvs, *lvs_changed)) {
allocatable_pvs, alloc,
*lvs_changed)) {
stack;
return NULL;
}
@ -439,7 +439,7 @@ static int _finish_pvmove(struct cmd_context *cmd, struct volume_group *vg,
}
log_verbose("Removing temporary pvmove LV");
if (!lv_remove(vg, lv_mirr)) {
if (!lv_remove(lv_mirr)) {
log_error("ABORTING: Removal of temporary pvmove LV failed");
return 0;
}

View File

@ -86,13 +86,13 @@ static int _remove_lv(struct cmd_context *cmd, struct logical_volume *lv,
cow = snap_seg->cow;
*list_unsafe = 1; /* May remove caller's lvht! */
if (!vg_remove_snapshot(lv->vg, cow)) {
if (!vg_remove_snapshot(cow)) {
stack;
return 0;
}
log_verbose("Removing LV %s from VG %s", cow->name,
lv->vg->name);
if (!lv_remove(lv->vg, cow)) {
if (!lv_remove(cow)) {
stack;
return 0;
}
@ -100,7 +100,7 @@ static int _remove_lv(struct cmd_context *cmd, struct logical_volume *lv,
/* Remove the LV itself */
log_verbose("Removing LV %s from VG %s", lv->name, lv->vg->name);
if (!lv_remove(lv->vg, lv)) {
if (!lv_remove(lv)) {
stack;
return 0;
}