mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
o code for building free area lists on a pv. Compiles but not run.
This commit is contained in:
parent
80f9662b05
commit
242019fdf4
@ -29,6 +29,7 @@ SOURCES=\
|
||||
format1/vg_number.c \
|
||||
log/log.c \
|
||||
metadata/metadata.c \
|
||||
metadata/pv_map.c \
|
||||
mm/dbg_malloc.c \
|
||||
mm/pool.c \
|
||||
regex/matcher.c \
|
||||
|
@ -33,7 +33,7 @@
|
||||
#define CLUSTERED 0x00000400 /* VG */
|
||||
#define SHARED 0x00000800 /* VG */
|
||||
|
||||
#define ALLOC_STRICT 0x00001000 /* LV */
|
||||
#define ALLOC_STRICT 0x00001000 /* LV */
|
||||
#define ALLOC_CONTIGUOUS 0x00002000 /* LV */
|
||||
#define SNAPSHOT 0x00004000 /* LV */
|
||||
#define SNAPSHOT_ORG 0x00008000 /* LV */
|
||||
@ -208,10 +208,17 @@ struct volume_group *vg_create(struct io_space *ios, const char *name,
|
||||
int pv_count, char **pv_names);
|
||||
struct physical_volume *pv_create(struct io_space *ios, const char *name);
|
||||
|
||||
struct logical_volume *lv_create(struct io_space *ios, const char *name,
|
||||
uint32_t status, int stripes,
|
||||
uint64_t extents, char **pv_names);
|
||||
|
||||
/*
|
||||
* This will insert the new lv into the
|
||||
* volume_group.
|
||||
*/
|
||||
struct logical_volume *lv_create(struct io_space *ios,
|
||||
const char *name,
|
||||
uint32_t status,
|
||||
uint32_t stripes,
|
||||
uint32_t stripe_size,
|
||||
struct volume_group *vg,
|
||||
struct pv_list *acceptable_pvs);
|
||||
|
||||
int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count,
|
||||
char **pv_names);
|
||||
|
171
lib/metadata/pv_map.c
Normal file
171
lib/metadata/pv_map.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#include "pv_map.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
static int _create_maps(struct pool *mem, struct volume_group *vg,
|
||||
struct list *maps)
|
||||
{
|
||||
struct list *tmp;
|
||||
struct physical_volume *pv;
|
||||
struct pv_map *pvm;
|
||||
|
||||
list_iterate(tmp, &vg->pvs) {
|
||||
pv = &(list_item(tmp, struct pv_list)->pv);
|
||||
|
||||
if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pvm->pv = pv;
|
||||
if (!(pvm->allocated_extents =
|
||||
bitset_create(mem, pv->pe_count))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(maps, &pvm->list);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _fill_bitsets(struct volume_group *vg, struct list *maps)
|
||||
{
|
||||
/*
|
||||
* FIXME: should put pvm's in a table for
|
||||
* O(1) access, and remove the nasty inner
|
||||
* loop in this code.
|
||||
*/
|
||||
struct list *lvh, *pvmh;
|
||||
struct logical_volume *lv;
|
||||
struct pe_specifier *pes;
|
||||
struct pv_map *pvm;
|
||||
uint32_t le;
|
||||
|
||||
list_iterate(lvh, &vg->lvs) {
|
||||
lv = &(list_item(lvh, struct lv_list)->lv);
|
||||
|
||||
for (le = 0; le < lv->le_count; le++) {
|
||||
pes = lv->map + le;
|
||||
|
||||
/* this is the nasty that will kill performance */
|
||||
list_iterate(pvmh, maps) {
|
||||
pvm = list_item(pvmh, struct pv_map);
|
||||
|
||||
if (pvm->pv == pes->pv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pvmh == maps) {
|
||||
log_err("couldn't find pv specified "
|
||||
"in extent map !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bit_set(pvm->allocated_extents, pes->pe);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_single_area(struct pool *mem, struct pv_map *pvm,
|
||||
uint32_t *extent)
|
||||
{
|
||||
uint32_t e = *extent, b, count = pvm->pv->pe_count;
|
||||
struct pv_area *pva;
|
||||
|
||||
while (e < count && bit(pvm->allocated_extents, e))
|
||||
e++;
|
||||
|
||||
if (e == count) {
|
||||
*extent = e;
|
||||
return 1;
|
||||
}
|
||||
|
||||
b = e++;
|
||||
|
||||
while (e < count && !bit(pvm->allocated_extents, e))
|
||||
e++;
|
||||
|
||||
if (!(pva = pool_zalloc(mem, sizeof(*pva)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pva->start = b;
|
||||
pva->count = e - b;
|
||||
list_add(&pvm->areas, &pva->list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_areas(struct pool *mem, struct pv_map *pvm)
|
||||
{
|
||||
uint32_t pe = 0;
|
||||
|
||||
while (pe < pvm->pv->pe_count)
|
||||
if (!_create_single_area(mem, pvm, &pe)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_all_areas(struct pool *mem, struct list *maps)
|
||||
{
|
||||
struct list *tmp;
|
||||
struct pv_map *pvm;
|
||||
|
||||
list_iterate(tmp, maps) {
|
||||
pvm = list_item(tmp, struct pv_map);
|
||||
|
||||
if (!_create_areas(mem, pvm)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct list *create_pv_maps(struct pool *mem, struct volume_group *vg)
|
||||
{
|
||||
struct list *maps = pool_zalloc(mem, sizeof(*maps));
|
||||
|
||||
if (!maps) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_init(maps);
|
||||
|
||||
if (!_create_maps(mem, vg, maps)) {
|
||||
log_err("couldn't create pv maps.");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_fill_bitsets(vg, maps)) {
|
||||
log_err("couldn't fill extent allocation bitmaps.");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_create_all_areas(mem, maps)) {
|
||||
log_err("couldn't create area maps.");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
return maps;
|
||||
|
||||
bad:
|
||||
pool_free(mem, maps);
|
||||
return NULL;
|
||||
}
|
39
lib/metadata/pv_map.h
Normal file
39
lib/metadata/pv_map.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#ifndef _LVM_PV_MAP_H
|
||||
#define _LVM_PV_MAP_H
|
||||
|
||||
#include "metadata.h"
|
||||
#include "bitset.h"
|
||||
#include "pool.h"
|
||||
|
||||
/*
|
||||
* The in core rep. only stores a mapping from
|
||||
* logical extents to physical extents against an
|
||||
* lv. Sometimes, when allocating a new lv for
|
||||
* instance, it is useful to have the inverse
|
||||
* mapping available.
|
||||
*/
|
||||
|
||||
struct pv_area {
|
||||
uint32_t start;
|
||||
uint32_t count;
|
||||
|
||||
struct list list;
|
||||
};
|
||||
|
||||
struct pv_map {
|
||||
struct physical_volume *pv;
|
||||
bitset_t allocated_extents;
|
||||
struct list areas;
|
||||
|
||||
struct list list;
|
||||
};
|
||||
|
||||
struct list *create_pv_maps(struct pool *mem, struct volume_group *vg);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user