Module Name: src Committed By: christos Date: Fri Dec 4 16:46:24 UTC 2015
Modified Files: src/sbin/gpt: gpt.c gpt.h recover.c resizedisk.c Log Message: Fix resizedisk. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sbin/gpt/gpt.c cvs rdiff -u -r1.29 -r1.30 src/sbin/gpt/gpt.h cvs rdiff -u -r1.14 -r1.15 src/sbin/gpt/recover.c cvs rdiff -u -r1.15 -r1.16 src/sbin/gpt/resizedisk.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/gpt/gpt.c diff -u src/sbin/gpt/gpt.c:1.62 src/sbin/gpt/gpt.c:1.63 --- src/sbin/gpt/gpt.c:1.62 Thu Dec 3 20:46:32 2015 +++ src/sbin/gpt/gpt.c Fri Dec 4 11:46:24 2015 @@ -35,7 +35,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: gpt.c,v 1.62 2015/12/04 01:46:32 christos Exp $"); +__RCSID("$NetBSD: gpt.c,v 1.63 2015/12/04 16:46:24 christos Exp $"); #endif #include <sys/param.h> @@ -829,16 +829,8 @@ gpt_create(gpt_t gpt, off_t last, u_int blocks--; /* Number of blocks in the GPT table. */ - if ((p = calloc(1, gpt->secsz)) == NULL) { - gpt_warnx(gpt, "Can't allocate the primary GPT"); - return -1; - } - if ((gpt->gpt = map_add(gpt, 1LL, 1LL, - MAP_TYPE_PRI_GPT_HDR, p, 1)) == NULL) { - free(p); - gpt_warnx(gpt, "Can't add the primary GPT"); + if (gpt_add_hdr(gpt, MAP_TYPE_PRI_GPT_HDR, 1) == -1) return -1; - } if ((p = calloc((size_t)blocks, gpt->secsz)) == NULL) { gpt_warnx(gpt, "Can't allocate the primary GPT table"); @@ -885,16 +877,8 @@ gpt_create(gpt_t gpt, off_t last, u_int if (primary_only) return last; - if ((p = calloc(1, gpt->secsz)) == NULL) { - gpt_warnx(gpt, "Can't allocate the secondary GPT"); + if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, last) == -1) return -1; - } - - if ((gpt->tpg = map_add(gpt, last, 1LL, - MAP_TYPE_SEC_GPT_HDR, p, 1)) == NULL) { - gpt_warnx(gpt, "Can't add the secondary GPT"); - return -1; - } if ((gpt->lbt = map_add(gpt, last - blocks, blocks, MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data, 0)) == NULL) { @@ -1202,3 +1186,38 @@ gpt_show_num(const char *prompt, uintmax #endif printf("\n"); } + +int +gpt_add_hdr(gpt_t gpt, int type, off_t loc) +{ + void *p; + map_t *t; + const char *msg; + + switch (type) { + case MAP_TYPE_PRI_GPT_HDR: + t = &gpt->gpt; + msg = "primary"; + break; + case MAP_TYPE_SEC_GPT_HDR: + t = &gpt->tpg; + msg = "secondary"; + break; + default: + gpt_warnx(gpt, "Unknown GPT header type %d", type); + return -1; + } + + if ((p = calloc(1, gpt->secsz)) == NULL) { + gpt_warn(gpt, "Error allocating %s GPT header", msg); + return -1; + } + + *t = map_add(gpt, loc, 1LL, type, p, 1); + if (*t == NULL) { + gpt_warn(gpt, "Error adding %s GPT header", msg); + free(p); + return -1; + } + return 0; +} Index: src/sbin/gpt/gpt.h diff -u src/sbin/gpt/gpt.h:1.29 src/sbin/gpt/gpt.h:1.30 --- src/sbin/gpt/gpt.h:1.29 Thu Dec 3 20:46:32 2015 +++ src/sbin/gpt/gpt.h Fri Dec 4 11:46:24 2015 @@ -125,6 +125,7 @@ int gpt_uint_get(u_int *); int gpt_human_get(off_t *); int gpt_uuid_get(gpt_t, gpt_uuid_t *); int gpt_name_get(gpt_t, void *); +int gpt_add_hdr(gpt_t, int, off_t); void gpt_show_num(const char *, uintmax_t); #endif /* _GPT_H_ */ Index: src/sbin/gpt/recover.c diff -u src/sbin/gpt/recover.c:1.14 src/sbin/gpt/recover.c:1.15 --- src/sbin/gpt/recover.c:1.14 Thu Dec 3 16:30:54 2015 +++ src/sbin/gpt/recover.c Fri Dec 4 11:46:24 2015 @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/recover.c,v 1.8 2005/08/31 01:47:19 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: recover.c,v 1.14 2015/12/03 21:30:54 christos Exp $"); +__RCSID("$NetBSD: recover.c,v 1.15 2015/12/04 16:46:24 christos Exp $"); #endif #include <sys/types.h> @@ -68,10 +68,12 @@ static int recover_gpt_hdr(gpt_t gpt, int type, off_t last) { const char *name, *origname; - void *p; map_t *dgpt, dtbl, sgpt, stbl; struct gpt_hdr *hdr; + if (gpt_add_hdr(gpt, type, last) == -1) + return -1; + switch (type) { case MAP_TYPE_PRI_GPT_HDR: dgpt = &gpt->gpt; @@ -94,14 +96,6 @@ recover_gpt_hdr(gpt_t gpt, int type, off return -1; } - if ((p = calloc(1, gpt->secsz)) == NULL) { - gpt_warn(gpt, "Cannot allocate %s GPT header", name); - return -1; - } - if ((*dgpt = map_add(gpt, last, 1LL, type, p, 1)) == NULL) { - gpt_warnx(gpt, "Cannot add %s GPT header", name); - return -1; - } memcpy((*dgpt)->map_data, sgpt->map_data, gpt->secsz); hdr = (*dgpt)->map_data; hdr->hdr_lba_self = htole64((uint64_t)(*dgpt)->map_start); Index: src/sbin/gpt/resizedisk.c diff -u src/sbin/gpt/resizedisk.c:1.15 src/sbin/gpt/resizedisk.c:1.16 --- src/sbin/gpt/resizedisk.c:1.15 Thu Dec 3 16:30:54 2015 +++ src/sbin/gpt/resizedisk.c Fri Dec 4 11:46:24 2015 @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: resizedisk.c,v 1.15 2015/12/03 21:30:54 christos Exp $"); +__RCSID("$NetBSD: resizedisk.c,v 1.16 2015/12/04 16:46:24 christos Exp $"); #endif #include <sys/bootblock.h> @@ -58,7 +58,7 @@ static const char *resizediskhelp[] = { }; struct gpt_cmd c_resizedisk = { - "resize", + "resizedisk", cmd_resizedisk, resizediskhelp, __arraycount(resizediskhelp), 0, @@ -86,14 +86,15 @@ resizedisk(gpt_t gpt, off_t sector, off_ struct mbr *mbr; off_t last, oldloc, newloc, lastdata, gpt_size; int i; - void *p; last = gpt->mediasz / gpt->secsz - 1; lastdata = 0; newloc = 0; if (sector > last) { - gpt_warnx(gpt, "specified size is larger then the disk"); + gpt_warnx(gpt, "specified number of sectors %jd" + " is larger then the disk %jd", (uintmax_t)sector, + (uintmax_t)last); return -1; } @@ -105,22 +106,39 @@ resizedisk(gpt_t gpt, off_t sector, off_ mbr = mbrmap->map_data; gpt->gpt = map_find(gpt, MAP_TYPE_PRI_GPT_HDR); - ent = NULL; if (gpt == NULL) { gpt_warnx(gpt, "No primary GPT header; run create or recover"); return -1; } + + gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL); + if (gpt->tbl == NULL) { + gpt_warnx(gpt, "No primary GPT table; Run recover"); + return -1; + } + hdr = gpt->gpt->map_data; oldloc = (off_t)le64toh((uint64_t)hdr->hdr_lba_alt); gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR); - if (gpt->tpg == NULL) - if (gpt_gpt(gpt, oldloc, 1)) - gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR); + gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL); + if (gpt->tpg == NULL || gpt->lbt == NULL) { + if (gpt_gpt(gpt, oldloc, 1) == -1) { + gpt_warnx(gpt, + "Error reading backup GPT information at %#jx", + oldloc); + return -1; + } + } - gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL); - if (gpt->tbl == NULL) { - gpt_warnx(gpt, "Run recover"); + gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR); + if (gpt->tpg == NULL) { + gpt_warnx(gpt, "No secondary GPT header; Run recover"); + return -1; + } + gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL); + if (gpt->lbt == NULL) { + gpt_warnx(gpt, "No secondary GPT table; Run recover"); return -1; } @@ -129,6 +147,7 @@ resizedisk(gpt_t gpt, off_t sector, off_ gpt_warnx(gpt, "Device is already the specified size"); return 0; } + if (sector == 0 && last == oldloc) { gpt_warnx(gpt, "Device hasn't changed size"); return 0; @@ -142,11 +161,13 @@ resizedisk(gpt_t gpt, off_t sector, off_ lastdata = (off_t)le64toh((uint64_t)ent->ent_lba_end); } } + if (sector - gpt_size <= lastdata) { gpt_warnx(gpt, "Not enough space at %" PRIu64 " for secondary GPT table", sector); return -1; } + if (last - gpt_size <= lastdata) { gpt_warnx(gpt, "Not enough space for new secondary GPT table"); return -1; @@ -158,6 +179,7 @@ resizedisk(gpt_t gpt, off_t sector, off_ newloc = sector; if (sector == 0 && last > oldloc) newloc = last; + if (newloc > 0) { if (gpt->tpg == NULL) { gpt_warnx(gpt, "No secondary GPT header; run recover"); @@ -175,16 +197,8 @@ resizedisk(gpt_t gpt, off_t sector, off_ else newloc = last; - if ((p = calloc(1, gpt->secsz)) == NULL) { - gpt_warn(gpt, "Error allocating secondary GPT header"); + if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, newloc) == -1) return -1; - } - - gpt->tpg = map_add(gpt, newloc, 1LL, MAP_TYPE_SEC_GPT_HDR, p, 1); - if (gpt->tpg == NULL) { - gpt_warn(gpt, "Error adding secondary GPT header"); - return -1; - } gpt->lbt = map_add(gpt, newloc - gpt_size, gpt_size, MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data, 0); @@ -238,7 +252,7 @@ static int cmd_resizedisk(gpt_t gpt, int argc, char *argv[]) { int ch; - off_t sector, size = 0; + off_t sector, size = gpt->mediasz; while ((ch = getopt(argc, argv, "s:")) != -1) { switch(ch) { @@ -257,5 +271,10 @@ cmd_resizedisk(gpt_t gpt, int argc, char if ((sector = gpt_check_ais(gpt, 0, (u_int)~0, size)) == -1) return -1; + if (--sector == 0) { + gpt_warnx(gpt, "New size %ju too small", (uintptr_t)size); + return -1; + } + return resizedisk(gpt, sector, size); }