summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--disk-utils/cfdisk.c3
-rw-r--r--disk-utils/fdisk-list.c2
-rw-r--r--disk-utils/sfdisk.c2
-rw-r--r--libfdisk/src/bsd.c16
-rw-r--r--libfdisk/src/dos.c56
-rw-r--r--libfdisk/src/fdiskP.h24
-rw-r--r--libfdisk/src/gpt.c23
-rw-r--r--libfdisk/src/label.c11
-rw-r--r--libfdisk/src/libfdisk.h22
-rw-r--r--libfdisk/src/partition.c263
-rw-r--r--libfdisk/src/script.c6
-rw-r--r--libfdisk/src/sgi.c8
-rw-r--r--libfdisk/src/sun.c8
-rw-r--r--libfdisk/src/table.c11
14 files changed, 277 insertions, 178 deletions
diff --git a/disk-utils/cfdisk.c b/disk-utils/cfdisk.c
index 1f2ad7c49..496871311 100644
--- a/disk-utils/cfdisk.c
+++ b/disk-utils/cfdisk.c
@@ -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)
diff --git a/disk-utils/fdisk-list.c b/disk-utils/fdisk-list.c
index 46d50a7f3..d0d752ef6 100644
--- a/disk-utils/fdisk-list.c
+++ b/disk-utils/fdisk-list.c
@@ -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);
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 68df57c0d..821b5ed15 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -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;
diff --git a/libfdisk/src/bsd.c b/libfdisk/src/bsd.c
index dfc47bda0..c92c893bb 100644
--- a/libfdisk/src/bsd.c
+++ b/libfdisk/src/bsd.c
@@ -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);
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c
index 0ae0615a2..bcfacfc7d 100644
--- a/libfdisk/src/dos.c
+++ b/libfdisk/src/dos.c
@@ -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;
diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h
index 253c515f8..7822466a2 100644
--- a/libfdisk/src/fdiskP.h
+++ b/libfdisk/src/fdiskP.h
@@ -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 */
diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c
index e695bea9d..ec6dbd664 100644
--- a/libfdisk/src/gpt.c
+++ b/libfdisk/src/gpt.c
@@ -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);
diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c
index a3a4e8812..12ad1dc30 100644
--- a/libfdisk/src/label.c
+++ b/libfdisk/src/label.c
@@ -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;
diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h
index 047119983..260f90839 100644
--- a/libfdisk/src/libfdisk.h
+++ b/libfdisk/src/libfdisk.h
@@ -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);
diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c
index cad4214ed..e510c649d 100644
--- a/libfdisk/src/partition.c
+++ b/libfdisk/src/partition.c
@@ -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;
diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c
index d6b47a696..97b5e4d26 100644
--- a/libfdisk/src/script.c
+++ b/libfdisk/src/script.c
@@ -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);
}
diff --git a/libfdisk/src/sgi.c b/libfdisk/src/sgi.c
index 20ae59c03..e2eff9bb4 100644
--- a/libfdisk/src/sgi.c
+++ b/libfdisk/src/sgi.c
@@ -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);
diff --git a/libfdisk/src/sun.c b/libfdisk/src/sun.c
index f9f1d472f..dcde5d7af 100644
--- a/libfdisk/src/sun.c
+++ b/libfdisk/src/sun.c
@@ -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);
diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c
index fb8f52c7e..ea392d900 100644
--- a/libfdisk/src/table.c
+++ b/libfdisk/src/table.c
@@ -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)