mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
o lv_manip.c will contain the code for lv_create, lv_extend and lv_reduce.
This commit is contained in:
parent
1138def67f
commit
dd4e3f9efc
@ -28,6 +28,7 @@ SOURCES=\
|
|||||||
format1/layout.c \
|
format1/layout.c \
|
||||||
format1/vg_number.c \
|
format1/vg_number.c \
|
||||||
log/log.c \
|
log/log.c \
|
||||||
|
metadata/lv_manip.c \
|
||||||
metadata/metadata.c \
|
metadata/metadata.c \
|
||||||
metadata/pv_map.c \
|
metadata/pv_map.c \
|
||||||
mm/dbg_malloc.c \
|
mm/dbg_malloc.c \
|
||||||
|
188
lib/metadata/lv_manip.c
Normal file
188
lib/metadata/lv_manip.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metadata.h"
|
||||||
|
#include "pv_map.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The heart of the allocation code. This
|
||||||
|
* function takes a pv_area and allocates it to
|
||||||
|
* the lv. If the lv doesn't need the complete
|
||||||
|
* area then the area is split, otherwise the area
|
||||||
|
* is unlinked from the pv_map.
|
||||||
|
*/
|
||||||
|
static int _alloc_area(struct logical_volume *lv, uint32_t index,
|
||||||
|
struct physical_volume *pv, struct pv_area *pva)
|
||||||
|
{
|
||||||
|
uint32_t count, remaining, i, start;
|
||||||
|
|
||||||
|
start = pva->start;
|
||||||
|
|
||||||
|
count = pva->count;
|
||||||
|
remaining = lv->le_count - index;
|
||||||
|
|
||||||
|
if (remaining < count) {
|
||||||
|
/* split the area */
|
||||||
|
count = remaining;
|
||||||
|
pva->start += count;
|
||||||
|
pva->count -= count;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* unlink the area */
|
||||||
|
list_del(&pva->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
lv->map[i + index].pv = pv;
|
||||||
|
lv->map[i + index].pe = start + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _alloc_striped(struct logical_volume *lv, struct list *pvms)
|
||||||
|
{
|
||||||
|
log_err("striped allocation not implemented yet.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _alloc_contiguous(struct logical_volume *lv, struct list *pvms)
|
||||||
|
{
|
||||||
|
log_err("contiguous allocation not implemented yet.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _alloc_simple(struct logical_volume *lv, struct list *pvms)
|
||||||
|
{
|
||||||
|
struct list *tmp1, *tmp2;
|
||||||
|
struct pv_map *pvm;
|
||||||
|
struct pv_area *pva;
|
||||||
|
uint32_t allocated = 0;
|
||||||
|
|
||||||
|
list_iterate (tmp1, pvms) {
|
||||||
|
pvm = list_item(tmp1, struct pv_map);
|
||||||
|
|
||||||
|
list_iterate (tmp2, &pvm->areas) {
|
||||||
|
pva = list_item(tmp2, struct pv_area);
|
||||||
|
allocated += _alloc_area(lv, allocated, pvm->pv, pva);
|
||||||
|
|
||||||
|
if (allocated == lv->le_count)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocated == lv->le_count) /* FIXME: yuck, repeated test */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocated != lv->le_count) {
|
||||||
|
log_err("insufficient free extents to "
|
||||||
|
"allocate logical volume");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct logical_volume *lv_create(struct io_space *ios,
|
||||||
|
const char *name,
|
||||||
|
uint32_t status,
|
||||||
|
uint32_t stripes,
|
||||||
|
uint32_t stripe_size,
|
||||||
|
uint32_t extents,
|
||||||
|
struct volume_group *vg,
|
||||||
|
struct pv_list *acceptable_pvs)
|
||||||
|
{
|
||||||
|
struct lv_list *ll = NULL;
|
||||||
|
struct logical_volume *lv;
|
||||||
|
struct list *pvms;
|
||||||
|
struct pool *scratch;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!(scratch = pool_create(1024))) {
|
||||||
|
stack;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extents) {
|
||||||
|
log_err("Attempt to create an lv with zero extents");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vg->free_count < extents) {
|
||||||
|
log_err("Insufficient free extents in volume group");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vg->max_lv == vg->lv_count) {
|
||||||
|
log_err("Maximum logical volumes already reached "
|
||||||
|
"for this volume group.");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ll = pool_zalloc(ios->mem, sizeof(*ll)))) {
|
||||||
|
stack;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv = &ll->lv;
|
||||||
|
|
||||||
|
strcpy(lv->id.uuid, "");
|
||||||
|
|
||||||
|
if (!(lv->name = pool_strdup(ios->mem, name))) {
|
||||||
|
stack;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv->vg = vg;
|
||||||
|
lv->status = status;
|
||||||
|
lv->read_ahead = 0;
|
||||||
|
lv->stripes = stripes;
|
||||||
|
lv->size = extents * vg->extent_size;
|
||||||
|
lv->le_count = extents;
|
||||||
|
|
||||||
|
if (!(lv->map = pool_zalloc(ios->mem, sizeof(*lv->map) * extents))) {
|
||||||
|
stack;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build the sets of available areas on
|
||||||
|
* the pv's.
|
||||||
|
*/
|
||||||
|
if (!(pvms = create_pv_maps(scratch, vg))) {
|
||||||
|
log_err("couldn't create extent mappings");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripes > 1)
|
||||||
|
r = _alloc_striped(lv, pvms);
|
||||||
|
|
||||||
|
else if (status & ALLOC_CONTIGUOUS)
|
||||||
|
r = _alloc_contiguous(lv, pvms);
|
||||||
|
|
||||||
|
else
|
||||||
|
r = _alloc_simple(lv, pvms);
|
||||||
|
|
||||||
|
if (!r) {
|
||||||
|
log_err("Extent allocation failed.");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_add(&ll->list, &vg->lvs);
|
||||||
|
vg->lv_count++;
|
||||||
|
vg->free_count -= extents;
|
||||||
|
|
||||||
|
pool_destroy(scratch);
|
||||||
|
return lv;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
if (ll)
|
||||||
|
pool_free(ios->mem, ll);
|
||||||
|
|
||||||
|
pool_destroy(scratch);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -217,7 +217,7 @@ struct logical_volume *lv_create(struct io_space *ios,
|
|||||||
uint32_t status,
|
uint32_t status,
|
||||||
uint32_t stripes,
|
uint32_t stripes,
|
||||||
uint32_t stripe_size,
|
uint32_t stripe_size,
|
||||||
uint64_t extents,
|
uint32_t extents,
|
||||||
struct volume_group *vg,
|
struct volume_group *vg,
|
||||||
struct pv_list *acceptable_pvs);
|
struct pv_list *acceptable_pvs);
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ static int _create_single_area(struct pool *mem, struct pv_map *pvm,
|
|||||||
pva->start = b;
|
pva->start = b;
|
||||||
pva->count = e - b;
|
pva->count = e - b;
|
||||||
list_add(&pvm->areas, &pva->list);
|
list_add(&pvm->areas, &pva->list);
|
||||||
|
*extent = e;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user