libfdisk: make it possible to use zero for size and start

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>
This commit is contained in:
Karel Zak 2014-10-15 12:17:40 +02:00
parent 6311e17845
commit ecf40cda76
14 changed files with 276 additions and 177 deletions

View 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)

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

View 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;

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

View 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;

View 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 */

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

View 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;

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

View 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
* @enable: 0|1
*
* Sets end offset, and zeroize size.
*
* 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
*
* Returns: size in sectors
* 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
*
* 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_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;
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;

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

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

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

View 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)