diff --git a/lib/Makefile.in b/lib/Makefile.in index 0fb07dbff..89802ae45 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -14,6 +14,7 @@ SOURCES=\ device/dev-cache.c \ device/dev-io.c \ device/device.c \ + display/display.c \ filters/filter.c \ format1/disk-rep.c \ format1/format1.c \ diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h index 528c08220..0f7589d02 100644 --- a/lib/format1/disk-rep.h +++ b/lib/format1/disk-rep.h @@ -18,6 +18,10 @@ #define MAX_LV 256 #define MAX_VG 99 +#define MIN_PE_SIZE ( 8192L / SECTOR_SIZE) /* 8 KB in sectors */ +#define MAX_PE_SIZE ( 16L * 1024L * 1024L / SECTOR_SIZE * 1024) +#define PE_SIZE_PV_SIZE_REL 5 /* PV size must be at least 5 times PE size */ + #define UNMAPPED_EXTENT 0 /* volume group */ diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 1f3afe729..422e86dc7 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -10,6 +10,7 @@ #include "hash.h" #include "list.h" #include "log.h" +#include "display.h" static int _check_vgs(struct list_head *pvs) { @@ -388,6 +389,32 @@ int _vg_setup(struct io_space *is, struct volume_group *vg) if (vg->max_pv >= MAX_PV) vg->max_pv = MAX_PV - 1; + if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) { + char *dummy, *dummy2; + + log_error("Extent size must be between %s and %s", + (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT)), + (dummy2 = display_size(MAX_PE_SIZE / 2, SIZE_SHORT))); + + dbg_free(dummy); + dbg_free(dummy2); + return 0; + } + + if (vg->extent_size % MIN_PE_SIZE) { + char *dummy; + log_error("Extent size must be multiple of %s", + (dummy = display_size(MIN_PE_SIZE / 2, SIZE_SHORT))); + dbg_free(dummy); + return 0; + } + + /* Redundant? */ + if (vg->extent_size & (vg->extent_size - 1)) { + log_error("Extent size must be power of 2"); + return 0; + } + return 1; } diff --git a/lib/format1/layout.c b/lib/format1/layout.c index 5851a0255..1168fbea6 100644 --- a/lib/format1/layout.c +++ b/lib/format1/layout.c @@ -106,6 +106,12 @@ int calculate_extent_count(struct physical_volume *pv) */ pvd->pe_total = (pv->size / pv->pe_size); + if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) { + log_error("Insufficient space for extents on %s", + pv->dev->name); + return 0; + } + do { pvd->pe_total--; _calc_simple_layout(pvd); diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index d2642e4c1..7f636c9f1 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -52,11 +52,13 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg, /* FIXME Tie this to activation or not? */ pv->status |= ACTIVE; + /* Units of 512-byte sectors */ if (!dev_get_size(pv->dev, &pv->size)) { stack; return 0; } + /* Units of 512-byte sectors */ pv->pe_size = vg->extent_size; /* @@ -69,7 +71,7 @@ int _add_pv_to_vg(struct io_space *ios, struct volume_group *vg, pv->pe_allocated = 0; if (!ios->pv_setup(ios, pv, vg)) { - log_debug("Format specific setup of physical volume '%s' " + log_debug("Format-specific setup of physical volume '%s' " "failed.", pv_name); return 0; } diff --git a/tools/vgcreate.c b/tools/vgcreate.c index 5ff143bd2..3f57e4204 100644 --- a/tools/vgcreate.c +++ b/tools/vgcreate.c @@ -9,7 +9,8 @@ /* FIXME From config file? */ #define DEFAULT_PV 255 #define DEFAULT_LV 255 -#define DEFAULT_EXTENT 8192 + +#define DEFAULT_EXTENT 4096 /* In KB */ int vgcreate(int argc, char **argv) { @@ -31,7 +32,9 @@ int vgcreate(int argc, char **argv) vg_name = argv[0]; max_lv = arg_int_value(maxlogicalvolumes_ARG, DEFAULT_LV); max_pv = arg_int_value(maxphysicalvolumes_ARG, DEFAULT_PV); - extent_size = arg_int_value(physicalextentsize_ARG, DEFAULT_EXTENT); + + /* Units of 512-byte sectors */ + extent_size = arg_int_value(physicalextentsize_ARG, DEFAULT_EXTENT) * 2; if (max_lv < 1) { log_error("maxlogicalvolumes too low");