Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/gpt - check errors from map allocation



details:   https://anonhg.NetBSD.org/src/rev/391927cfc10e
branches:  trunk
changeset: 812152:391927cfc10e
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Dec 02 20:01:44 2015 +0000

description:
- check errors from map allocation
- make map_resize return -1 instead of 0, and handle errors locally
  explaining what's going wrong

diffstat:

 sbin/gpt/gpt.c    |    5 +-
 sbin/gpt/map.c    |  103 +++++++++++++++++++++++++++++++++++------------------
 sbin/gpt/map.h    |    2 +-
 sbin/gpt/resize.c |   10 +----
 4 files changed, 73 insertions(+), 47 deletions(-)

diffs (truncated from 305 to 300 lines):

diff -r 9fa8ab6b3071 -r 391927cfc10e sbin/gpt/gpt.c
--- a/sbin/gpt/gpt.c    Wed Dec 02 18:09:53 2015 +0000
+++ b/sbin/gpt/gpt.c    Wed Dec 02 20:01:44 2015 +0000
@@ -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 @@
                    (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;
diff -r 9fa8ab6b3071 -r 391927cfc10e sbin/gpt/map.c
--- a/sbin/gpt/map.c    Wed Dec 02 18:09:53 2015 +0000
+++ b/sbin/gpt/map.c    Wed Dec 02 20:01:44 2015 +0000
@@ -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 @@
 
        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 @@
        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 @@
                        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 @@
                    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 @@
                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 @@
                        gpt->mediamap = p;
        }
 
-       return (m);
+       return m;
+oomem:
+       gpt_warn(gpt, "Can't create map");
+       return NULL;
 }
 
 map_t
@@ -193,7 +199,7 @@
                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 @@
 
        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 @@
                                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 @@
                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 @@
                        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 @@
        m = gpt->mediamap;
        while (m != NULL && m->map_type != type)
                m = m->map_next;
-       return (m);
+       return m;
 }
 
 map_t
@@ -341,7 +367,7 @@
        m = gpt->mediamap;
        while (m != NULL && m->map_next != NULL)
                m = m->map_next;
-       return (m);
+       return m;
 }
 
 off_t
@@ -354,19 +380,24 @@
        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;
 }
diff -r 9fa8ab6b3071 -r 391927cfc10e sbin/gpt/map.h
--- a/sbin/gpt/map.h    Wed Dec 02 18:09:53 2015 +0000
+++ b/sbin/gpt/map.h    Wed Dec 02 20:01:44 2015 +0000
@@ -57,6 +57,6 @@
 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_ */
diff -r 9fa8ab6b3071 -r 391927cfc10e sbin/gpt/resize.c
--- a/sbin/gpt/resize.c Wed Dec 02 18:09:53 2015 +0000
+++ b/sbin/gpt/resize.c Wed Dec 02 20:01:44 2015 +0000
@@ -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 @@
                }
 
        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");



Home | Main Index | Thread Index | Old Index