Module Name: src Committed By: christos Date: Wed Dec 2 20:01:44 UTC 2015
Modified Files: src/sbin/gpt: gpt.c map.c map.h resize.c Log Message: - check errors from map allocation - make map_resize return -1 instead of 0, and handle errors locally explaining what's going wrong To generate a diff of this commit: cvs rdiff -u -r1.56 -r1.57 src/sbin/gpt/gpt.c cvs rdiff -u -r1.11 -r1.12 src/sbin/gpt/map.c cvs rdiff -u -r1.4 -r1.5 src/sbin/gpt/map.h cvs rdiff -u -r1.17 -r1.18 src/sbin/gpt/resize.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.56 src/sbin/gpt/gpt.c:1.57 --- src/sbin/gpt/gpt.c:1.56 Wed Dec 2 07:20:52 2015 +++ src/sbin/gpt/gpt.c Wed Dec 2 15:01:44 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.56 2015/12/02 12:20:52 christos Exp $"); +__RCSID("$NetBSD: gpt.c,v 1.57 2015/12/02 20:01:44 christos Exp $"); #endif #include <sys/param.h> @@ -547,7 +547,8 @@ gpt_open(const char *dev, int flags, int (uintmax_t)gpt->mediasz, gpt->secsz, (uintmax_t)devsz); } - map_init(gpt, devsz); + if (map_init(gpt, devsz) == -1) + goto close; if (gpt_mbr(gpt, 0LL) == -1) goto close; Index: src/sbin/gpt/map.c diff -u src/sbin/gpt/map.c:1.11 src/sbin/gpt/map.c:1.12 --- src/sbin/gpt/map.c:1.11 Tue Dec 1 04:05:33 2015 +++ src/sbin/gpt/map.c Wed Dec 2 15:01:44 2015 @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/map.c,v 1.6 2005/08/31 01:47:19 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: map.c,v 1.11 2015/12/01 09:05:33 christos Exp $"); +__RCSID("$NetBSD: map.c,v 1.12 2015/12/02 20:01:44 christos Exp $"); #endif #include <sys/types.h> @@ -52,14 +52,14 @@ mkmap(off_t start, off_t size, int type) m = calloc(1, sizeof(*m)); if (m == NULL) - return (NULL); + return NULL; m->map_start = start; m->map_size = size; m->map_next = m->map_prev = NULL; m->map_type = type; m->map_index = 0; m->map_data = NULL; - return (m); + return m; } static const char *maptypes[] = { @@ -101,13 +101,13 @@ map_add(gpt_t gpt, off_t start, off_t si if (n == NULL) { if (!(gpt->flags & GPT_QUIET)) gpt_warnx(gpt, "Can't find map"); - return (NULL); + return NULL; } if (n->map_start + n->map_size < start + size) { if (!(gpt->flags & GPT_QUIET)) gpt_warnx(gpt, "map entry doesn't fit media"); - return (NULL); + return NULL; } if (n->map_start == start && n->map_size == size) { @@ -115,13 +115,14 @@ map_add(gpt_t gpt, off_t start, off_t si if (n->map_type != MAP_TYPE_MBR_PART || type != MAP_TYPE_GPT_PART) { if (!(gpt->flags & GPT_QUIET)) - gpt_warnx(gpt, "partition(%ju,%ju) mirrored", + gpt_warnx(gpt, + "partition(%ju,%ju) mirrored", (uintmax_t)start, (uintmax_t)size); } } n->map_type = type; n->map_data = data; - return (n); + return n; } if (n->map_type != MAP_TYPE_UNUSED) { @@ -129,14 +130,14 @@ map_add(gpt_t gpt, off_t start, off_t si type != MAP_TYPE_GPT_PART) { gpt_warnx(gpt, "bogus map current=%s new=%s", map_type(n->map_type), map_type(type)); - return (NULL); + return NULL; } n->map_type = MAP_TYPE_UNUSED; } m = mkmap(start, size, type); if (m == NULL) - return (NULL); + goto oomem; m->map_data = data; @@ -160,6 +161,8 @@ map_add(gpt_t gpt, off_t start, off_t si p->map_size -= size; } else { p = mkmap(n->map_start, start - n->map_start, n->map_type); + if (p == NULL) + goto oomem; n->map_start += p->map_size + m->map_size; n->map_size -= (p->map_size + m->map_size); p->map_prev = n->map_prev; @@ -173,7 +176,10 @@ map_add(gpt_t gpt, off_t start, off_t si gpt->mediamap = p; } - return (m); + return m; +oomem: + gpt_warn(gpt, "Can't create map"); + return NULL; } map_t @@ -193,7 +199,7 @@ map_alloc(gpt_t gpt, off_t start, off_t if (m->map_type != MAP_TYPE_UNUSED || m->map_start < 2) continue; if (start != 0 && m->map_start > start) - return (NULL); + return NULL; if (start != 0) delta = start - m->map_start; @@ -232,12 +238,20 @@ map_resize(gpt_t gpt, map_t m, off_t siz if (size < 0 || alignment < 0) { gpt_warnx(gpt, "negative size or alignment"); - return 0; + return -1; } - if (size == 0 && alignment == 0) { - if (n == NULL || n->map_type != MAP_TYPE_UNUSED) - return 0; - else { + /* Size == 0 means delete, if the next map is unused */ + if (size == 0) { + if (n == NULL) { + // XXX: we could just turn the map to UNUSED! + gpt_warnx(gpt, "Can't delete, next map is not found"); + return -1; + } + if (n->map_type != MAP_TYPE_UNUSED) { + gpt_warnx(gpt, "Can't delete, next map is in use"); + return -1; + } + if (alignment == 0) { size = m->map_size + n->map_size; m->map_size = size; m->map_next = n->map_next; @@ -247,18 +261,15 @@ map_resize(gpt_t gpt, map_t m, off_t siz free(n->map_data); free(n); return size; - } - } - - if (size == 0 && alignment > 0) { - if (n == NULL || n->map_type != MAP_TYPE_UNUSED) - return 0; - else { + } else { /* alignment > 0 */ prevsize = m->map_size; - size = (m->map_size + n->map_size) / - alignment * alignment; - if (size <= prevsize) - return 0; + size = ((m->map_size + n->map_size) / alignment) + * alignment; + if (size <= prevsize) { + gpt_warnx(gpt, "Can't coalesce %ju <= %ju", + (uintmax_t)prevsize, (uintmax_t)size); + return -1; + } m->map_size = size; n->map_start += size - prevsize; n->map_size -= size - prevsize; @@ -284,6 +295,10 @@ map_resize(gpt_t gpt, map_t m, off_t siz if (n == NULL || n->map_type != MAP_TYPE_UNUSED) { o = mkmap(m->map_start + alignsize, prevsize - alignsize, MAP_TYPE_UNUSED); + if (o == NULL) { + gpt_warn(gpt, "Can't create map"); + return -1; + } m->map_next = o; o->map_prev = m; o->map_next = n; @@ -296,9 +311,20 @@ map_resize(gpt_t gpt, map_t m, off_t siz return alignsize; } } else if (alignsize > m->map_size) { /* expanding */ - if (n == NULL || n->map_type != MAP_TYPE_UNUSED || - n->map_size < alignsize - m->map_size) { - return 0; + if (n == NULL) { + gpt_warnx(gpt, "Can't expand map, no space after it"); + return -1; + } + if (n->map_type != MAP_TYPE_UNUSED) { + gpt_warnx(gpt, + "Can't expand map, next map after it in use"); + return -1; + } + if (n->map_size < alignsize - m->map_size) { + gpt_warnx(gpt, + "Can't expand map, not enough space in the" + " next map after it"); + return -1; } n->map_size -= alignsize - m->map_size; n->map_start += alignsize - m->map_size; @@ -324,7 +350,7 @@ map_find(gpt_t gpt, int type) m = gpt->mediamap; while (m != NULL && m->map_type != type) m = m->map_next; - return (m); + return m; } map_t @@ -341,7 +367,7 @@ map_last(gpt_t gpt) m = gpt->mediamap; while (m != NULL && m->map_next != NULL) m = m->map_next; - return (m); + return m; } off_t @@ -354,19 +380,24 @@ map_free(gpt_t gpt, off_t start, off_t s while (m != NULL && m->map_start + m->map_size <= start) m = m->map_next; if (m == NULL || m->map_type != MAP_TYPE_UNUSED) - return (0LL); + return 0LL; if (size) - return ((m->map_start + m->map_size >= start + size) ? 1 : 0); - return (m->map_size - (start - m->map_start)); + return (m->map_start + m->map_size >= start + size) ? 1 : 0; + return m->map_size - (start - m->map_start); } -void +int map_init(gpt_t gpt, off_t size) { char buf[32]; gpt->mediamap = mkmap(0LL, size, MAP_TYPE_UNUSED); + if (gpt->mediamap == NULL) { + gpt_warn(gpt, "Can't create map"); + return -1; + } gpt->lbawidth = snprintf(buf, sizeof(buf), "%ju", (uintmax_t)size); if (gpt->lbawidth < 5) gpt->lbawidth = 5; + return 0; } Index: src/sbin/gpt/map.h diff -u src/sbin/gpt/map.h:1.4 src/sbin/gpt/map.h:1.5 --- src/sbin/gpt/map.h:1.4 Tue Dec 1 04:05:33 2015 +++ src/sbin/gpt/map.h Wed Dec 2 15:01:44 2015 @@ -57,6 +57,6 @@ struct map *map_first(struct gpt *); struct map *map_last(struct gpt *); off_t map_resize(struct gpt *, struct map *, off_t, off_t); off_t map_free(struct gpt *, off_t, off_t); -void map_init(struct gpt *, off_t); +int map_init(struct gpt *, off_t); #endif /* _MAP_H_ */ Index: src/sbin/gpt/resize.c diff -u src/sbin/gpt/resize.c:1.17 src/sbin/gpt/resize.c:1.18 --- src/sbin/gpt/resize.c:1.17 Tue Dec 1 14:25:24 2015 +++ src/sbin/gpt/resize.c Wed Dec 2 15:01:44 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: resize.c,v 1.17 2015/12/01 19:25:24 christos Exp $"); +__RCSID("$NetBSD: resize.c,v 1.18 2015/12/02 20:01:44 christos Exp $"); #endif #include <sys/types.h> @@ -110,14 +110,8 @@ resize(gpt_t gpt) } newsize = map_resize(gpt, map, sectors, alignsecs); - if (newsize == 0 && alignment > 0) { - gpt_warnx(gpt, "Could not resize partition with alignment " - "constraint"); + if (newsize == -1) return -1; - } else if (newsize == 0) { - gpt_warnx(gpt, "Could not resize partition"); - return -1; - } ent->ent_lba_end = htole64(map->map_start + newsize - 1LL);