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);
 }

Reply via email to