From f7baa67a0a3dec66e3c5735c2872059eff1d9ddb Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Fri, 15 Feb 2002 01:26:16 +0000 Subject: [PATCH] First cut on "pvcreate -s" --- lib/format1/disk-rep.h | 1 + lib/format1/format1.c | 6 ++++++ lib/metadata/lv_manip.c | 6 +++--- lib/metadata/metadata.c | 13 +++++++++++-- lib/metadata/metadata.h | 4 +++- tools/args.h | 1 + tools/commands.h | 3 ++- tools/lvresize.c | 7 +++++-- tools/pvcreate.c | 5 ++++- 9 files changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h index 63390708d..66d688460 100644 --- a/lib/format1/disk-rep.h +++ b/lib/format1/disk-rep.h @@ -18,6 +18,7 @@ #define MAX_LV 256 #define MAX_VG 99 +#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */ #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 */ diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 12b739ed6..27080aedd 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -394,6 +394,12 @@ static struct list *_get_vgs(struct format_instance *fi) static int _pv_setup(struct format_instance *fi, struct physical_volume *pv, struct volume_group *vg) { + if (pv->size == MAX_PV_SIZE) pv->size--; + if (pv->size > MAX_PV_SIZE) { + log_error("physical volumes cannot be bigger than 2TB"); + return 0; + } + /* * This works out pe_start and pe_count. */ diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index c2ce36438..4ab4d466d 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -426,7 +426,7 @@ struct logical_volume *lv_create(struct format_instance *fi, lv->status = status; lv->read_ahead = 0; lv->minor = -1; - lv->size = extents * vg->extent_size; + lv->size = (uint64_t) extents * vg->extent_size; lv->le_count = extents; lv->vg = vg; list_init(&lv->segments); @@ -480,7 +480,7 @@ int lv_reduce(struct format_instance *fi, } lv->le_count -= extents; - lv->size = lv->le_count * lv->vg->extent_size; + lv->size = (uint64_t) lv->le_count * lv->vg->extent_size; if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) { stack; @@ -500,7 +500,7 @@ int lv_extend(struct format_instance *fi, uint64_t old_size = lv->size; lv->le_count += extents; - lv->size += extents * lv->vg->extent_size; + lv->size += (uint64_t) extents * lv->vg->extent_size; /* FIXME: Format1 must ensure stripes is consistent with 1st seg */ diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index f8a641dec..fd91509c7 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -46,10 +46,12 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg, } /* 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; @@ -192,7 +194,8 @@ struct volume_group *vg_create(struct format_instance *fi, const char *vg_name, struct physical_volume *pv_create(struct format_instance *fi, const char *name, - struct id *id) + struct id *id, + uint64_t size) { struct pool *mem = fi->cmd->mem; struct physical_volume *pv = pool_alloc(mem, sizeof (*pv)); @@ -220,7 +223,13 @@ struct physical_volume *pv_create(struct format_instance *fi, *pv->vg_name = 0; pv->status = ALLOCATABLE_PV; - if (!dev_get_size(pv->dev, &pv->size)) { + if (size) { + if (size < PV_MIN_SIZE) { + log_err("Given size for '%s' is too small", name); + goto bad; + } + pv->size = size; + } else if (!dev_get_size(pv->dev, &pv->size)) { log_err("Couldn't get size of device '%s'", name); goto bad; } diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 8cf6cd04e..ff56b42b9 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -22,6 +22,7 @@ #define STRIPE_SIZE_DEFAULT 16 /* 16KB */ #define STRIPE_SIZE_MIN ( PAGE_SIZE/SECTOR_SIZE) /* PAGESIZE in sectors */ #define STRIPE_SIZE_MAX ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */ +#define PV_MIN_SIZE ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */ /* Various flags */ @@ -245,7 +246,8 @@ struct format_handler { */ struct physical_volume *pv_create(struct format_instance *fi, const char *name, - struct id *id); + struct id *id, + uint64_t size); struct volume_group *vg_create(struct format_instance *fi, const char *name, uint32_t extent_size, int max_pv, int max_lv, diff --git a/tools/args.h b/tools/args.h index a294166ab..f18e41b8b 100644 --- a/tools/args.h +++ b/tools/args.h @@ -58,6 +58,7 @@ arg(physicalvolume_ARG, 'P', "physicalvolume", NULL) arg(readahead_ARG, 'r', "readahead", int_arg) arg(reset_ARG, 'R', "reset", NULL) arg(physicalextentsize_ARG, 's', "physicalextentsize", size_arg) +arg(physicalvolumesize_ARG, 's', "size", size_arg) arg(stdin_ARG, 's', "stdin", NULL) arg(snapshot_ARG, 's', "snapshot", NULL) arg(short_ARG, 's', "short", NULL) diff --git a/tools/commands.h b/tools/commands.h index a5274f28d..6668e5787 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -265,13 +265,14 @@ xx(pvcreate, "\t[-f[f]|--force [--force]] " "\n" "\t[-h|--help] " "\n" "\t[-y|--yes]" "\n" + "\t[-s|--size PhysicalVolumeSize[kKmMgGtT]" "\n" "\t[-t|--test] " "\n" "\t[-u|--uuid uuid] " "\n" "\t[-v|--verbose] " "\n" "\t[--version] " "\n" "\tPhysicalVolume [PhysicalVolume...]\n", - force_ARG, test_ARG, uuidstr_ARG, yes_ARG) + force_ARG, test_ARG, physicalvolumesize_ARG, uuidstr_ARG, yes_ARG) xx(pvdata, "Display the on-disk metadata for physical volume(s)", diff --git a/tools/lvresize.c b/tools/lvresize.c index a313164fb..6486a3870 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -279,7 +279,8 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) if (lv_active(lv) > 0) { dummy = - display_size(extents * vg->extent_size / 2, + display_size((unsigned long long) + extents * (vg->extent_size / 2), SIZE_SHORT); log_print("WARNING: Reducing active%s logical volume " "to %s", lv_open_count(lv) ? " and open" : "", @@ -320,7 +321,9 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) /* Use full list from VG */ pvh = &vg->pvs; } - dummy = display_size(extents * vg->extent_size / 2, SIZE_SHORT); + dummy = display_size((unsigned long long) + extents * (vg->extent_size / 2), + SIZE_SHORT); log_print("Extending logical volume %s to %s", lv_name, dummy); dbg_free(dummy); diff --git a/tools/pvcreate.c b/tools/pvcreate.c index 1d8c5d1ec..c2287ad2b 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -74,6 +74,7 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) struct physical_volume *pv; struct id id, *idp = NULL; char *uuid; + uint64_t size = 0; struct device *dev; if (arg_count(cmd, uuidstr_ARG)) { @@ -91,7 +92,9 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) if (!pvcreate_check(cmd, pv_name)) return; - if (!(pv = pv_create(cmd->fid, pv_name, idp))) { + size = arg_int_value(cmd, physicalvolumesize_ARG, 0) * 2; +printf("%Ld\n", size); + if (!(pv = pv_create(cmd->fid, pv_name, idp, size))) { log_err("Failed to setup physical volume \"%s\"", pv_name); return; }