diff options
author | Karel Zak | 2014-10-15 12:17:40 +0200 |
---|---|---|
committer | Karel Zak | 2014-10-15 12:17:40 +0200 |
commit | ecf40cda764496d3d1b29435ea64a65335ae0acf (patch) | |
tree | 9ef1d00a3906fd495194b88ca5023c9729353df0 /libfdisk/src/partition.c | |
parent | tests: check for wipefs and helpers in fdisk tests (diff) | |
download | kernel-qcow2-util-linux-ecf40cda764496d3d1b29435ea64a65335ae0acf.tar.gz kernel-qcow2-util-linux-ecf40cda764496d3d1b29435ea64a65335ae0acf.tar.xz kernel-qcow2-util-linux-ecf40cda764496d3d1b29435ea64a65335ae0acf.zip |
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>
Diffstat (limited to 'libfdisk/src/partition.c')
-rw-r--r-- | libfdisk/src/partition.c | 263 |
1 files changed, 162 insertions, 101 deletions
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; |