]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: make it possible to use zero for size and start
authorKarel Zak <kzak@redhat.com>
Wed, 15 Oct 2014 10:17:40 +0000 (12:17 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 15 Oct 2014 10:17:40 +0000 (12:17 +0200)
The zero may be valid size and start of the partition. This patch
introduces:

fdisk_partition_has_start()
fdisk_partition_has_size()
fdisk_partition_unset_size()
fdisk_partition_unset_start()

to make it possible to work with zero. The feature is internally
implemented by magic constant ((type) -1) for undefined sizes and
offsets.

Signed-off-by: Karel Zak <kzak@redhat.com>
14 files changed:
disk-utils/cfdisk.c
disk-utils/fdisk-list.c
disk-utils/sfdisk.c
libfdisk/src/bsd.c
libfdisk/src/dos.c
libfdisk/src/fdiskP.h
libfdisk/src/gpt.c
libfdisk/src/label.c
libfdisk/src/libfdisk.h
libfdisk/src/partition.c
libfdisk/src/script.c
libfdisk/src/sgi.c
libfdisk/src/sun.c
libfdisk/src/table.c

index 1f2ad7c4921e904b20306a5a321784ae4dc4ed67..4968713111a85113880084160ae9fb280e305d36 100644 (file)
@@ -1812,7 +1812,8 @@ static int main_menu_action(struct cfdisk *cf, int key)
                struct fdisk_partition *npa;    /* the new partition */
                int expsize = 0;                /* size specified explicitly in sectors */
 
-               if (!pa || !fdisk_partition_is_freespace(pa))
+               if (!pa || !fdisk_partition_is_freespace(pa)
+                       || !fdisk_partition_has_start(pa))
                        return -EINVAL;
                npa = fdisk_new_partition();
                if (!npa)
index 46d50a7f3e03f3835f274238b3814750a14138f9..d0d752ef61db90fad94efe401cfc5cac9bbacd6f 100644 (file)
@@ -171,6 +171,8 @@ void list_disklabel(struct fdisk_context *cxt)
 
        /* print warnings */
        while (itr && fdisk_table_next_partition(tb, itr, &pa) == 0) {
+               if (!fdisk_partition_has_start(pa))
+                       continue;
                if (!fdisk_lba_is_phy_aligned(cxt, fdisk_partition_get_start(pa)))
                        fdisk_warnx(cxt, _("Partition %zu does not start on physical sector boundary."),
                                          fdisk_partition_get_partno(pa) + 1);
index 68df57c0d5fcd1122611a1f8b5e6ebf3f34bdfa0..821b5ed15d863c91d25543b7e95520e134c5b4b6 100644 (file)
@@ -1230,7 +1230,7 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
 
                        assert(pa);
 
-                       if (!fdisk_partition_get_start(pa) &&
+                       if (!fdisk_partition_has_start(pa) &&
                            !fdisk_partition_start_is_default(pa)) {
                                fdisk_info(sf->cxt, _("Ignore partition %zu"), next_partno + 1);
                                continue;
index dfc47bda08172b78eb3416305d3651bf74f9afed..c92c893bbbf259e7e7dedb0056b88ed88ef5ad95 100644 (file)
@@ -238,7 +238,7 @@ static int bsd_add_partition(struct fdisk_context *cxt,
         */
        if (pa && pa->start_follow_default)
                ;
-       else if (pa && pa->start) {
+       else if (pa && fdisk_partition_has_start(pa)) {
                if (pa->start < begin || pa->start > end)
                        return -ERANGE;
                begin = pa->start;
@@ -269,7 +269,7 @@ static int bsd_add_partition(struct fdisk_context *cxt,
         */
        if (pa && pa->end_follow_default)
                ;
-       else if (pa && pa->size) {
+       else if (pa && fdisk_partition_has_size(pa)) {
                if (begin + pa->size > end)
                        return -ERANGE;
                end = begin + pa->size - 1ULL;
@@ -335,11 +335,13 @@ static int bsd_set_partition(struct fdisk_context *cxt, size_t n,
        p = &d->d_partitions[n];
 
        /* we have to stay within parental DOS partition */
-       if (l->dos_part && (pa->start || pa->size)) {
+       if (l->dos_part && (fdisk_partition_has_start(pa) ||
+                           fdisk_partition_has_size(pa))) {
+
                sector_t dosbegin = dos_partition_get_start(l->dos_part);
                sector_t dosend = dosbegin + dos_partition_get_size(l->dos_part) - 1;
-               sector_t begin = pa->start ? pa->start : p->p_offset;
-               sector_t end = begin + (pa->size ? pa->size : p->p_size) - 1;
+               sector_t begin = fdisk_partition_has_start(pa) ? pa->start : p->p_offset;
+               sector_t end = begin + (fdisk_partition_has_size(pa) ? pa->size : p->p_size) - 1;
 
                if (begin < dosbegin || begin > dosend)
                        return -ERANGE;
@@ -353,9 +355,9 @@ static int bsd_set_partition(struct fdisk_context *cxt, size_t n,
                        return rc;
        }
 
-       if (pa->start)
+       if (fdisk_partition_has_start(pa))
                d->d_partitions[n].p_offset = pa->start;
-       if (pa->size)
+       if (fdisk_partition_has_size(pa))
                d->d_partitions[n].p_size = pa->size;
 
        fdisk_label_set_changed(cxt->label, 1);
index 0ae0615a24847913b1dc94ce4c6506001626c619..bcfacfc7d48d08b5e97e707ce36852ecacd3d355 100644 (file)
@@ -819,6 +819,8 @@ static void set_partition(struct fdisk_context *cxt,
        struct dos_partition *p;
        sector_t offset;
 
+       assert(!FDISK_IS_UNDEF(start));
+       assert(!FDISK_IS_UNDEF(stop));
 
        if (doext) {
                struct fdisk_dos_label *l = self_label(cxt);
@@ -902,7 +904,7 @@ static int get_start_from_user(     struct fdisk_context *cxt,
        if (pa && pa->start_follow_default)
                *start = dflt;
 
-       else if (pa && pa->start) {
+       else if (pa && fdisk_partition_has_start(pa)) {
                DBG(LABEL, ul_debug("DOS: start: wanted=%ju, low=%ju, limit=%ju",
                                (uintmax_t) pa->start, (uintmax_t) low, (uintmax_t) limit));
                *start = pa->start;
@@ -971,7 +973,8 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
                if (cxt->parent && fdisk_is_label(cxt->parent, GPT))
                        start = 1;              /* Bad boy modifies hybrid MBR */
                else {
-                       if (cxt->script && pa && pa->start && pa->start < cxt->first_lba
+                       if (cxt->script && pa && fdisk_partition_has_start(pa)
+                           && pa->start < cxt->first_lba
                            && pa->start >= 1)
                                fdisk_set_first_lba(cxt, 1);
 
@@ -995,7 +998,8 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
                assert(ext_pe);
                limit = get_abs_partition_end(ext_pe);
 
-               if (cxt->script && pa && pa->start && pa->start >= l->ext_offset
+               if (cxt->script && pa && fdisk_partition_has_start(pa)
+                   && pa->start >= l->ext_offset
                    && pa->start < l->ext_offset + cxt->first_lba)
                        fdisk_set_first_lba(cxt, 1);
 
@@ -1017,7 +1021,7 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
                temp = start;
                dflt = start = get_unused_start(cxt, n, start, first, last);
 
-               if (n >= 4 && pa && pa->start && cxt->script
+               if (n >= 4 && pa && fdisk_partition_has_start(pa) && cxt->script
                    && cxt->first_lba > 1
                    && temp == start - cxt->first_lba) {
                        fdisk_set_first_lba(cxt, 1);
@@ -1040,7 +1044,8 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
                                        temp);
                        temp = start;
                        read = 0;
-                       if (pa && (pa->start || pa->start_follow_default))
+                       if (pa && (fdisk_partition_has_start(pa) ||
+                                  pa->start_follow_default))
                                break;
                }
 
@@ -1091,7 +1096,7 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
                stop = limit;
        else if (pa && pa->end_follow_default)
                stop = limit;
-       else if (pa && pa->size) {
+       else if (pa && fdisk_partition_has_size(pa)) {
                stop = start + pa->size - 1;
                isrel = pa->size_explicit ? 0 : 1;
        } else {
@@ -1148,7 +1153,7 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
                }
        }
 
-       set_partition(cxt, n, 0, start, stop, sys, pa && pa->boot ? 1 : 0);
+       set_partition(cxt, n, 0, start, stop, sys, pa && pa->boot == 1 ? 1 : 0);
        if (n > 4) {
                struct pte *pe = self_pte(cxt, n);
                set_partition(cxt, n - 1, 1, pe->offset, stop,
@@ -1445,7 +1450,7 @@ static int dos_add_partition(struct fdisk_context *cxt,
         */
 
        /* pa specifies start within extended partition, add logical */
-       if (pa && pa->start && ext_pe
+       if (pa && fdisk_partition_has_start(pa) && ext_pe
            && pa->start >= l->ext_offset
            && pa->start <= get_abs_partition_end(ext_pe)) {
                DBG(LABEL, ul_debug("DOS: pa template %p: add logical", pa));
@@ -1466,7 +1471,7 @@ static int dos_add_partition(struct fdisk_context *cxt,
                }
 
        /* pa specifies start, but outside extended partition */
-       } else if (pa && pa->start && l->ext_offset) {
+       } else if (pa && fdisk_partition_has_start(pa) && l->ext_offset) {
                DBG(LABEL, ul_debug("DOS: pa template %p: add primary", pa));
                res = get_partition_unused_primary(cxt, pa);
                if (res >= 0) {
@@ -1508,7 +1513,7 @@ static int dos_add_partition(struct fdisk_context *cxt,
        if (!free_primary || !free_sectors) {
                DBG(LABEL, ul_debug("DOS: primary impossible, add logical"));
                if (l->ext_offset) {
-                       if (!pa || pa->start) {
+                       if (!pa || fdisk_partition_has_start(pa)) {
                                if (!free_primary)
                                        fdisk_info(cxt, _("All primary partitions are in use."));
                                else if (!free_sectors)
@@ -1578,15 +1583,22 @@ static int dos_add_partition(struct fdisk_context *cxt,
                } else if (c == 'e' && !l->ext_offset) {
                        res = get_partition_unused_primary(cxt, pa);
                        if (res >= 0) {
-                               struct fdisk_partition xpa = { .type = NULL };
+                               struct fdisk_partition *xpa = NULL;
                                struct fdisk_parttype *t;
 
                                t = fdisk_label_get_parttype_from_code(cxt->label,
                                                MBR_DOS_EXTENDED_PARTITION);
-                               if (!pa)
-                                       pa = &xpa;
+                               if (!pa) {
+                                       pa = xpa = fdisk_new_partition();
+                                       if (!xpa)
+                                               return -ENOMEM;
+                               }
                                fdisk_partition_set_type(pa, t);
                                rc = add_partition(cxt, res, pa);
+                               if (xpa) {
+                                       fdisk_unref_partition(xpa);
+                                       pa = NULL;
+                               }
                        }
                        goto done;
                } else
@@ -1787,14 +1799,14 @@ static int dos_get_partition(struct fdisk_context *cxt, size_t n,
                return -ENOMEM;
 
        /* start C/H/S */
-       if (asprintf(&pa->start_addr, "%d/%d/%d",
+       if (asprintf(&pa->start_chs, "%d/%d/%d",
                                cylinder(p->bs, p->bc),
                                sector(p->bs),
                                p->bh) < 0)
                return -ENOMEM;
 
        /* end C/H/S */
-       if (asprintf(&pa->end_addr, "%d/%d/%d",
+       if (asprintf(&pa->end_chs, "%d/%d/%d",
                                cylinder(p->es, p->ec),
                                sector(p->es),
                                p->eh) < 0)
@@ -1829,22 +1841,25 @@ static int dos_set_partition(struct fdisk_context *cxt, size_t n,
 
        p  = self_partition(cxt, n);
 
-       if (pa->start || pa->size) {
+       if (fdisk_partition_has_start(pa) || fdisk_partition_has_size(pa)) {
                sector_t start, size;
 
+               DBG(LABEL, ul_debug("DOS: resize partition"));
+
                pe = self_pte(cxt, n);
 
-               start = pa->start ? pa->start : get_abs_partition_start(pe);
-               size = pa->size ? pa->size : dos_partition_get_size(p);
+               start = fdisk_partition_has_start(pa) ? pa->start : get_abs_partition_start(pe);
+               size = fdisk_partition_has_size(pa) ? pa->size : dos_partition_get_size(p);
 
                set_partition(cxt, n, 0, start, start + size - 1,
                                pa->type  ? pa->type->code : p->sys_ind,
-                               pa->boot);
+                               pa->boot == 1);
 
        } else {
+               DBG(LABEL, ul_debug("DOS: keep size, modify properties"));
                if (pa->type)
                        p->sys_ind = pa->type->code;
-               if (pa->boot != FDISK_EMPTY_BOOTFLAG)
+               if (!FDISK_IS_UNDEF(pa->boot))
                        p->boot_ind = pa->boot == 1 ? ACTIVE_FLAG : 0;
        }
 
@@ -2006,6 +2021,7 @@ static int dos_reorder(struct fdisk_context *cxt)
        return 0;
 }
 
+/* TODO: use fdisk_set_partition() API */
 int fdisk_dos_move_begin(struct fdisk_context *cxt, size_t i)
 {
        struct pte *pe;
index 253c515f8b00d47637fa690c56042bd37a278641..7822466a22b0d0051dc6bf55e489b1ae3b17ab4d 100644 (file)
@@ -113,6 +113,7 @@ enum {
 
 struct fdisk_partition {
        int             refcount;               /* reference counter */
+
        size_t          partno;                 /* partition number */
        size_t          parent_partno;          /* for logical partitions */
 
@@ -136,24 +137,23 @@ struct fdisk_partition {
        uint64_t        bsize;
        uint64_t        cpg;
 
-       char            *start_addr;            /* start C/H/S in string */
-       char            *end_addr;              /* end C/H/S in string */
+       char            *start_chs;             /* start C/H/S in string */
+       char            *end_chs;               /* end C/H/S in string */
 
-       int             boot;                   /* MBR only: 1 = yes, 0 = no, -1 undefined */
+       unsigned int    boot;                   /* MBR: bootable */
 
-       unsigned int    partno_follow_default : 1,      /* use default partno */
-                       start_follow_default : 1,       /* use default start */
+       unsigned int    container : 1,                  /* container partition (e.g. extended partition) */
                        end_follow_default : 1,         /* use default end */
+                       freespace : 1,                  /* this is free space */
+                       partno_follow_default : 1,      /* use default partno */
                        size_explicit : 1,              /* don't align the size */
-                       freespace : 1,          /* this is free space */
-                       container : 1,          /* container partition (e.g. extended partition) */
-                       wholedisk : 1,          /* special system partition */
-                       used : 1;               /* partition already used */
+                       start_follow_default : 1,       /* use default start */
+                       used : 1,                       /* partition already used */
+                       wholedisk : 1;                  /* special system partition */
 };
 
-#define FDISK_EMPTY_PARTNO     ((size_t) -1)
-#define FDISK_EMPTY_PARTITION  { .partno = FDISK_EMPTY_PARTNO }
-#define FDISK_EMPTY_BOOTFLAG   (-1)
+#define FDISK_INIT_UNDEF(_x)   ((_x) = (__typeof__(_x)) -1)
+#define FDISK_IS_UNDEF(_x)     ((_x) == (__typeof__(_x)) -1)
 
 struct fdisk_table {
        struct list_head        parts;          /* partitions */
index e695bea9d37f9d84ce6b561d3603ee2b7af885c2..ec6dbd6644099a6a7898a0a24f7b22a4ea40cb80 100644 (file)
@@ -1545,13 +1545,11 @@ static int gpt_set_partition(struct fdisk_context *cxt, size_t n,
                        return rc;
        }
 
-       if (pa->start)
+       if (fdisk_partition_has_start(pa))
                e->lba_start = cpu_to_le64(pa->start);
-       if (pa->size)
+       if (fdisk_partition_has_size(pa))
                e->lba_end = cpu_to_le64(gpt_partition_start(e) + pa->size - 1ULL);
 
-       /* TODO: pa->attrs */
-
        gpt_recompute_crc(gpt->pheader, gpt->ents);
        gpt_recompute_crc(gpt->bheader, gpt->ents);
 
@@ -1954,15 +1952,16 @@ static int gpt_add_partition(
        dflt_f = fdisk_align_lba_in_range(cxt, dflt_f, dflt_f, dflt_l);
 
        /* first sector */
-       if (pa && pa->start) {
+       if (pa && pa->start_follow_default) {
+               user_f = dflt_f;
+
+       } else if (pa && fdisk_partition_has_start(pa)) {
                DBG(LABEL, ul_debug("first sector defined: %ju", pa->start));
                if (pa->start != find_first_available(pheader, ents, pa->start)) {
                        fdisk_warnx(cxt, _("Sector %ju already used."), pa->start);
                        return -ERANGE;
                }
                user_f = pa->start;
-       } else if (pa && pa->start_follow_default) {
-               user_f = dflt_f;
        } else {
                /*  ask by dialog */
                for (;;) {
@@ -1995,15 +1994,16 @@ static int gpt_add_partition(
        /* Last sector */
        dflt_l = find_last_free(pheader, ents, user_f);
 
-       if (pa && pa->size) {
+       if (pa && pa->end_follow_default) {
+               user_l = dflt_l;
+
+       } else if (pa && fdisk_partition_has_size(pa)) {
                user_l = user_f + pa->size - 1;
                DBG(LABEL, ul_debug("size defined: %ju, end: %ju (last possible: %ju)",
                                        pa->size, user_l, dflt_l));
                if (user_l != dflt_l && !pa->size_explicit)
                        user_l = fdisk_align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1;
 
-       } else if (pa && pa->end_follow_default) {
-               user_l = dflt_l;
        } else {
                for (;;) {
                        if (!ask)
@@ -2045,6 +2045,9 @@ static int gpt_add_partition(
                goto done;
        }
 
+       assert(!FDISK_IS_UNDEF(user_l));
+       assert(!FDISK_IS_UNDEF(user_f));
+
        e = &ents[partnum];
        e->lba_end = cpu_to_le64(user_l);
        e->lba_start = cpu_to_le64(user_f);
index a3a4e88123cb4c7e996c0174a4ae376fd1e48120..12ad1dc3024f5522a0297ec2d4d840c4daa38666 100644 (file)
@@ -434,10 +434,17 @@ int fdisk_set_partition_type(struct fdisk_context *cxt,
 
 
        if (cxt->label->op->set_part) {
-               struct fdisk_partition pa = { .type = t };
+               struct fdisk_partition *pa = fdisk_new_partition();
+               int rc;
+
+               if (!pa)
+                       return -ENOMEM;
+               fdisk_partition_set_type(pa, t);
 
                DBG(CXT, ul_debugobj(cxt, "partition: %zd: set type", partnum));
-               return cxt->label->op->set_part(cxt, partnum, &pa);
+               rc = cxt->label->op->set_part(cxt, partnum, pa);
+               fdisk_unref_partition(pa);
+               return rc;
        }
 
        return -ENOSYS;
index 047119983d5f982c1a5f968b2b07fc0528f34913..260f9083944f628562a379746b12927d5814724b 100644 (file)
@@ -247,16 +247,20 @@ extern void fdisk_ref_partition(struct fdisk_partition *pa);
 extern void fdisk_unref_partition(struct fdisk_partition *pa);
 extern int fdisk_partition_is_freespace(struct fdisk_partition *pa);
 
-extern int fdisk_partition_set_start(struct fdisk_partition *pa, uint64_t off);
-extern uint64_t fdisk_partition_get_start(struct fdisk_partition *pa);
-extern int fdisk_partition_cmp_start(struct fdisk_partition *a,
+int fdisk_partition_set_start(struct fdisk_partition *pa, uint64_t off);
+int fdisk_partition_unset_start(struct fdisk_partition *pa);
+uint64_t fdisk_partition_get_start(struct fdisk_partition *pa);
+int fdisk_partition_has_start(struct fdisk_partition *pa);
+int fdisk_partition_cmp_start(struct fdisk_partition *a,
                              struct fdisk_partition *b);
+int fdisk_partition_start_follow_default(struct fdisk_partition *pa, int enable);
+int fdisk_partition_start_is_default(struct fdisk_partition *pa);
 
-extern int fdisk_partition_set_end(struct fdisk_partition *pa, uint64_t off);
-extern uint64_t fdisk_partition_get_end(struct fdisk_partition *pa);
-extern int fdisk_partition_set_size(struct fdisk_partition *pa, uint64_t size);
-extern int fdisk_partition_size_explicit(struct fdisk_partition *pa, int enable);
-extern uint64_t fdisk_partition_get_size(struct fdisk_partition *pa);
+int fdisk_partition_set_size(struct fdisk_partition *pa, uint64_t sz);
+int fdisk_partition_unset_size(struct fdisk_partition *pa);
+uint64_t fdisk_partition_get_size(struct fdisk_partition *pa);
+int fdisk_partition_has_size(struct fdisk_partition *pa);
+int fdisk_partition_size_explicit(struct fdisk_partition *pa, int enable);
 
 extern int fdisk_partition_set_partno(struct fdisk_partition *pa, size_t n);
 extern size_t fdisk_partition_get_partno(struct fdisk_partition *pa);
@@ -285,10 +289,8 @@ extern int fdisk_partition_next_partno(struct fdisk_partition *pa,
                                       size_t *n);
 
 extern int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable);
-extern int fdisk_partition_start_follow_default(struct fdisk_partition *pa, int enable);
 extern int fdisk_partition_end_follow_default(struct fdisk_partition *pa, int enable);
 extern int fdisk_partition_end_is_default(struct fdisk_partition *pa);
-extern int fdisk_partition_start_is_default(struct fdisk_partition *pa);
 
 extern int fdisk_reorder_partitions(struct fdisk_context *cxt);
 
index cad4214edf2e0e9fb4a7af81122688bc2d5d7eee..e510c649d952aa247d14c20d87b8b3a7e2681e3d 100644 (file)
@@ -4,6 +4,19 @@
 
 #include "fdiskP.h"
 
+
+static void init_partition(struct fdisk_partition *pa)
+{
+       FDISK_INIT_UNDEF(pa->size);
+       FDISK_INIT_UNDEF(pa->start);
+       FDISK_INIT_UNDEF(pa->end);
+       FDISK_INIT_UNDEF(pa->partno);
+       FDISK_INIT_UNDEF(pa->parent_partno);
+       FDISK_INIT_UNDEF(pa->boot);
+
+       INIT_LIST_HEAD(&pa->parts);
+}
+
 /**
  * fdisk_new_partition:
  *
@@ -14,10 +27,7 @@ struct fdisk_partition *fdisk_new_partition(void)
        struct fdisk_partition *pa = calloc(1, sizeof(*pa));
 
        pa->refcount = 1;
-       INIT_LIST_HEAD(&pa->parts);
-       pa->partno = FDISK_EMPTY_PARTNO;
-       pa->parent_partno = FDISK_EMPTY_PARTNO;
-       pa->boot = FDISK_EMPTY_BOOTFLAG;
+       init_partition(pa);
        DBG(PART, ul_debugobj(pa, "alloc"));
        return pa;
 }
@@ -37,16 +47,16 @@ void fdisk_reset_partition(struct fdisk_partition *pa)
 
        DBG(PART, ul_debugobj(pa, "reset"));
        ref = pa->refcount;
+
        fdisk_free_parttype(pa->type);
        free(pa->name);
        free(pa->uuid);
        free(pa->attrs);
+
        memset(pa, 0, sizeof(*pa));
-       pa->partno = FDISK_EMPTY_PARTNO;
-       pa->parent_partno = FDISK_EMPTY_PARTNO;
-       pa->boot = FDISK_EMPTY_BOOTFLAG;
        pa->refcount = ref;
-       INIT_LIST_HEAD(&pa->parts);
+
+       init_partition(pa);
 }
 
 /**
@@ -85,7 +95,10 @@ void fdisk_unref_partition(struct fdisk_partition *pa)
 /**
  * fdisk_partition_set_start:
  * @pa: partition
- * @off: offset in sectors
+ * @off: offset in sectors, maximal is UINT64_MAX-1
+ *
+ * Note that zero is valid offset too. Use fdisk_partition_unset_start() to
+ * undefine the offset. 
  *
  * Returns: 0 on success, <0 on error.
  */
@@ -93,26 +106,64 @@ int fdisk_partition_set_start(struct fdisk_partition *pa, uint64_t off)
 {
        if (!pa)
                return -EINVAL;
+       if (FDISK_IS_UNDEF(off))
+               return -ERANGE;
        pa->start = off;
        return 0;
 }
 
+/**
+ * fdisk_partition_unset_start:
+ * @pa: partition
+ *
+ * Sets the size as undefined. See fdisk_partition_has_start().
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int fdisk_partition_unset_start(struct fdisk_partition *pa)
+{
+       if (!pa)
+               return -EINVAL;
+       FDISK_INIT_UNDEF(pa->start);
+       return 0;
+}
+
 /**
  * fdisk_partition_get_start:
  * @pa: partition
  *
+ * The zero is also valid offset. The function may return random undefined
+ * value when start offset is undefined (for example after
+ * fdisk_partition_unset_start()). Always use fdisk_partition_has_start() to be
+ * sure that you work with valid numbers.
+ *
  * Returns: start offset in sectors
  */
 uint64_t fdisk_partition_get_start(struct fdisk_partition *pa)
 {
-       return pa ? pa->start : 0;
+       return pa->start;
+}
+
+/**
+ * fdisk_partition_has_start:
+ * @pa: partition
+ *
+ * Returns: 1 or 0
+ */
+int fdisk_partition_has_start(struct fdisk_partition *pa)
+{
+       return pa && !FDISK_IS_UNDEF(pa->start);
 }
 
+
 /**
  * fdisk_partition_cmp_start:
  * @a: partition
  * @b: partition
- * See fdisk_sort_table().
+ *
+ * Compares partitons according to start offset, See fdisk_sort_table().
+ *
+ * Return: 0 if the same, <0 if @b greater, >0 if @a greater.
  */
 int fdisk_partition_cmp_start(struct fdisk_partition *a,
                              struct fdisk_partition *b)
@@ -121,69 +172,125 @@ int fdisk_partition_cmp_start(struct fdisk_partition *a,
 }
 
 /**
- * fdisk_partition_set_end:
+ * fdisk_partition_start_follow_default
  * @pa: partition
- * @off: offset in sectors
- *
- * Sets end offset, and zeroize size.
+ * @enable: 0|1
  *
- * The usual way is to address end of the partition by fdisk_partition_set_size().
+ * When @pa used as a tempalate for fdisk_add_partition() when force label driver
+ * to use the first possible space for the new partition.
  *
  * Returns: 0 on success, <0 on error.
  */
-int fdisk_partition_set_end(struct fdisk_partition *pa, uint64_t off)
+int fdisk_partition_start_follow_default(struct fdisk_partition *pa, int enable)
 {
        if (!pa)
                return -EINVAL;
-       pa->end = off;
-       pa->size = 0;
+       pa->start_follow_default = enable ? 1 : 0;
        return 0;
 }
 
 /**
- * fdisk_partition_get_start:
+ * fdisk_partition_start_is_default:
  * @pa: partition
  *
- * Returns: start offset in sectors
+ * See fdisk_partition_start_follow_default().
+ *
+ * Returns: 1 if the partition follows default
  */
-uint64_t fdisk_partition_get_end(struct fdisk_partition *pa)
+int fdisk_partition_start_is_default(struct fdisk_partition *pa)
 {
-       return pa ? pa->end : 0;
+       assert(pa);
+       return pa->start_follow_default;
 }
 
+
 /**
- * fdisk_partition_set_size
+ * fdisk_partition_set_size:
  * @pa: partition
- * @size: in bytes
+ * @sz: size in sectors, maximal is UIN64_MAX-1
  *
- * Sets size, zeroize end offset. See also fdisk_partition_set_end().
+ * Note that zero is valid size too. Use fdisk_partition_unset_size() to
+ * undefine the size.
  *
  * Returns: 0 on success, <0 on error.
  */
-int fdisk_partition_set_size(struct fdisk_partition *pa, uint64_t size)
+int fdisk_partition_set_size(struct fdisk_partition *pa, uint64_t sz)
 {
        if (!pa)
                return -EINVAL;
-       pa->size = size;
-       pa->end = 0;
+       if (FDISK_IS_UNDEF(sz))
+               return -ERANGE;
+       pa->size = sz;
        return 0;
 }
 
 /**
- * fdisk_partition_get_start:
+ * fdisk_partition_unset_size:
+ * @pa: partition
+ *
+ * Sets the size as undefined. See fdisk_partition_has_size().
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int fdisk_partition_unset_size(struct fdisk_partition *pa)
+{
+       if (!pa)
+               return -EINVAL;
+       FDISK_INIT_UNDEF(pa->size);
+       return 0;
+}
+
+/**
+ * fdisk_partition_get_size:
  * @pa: partition
  *
- * Returns: size in sectors
+ * The zero is also valid size. The function may return random undefined
+ * value when size is undefined (for example after fdisk_partition_unset_size()).
+ * Always use fdisk_partition_has_size() to be sure that you work with valid 
+ * numbers.
+ *
+ * Returns: size offset in sectors
  */
 uint64_t fdisk_partition_get_size(struct fdisk_partition *pa)
 {
-       return pa ? pa->size : 0;
+       return pa->size;
 }
 
+/**
+ * fdisk_partition_has_size:
+ * @pa: partition
+ *
+ * Returns: 1 or 0
+ */
+int fdisk_partition_has_size(struct fdisk_partition *pa)
+{
+       return pa && !FDISK_IS_UNDEF(pa->size);
+}
+
+/**
+ * fdisk_partition_size_explicit:
+ * @pa: partition
+ * @enable: 0|1
+ *
+ * By default libfdisk aligns the size when add the new partition (by
+ * fdisk_add_partrition()). If you want to disable this functionality use
+ * @enable = 1.
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int fdisk_partition_size_explicit(struct fdisk_partition *pa, int enable)
+{
+       if (!pa)
+               return -EINVAL;
+       pa->size_explicit = enable ? 1 : 0;
+       return 0;
+}
+
+
 /**
  * fdisk_partition_set_partno
  * @pa: partition
- * @n: partitiion number
+ * @n: partition number
  *
  * When @pa used as a tempalate for fdisk_add_partition() when infor label driver 
  * about wanted partition position.
@@ -279,35 +386,6 @@ int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable
        return 0;
 }
 
-/**
- * fdisk_partition_start_follow_default
- * @pa: partition
- * @enable: 0|1
- *
- * When @pa used as a tempalate for fdisk_add_partition() when force label driver
- * to use the first possible space for the new partition.
- *
- * Returns: 0 on success, <0 on error.
- */
-int fdisk_partition_start_follow_default(struct fdisk_partition *pa, int enable)
-{
-       if (!pa)
-               return -EINVAL;
-       pa->start_follow_default = enable ? 1 : 0;
-       return 0;
-}
-
-/**
- * fdisk_partition_start_is_default:
- * @pa: partition
- *
- * Returns: 1 if the partition follows default
- */
-int fdisk_partition_start_is_default(struct fdisk_partition *pa)
-{
-       assert(pa);
-       return pa->start_follow_default;
-}
 
 /**
  * fdisk_partition_start_follow_default
@@ -339,25 +417,6 @@ int fdisk_partition_end_is_default(struct fdisk_partition *pa)
        return pa->end_follow_default;
 }
 
-/**
- * fdisk_partition_size_explicit:
- * @pa: partition
- * @enable: 0|1
- *
- * By default libfdisk aligns the size when add the new partition (by
- * fdisk_add_partrition()). If you want to disable this functionality use
- * @enable = 1.
- *
- * Returns: 0 on success, <0 on error.
- */
-int fdisk_partition_size_explicit(struct fdisk_partition *pa, int enable)
-{
-       if (!pa)
-               return -EINVAL;
-       pa->size_explicit = enable ? 1 : 0;
-       return 0;
-}
-
 const char *fdisk_partition_get_uuid(struct fdisk_partition *pa)
 {
        return pa ? pa->uuid : NULL;
@@ -386,7 +445,7 @@ int fdisk_partition_set_attrs(struct fdisk_partition *pa, const char *attrs)
 
 int fdisk_partition_is_nested(struct fdisk_partition *pa)
 {
-       return pa && pa->parent_partno != FDISK_EMPTY_PARTNO;
+       return pa && !FDISK_IS_UNDEF(pa->parent_partno);
 }
 
 int fdisk_partition_is_container(struct fdisk_partition *pa)
@@ -439,7 +498,7 @@ int fdisk_partition_next_partno(
                }
                return -ERANGE;
 
-       } else if (pa && pa->partno != FDISK_EMPTY_PARTNO) {
+       } else if (pa && !FDISK_IS_UNDEF(pa->partno)) {
 
                DBG(PART, ul_debugobj(pa, "next partno (specified=%zu)", pa->partno));
 
@@ -500,10 +559,12 @@ int fdisk_partition_to_string(struct fdisk_partition *pa,
                rc = asprintf(&p, "%c", pa->boot ? '*' : ' ');
                break;
        case FDISK_FIELD_START:
-               x = fdisk_cround(cxt, pa->start);
-               rc = pa->start_post ?
+               if (fdisk_partition_has_start(pa)) {
+                       x = fdisk_cround(cxt, pa->start);
+                       rc = pa->start_post ?
                                asprintf(&p, "%ju%c", x, pa->start_post) :
                                asprintf(&p, "%ju", x);
+               }
                break;
        case FDISK_FIELD_END:
                x = fdisk_cround(cxt, pa->end);
@@ -512,26 +573,26 @@ int fdisk_partition_to_string(struct fdisk_partition *pa,
                                asprintf(&p, "%ju", x);
                break;
        case FDISK_FIELD_SIZE:
-       {
-               uint64_t sz = pa->size * cxt->sector_size;
-
-               if (fdisk_is_details(cxt)) {
-                       rc = pa->size_post ?
-                                       asprintf(&p, "%ju%c", sz, pa->size_post) :
-                                       asprintf(&p, "%ju", sz);
-               } else {
-                       p = size_to_human_string(SIZE_SUFFIX_1LETTER, sz);
-                       if (!p)
-                               rc = -ENOMEM;
+               if (fdisk_partition_has_size(pa)) {
+                       uint64_t sz = pa->size * cxt->sector_size;
+
+                       if (fdisk_is_details(cxt)) {
+                               rc = pa->size_post ?
+                                               asprintf(&p, "%ju%c", sz, pa->size_post) :
+                                               asprintf(&p, "%ju", sz);
+                       } else {
+                               p = size_to_human_string(SIZE_SUFFIX_1LETTER, sz);
+                               if (!p)
+                                       rc = -ENOMEM;
+                       }
                }
                break;
-       }
        case FDISK_FIELD_CYLINDERS:
                rc = asprintf(&p, "%ju", (uintmax_t)
-                               fdisk_cround(cxt, pa->size));
+                       fdisk_cround(cxt, fdisk_partition_has_size(pa) ? pa->size : 0));
                break;
        case FDISK_FIELD_SECTORS:
-               rc = asprintf(&p, "%ju", pa->size);
+               rc = asprintf(&p, "%ju", fdisk_partition_has_size(pa) ? pa->size : 0);
                break;
        case FDISK_FIELD_BSIZE:
                rc = asprintf(&p, "%ju", pa->bsize);
@@ -561,10 +622,10 @@ int fdisk_partition_to_string(struct fdisk_partition *pa,
                p = pa->attrs ? strdup(pa->attrs) : NULL;
                break;
        case FDISK_FIELD_SADDR:
-               p = pa->start_addr ? strdup(pa->start_addr) : NULL;
+               p = pa->start_chs ? strdup(pa->start_chs) : NULL;
                break;
        case FDISK_FIELD_EADDR:
-               p = pa->end_addr ? strdup(pa->end_addr) : NULL;
+               p = pa->end_chs ? strdup(pa->end_chs) : NULL;
                break;
        default:
                return -EINVAL;
index d6b47a696fb715bc7a11059aab2185eb0651f3b2..97b5e4d26adf343530ca97724eeef68dce0c15dd 100644 (file)
@@ -398,9 +398,9 @@ int fdisk_script_write_file(struct fdisk_script *dp, FILE *f)
                else
                        fprintf(f, "%zu :", pa->partno + 1);
 
-               if (pa->start)
+               if (fdisk_partition_has_start(pa))
                        fprintf(f, " start=%12ju", pa->start);
-               if (pa->size)
+               if (fdisk_partition_has_size(pa))
                        fprintf(f, ", size=%12ju", pa->size);
 
                if (pa->type && fdisk_parttype_get_string(pa->type))
@@ -420,7 +420,7 @@ int fdisk_script_write_file(struct fdisk_script *dp, FILE *f)
                        if (!lb || fdisk_label_get_type(lb) != FDISK_DISKLABEL_DOS)
                                fprintf(f, ", attrs=\"%s\"", pa->attrs);
                }
-               if (pa->boot)
+               if (fdisk_partition_is_bootable(pa))
                        fprintf(f, ", bootable");
                fputc('\n', f);
        }
index 20ae59c03077ea14f88bbe7349efefba93b8ca32..e2eff9bb4739aad5be7e38b070808aa3312f9f6b 100644 (file)
@@ -816,7 +816,7 @@ static int sgi_add_partition(struct fdisk_context *cxt,
        /* first sector */
        if (pa && pa->start_follow_default)
                ;
-       else if (pa && pa->start) {
+       else if (pa && fdisk_partition_has_start(pa)) {
                first = pa->start;
                last = is_in_freelist(cxt, first);
 
@@ -856,7 +856,7 @@ static int sgi_add_partition(struct fdisk_context *cxt,
        /* last sector */
        if (pa && pa->end_follow_default)
                last -= 1ULL;
-       else if (pa && pa->size) {
+       else if (pa && fdisk_partition_has_size(pa)) {
                if (first + pa->size - 1ULL > last)
                        return -ERANGE;
                last = first + pa->size - 1ULL;
@@ -1050,9 +1050,9 @@ static int sgi_set_partition(struct fdisk_context *cxt,
                sgilabel->partitions[i].type = cpu_to_be32(t->code);
        }
 
-       if (pa->start)
+       if (fdisk_partition_has_start(pa))
                sgilabel->partitions[i].first_block = cpu_to_be32(pa->start);
-       if (pa->size)
+       if (fdisk_partition_has_size(pa))
                sgilabel->partitions[i].num_blocks = cpu_to_be32(pa->size);
 
        fdisk_label_set_changed(cxt->label, 1);
index f9f1d472f2a69e3f7b4c384737c3a9d25886770b..dcde5d7afa2f5a3af2fe244dc13336010fdd665c 100644 (file)
@@ -521,7 +521,7 @@ static int sun_add_partition(
 
        if (pa && pa->start_follow_default)
                first = start;
-       else if (pa && pa->start) {
+       else if (pa && fdisk_partition_has_start(pa)) {
                first = pa->start;
 
                if (!whole_disk && !is_free_sector(cxt, first, starts, lens))
@@ -612,7 +612,7 @@ static int sun_add_partition(
        /* last */
        if (pa && pa->end_follow_default)
                last = whole_disk || (n == 2 && !first) ? stop2 : stop;
-       else if (pa && pa->size) {
+       else if (pa && fdisk_partition_has_size(pa)) {
                last = first + pa->size - 1ULL;
 
                if (!whole_disk && last > stop)
@@ -983,10 +983,10 @@ static int sun_set_partition(
                info->id = cpu_to_be16(t->code);
        }
 
-       if (pa->start)
+       if (fdisk_partition_has_start(pa))
                sunlabel->partitions[i].start_cylinder =
                        cpu_to_be32(pa->start / (cxt->geom.heads * cxt->geom.sectors));
-       if (pa->size)
+       if (fdisk_partition_has_size(pa))
                sunlabel->partitions[i].num_sectors = cpu_to_be32(pa->size);
 
        fdisk_label_set_changed(cxt->label, 1);
index fb8f52c7ebf7b590e28f66d1490eaf2431ce162f..ea392d900e0d7c8df41f0072bb06be27241427cc 100644 (file)
@@ -413,13 +413,15 @@ static int check_container_freespace(struct fdisk_context *cxt,
        assert(parts);
        assert(tb);
        assert(cont);
+       assert(fdisk_partition_has_start(cont));
 
        last = fdisk_partition_get_start(cont);
        grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1;
        fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
 
        while (fdisk_table_next_partition(parts, &itr, &pa) == 0) {
-               if (!pa->used || !fdisk_partition_is_nested(pa))
+               if (!pa->used || !fdisk_partition_is_nested(pa)
+                             || !fdisk_partition_has_start(pa))
                        continue;
 
                lastplusoff = last + cxt->first_lba;
@@ -476,7 +478,8 @@ int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
 
        /* analyze gaps between partitions */
        while (rc == 0 && fdisk_table_next_partition(parts, &itr, &pa) == 0) {
-               if (!pa->used || pa->wholedisk || fdisk_partition_is_nested(pa))
+               if (!pa->used || pa->wholedisk || fdisk_partition_is_nested(pa)
+                             || !fdisk_partition_has_start(pa))
                        continue;
                DBG(CXT, ul_debugobj(cxt, "freespace analyze: partno=%zu, start=%ju, end=%ju",
                                        pa->partno, pa->start, pa->end));
@@ -524,6 +527,8 @@ int fdisk_table_wrong_order(struct fdisk_table *tb)
 
        fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
        while (tb && fdisk_table_next_partition(tb, &itr, &pa) == 0) {
+               if (!fdisk_partition_has_start(pa))
+                       continue;
                if (pa->start < last)
                        return 1;
                last = pa->start;
@@ -556,7 +561,7 @@ int fdisk_apply_table(struct fdisk_context *cxt, struct fdisk_table *tb)
 
        fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
        while (tb && fdisk_table_next_partition(tb, &itr, &pa) == 0) {
-               if (!pa->start && !pa->start_follow_default)
+               if (!fdisk_partition_has_start(pa) && !pa->start_follow_default)
                        continue;
                rc = fdisk_add_partition(cxt, pa, NULL);
                if (rc)