mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-30 17:18:21 +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 \
|
format1/vg_number.c \
|
||||||
log/log.c \
|
log/log.c \
|
||||||
metadata/metadata.c \
|
metadata/metadata.c \
|
||||||
|
metadata/pv_map.c \
|
||||||
mm/dbg_malloc.c \
|
mm/dbg_malloc.c \
|
||||||
mm/pool.c \
|
mm/pool.c \
|
||||||
regex/matcher.c \
|
regex/matcher.c \
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#define CLUSTERED 0x00000400 /* VG */
|
#define CLUSTERED 0x00000400 /* VG */
|
||||||
#define SHARED 0x00000800 /* VG */
|
#define SHARED 0x00000800 /* VG */
|
||||||
|
|
||||||
#define ALLOC_STRICT 0x00001000 /* LV */
|
#define ALLOC_STRICT 0x00001000 /* LV */
|
||||||
#define ALLOC_CONTIGUOUS 0x00002000 /* LV */
|
#define ALLOC_CONTIGUOUS 0x00002000 /* LV */
|
||||||
#define SNAPSHOT 0x00004000 /* LV */
|
#define SNAPSHOT 0x00004000 /* LV */
|
||||||
#define SNAPSHOT_ORG 0x00008000 /* 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);
|
int pv_count, char **pv_names);
|
||||||
struct physical_volume *pv_create(struct io_space *ios, const char *name);
|
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,
|
* This will insert the new lv into the
|
||||||
uint64_t extents, char **pv_names);
|
* 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,
|
int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count,
|
||||||
char **pv_names);
|
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