diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h index e96691dcc..5ad2ed03e 100644 --- a/lib/format1/disk-rep.h +++ b/lib/format1/disk-rep.h @@ -156,7 +156,7 @@ struct disk_list { * Layout constants. */ #define METADATA_ALIGN 4096UL -#define PE_ALIGN 65536UL +#define PE_ALIGN (65536UL / SECTOR_SIZE) #define METADATA_BASE 0UL #define PV_SIZE 1024UL @@ -167,6 +167,7 @@ struct disk_list { * Functions to calculate layout info. */ int calculate_layout(struct disk_list *dl); +int calculate_extent_count(struct physical_volume *pv); /* diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 186caf691..2eb2f4aff 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -308,7 +308,32 @@ static struct list_head *_get_vgs(struct io_space *is) static int _pv_setup(struct io_space *is, struct physical_volume *pv, struct volume_group *vg) { - log_err("format1:pv_setup not implemented."); + if (!(pv->vg_name = pool_strdup(is->mem, vg->name))) { + stack; + return 0; + } + + pv->exported = NULL; + + pv->status = ACTIVE; + + if (!dev_get_size(pv->dev, &pv->size)) { + stack; + return 0; + } + + pv->pe_size = vg->extent_size; + + /* + * This works out pe_start and pe_count. + */ + if (!calculate_extent_count(pv)) { + stack; + return 0; + } + + pv->pe_allocated = 0; + return 1; } diff --git a/lib/format1/layout.c b/lib/format1/layout.c index 7a48a05e3..7c40bda89 100644 --- a/lib/format1/layout.c +++ b/lib/format1/layout.c @@ -6,6 +6,7 @@ #include "disk-rep.h" #include "log.h" +#include "dbg_malloc.h" /* @@ -45,14 +46,8 @@ static int _adjust_pe_on_disk(struct pv_disk *pvd) return 1; } -/* - * This assumes pe_count and pe_start have already - * been calculated correctly. - */ -int calculate_layout(struct disk_list *dl) +static void _calc_simple_layout(struct pv_disk *pvd) { - struct pv_disk *pvd = &dl->pv; - pvd->pv_on_disk.base = METADATA_BASE; pvd->pv_on_disk.size = PV_SIZE; @@ -67,7 +62,17 @@ int calculate_layout(struct disk_list *dl) pvd->pe_on_disk.base = _next_base(&pvd->lv_on_disk); pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk); +} +/* + * This assumes pe_count and pe_start have already + * been calculated correctly. + */ +int calculate_layout(struct disk_list *dl) +{ + struct pv_disk *pvd = &dl->pv; + + _calc_simple_layout(pvd); if (!_adjust_pe_on_disk(pvd)) { log_err("insufficient space for metadata and PE's."); return 0; @@ -77,3 +82,42 @@ int calculate_layout(struct disk_list *dl) } +/* + * It may seem strange to have a struct + * physical_volume in here, but the number of + * extents that can fit on a disk *is* metadata + * format dependant. + */ +int calculate_extent_count(struct physical_volume *pv) +{ + struct pv_disk *pvd = dbg_malloc(sizeof(*pvd)); + uint32_t end; + + if (!pvd) { + stack; + return 0; + } + + /* + * Guess how many extents will fit, + * bearing in mind that one is going to be + * knocked off at the start of the next + * loop. + */ + pvd->pe_total = (pv->size / pv->pe_size); + + do { + pvd->pe_total--; + _calc_simple_layout(pvd); + end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size) / + SECTOR_SIZE); + + pvd->pe_start = _round_up(end, PE_ALIGN); + + } while((pvd->pe_start + (pvd->pe_total * pv->pe_size)) > pv->size); + + pv->pe_count = pvd->pe_total; + pv->pe_start = pvd->pe_start; + dbg_free(pvd); + return 1; +} diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index bd83724d7..c31c80713 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -140,8 +140,9 @@ struct io_space { const char *pv_name); /* - * fill out a pv ready for importing into - * a vg. + * Fill out a pv ready for importing into + * a vg. *Be careful*, this allocates + * vg_name from is->mem. */ int (*pv_setup)(struct io_space *is, struct physical_volume *pv, struct volume_group *vg);