From 764b697c56660d3d7207b985ff6b0730df387954 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 4 Dec 2014 13:06:03 +0100 Subject: libfdisk: fix bug in cmp_numbers() and partitions sorting Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1170191 Signed-off-by: Karel Zak --- include/c.h | 2 +- libfdisk/src/partition.c | 10 +++++----- libfdisk/src/table.c | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/include/c.h b/include/c.h index 142583956..068e2676a 100644 --- a/include/c.h +++ b/include/c.h @@ -112,7 +112,7 @@ __typeof__(x) _a = (x); \ __typeof__(y) _b = (y); \ (void) (&_a == &_b); \ - a == b ? 0 : a > b ? 1 : -1; }) + _a == _b ? 0 : _a > _b ? 1 : -1; }) #endif #ifndef offsetof diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c index 8ebdb4682..8f8402716 100644 --- a/libfdisk/src/partition.c +++ b/libfdisk/src/partition.c @@ -179,14 +179,14 @@ int fdisk_partition_has_start(struct fdisk_partition *pa) int fdisk_partition_cmp_start(struct fdisk_partition *a, struct fdisk_partition *b) { - int is_a = FDISK_IS_UNDEF(a->start), - is_b = FDISK_IS_UNDEF(b->start); + int no_a = FDISK_IS_UNDEF(a->start), + no_b = FDISK_IS_UNDEF(b->start); - if (!is_a && !is_b) + if (no_a && no_b) return 0; - if (!is_a) + if (no_a) return -1; - if (!is_b) + if (no_b) return 1; return cmp_numbers(a->start, b->start); diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c index 18944e0c4..1add09fca 100644 --- a/libfdisk/src/table.c +++ b/libfdisk/src/table.c @@ -307,6 +307,22 @@ int fdisk_get_partitions(struct fdisk_context *cxt, struct fdisk_table **tb) return 0; } +static void debug_print_table(struct fdisk_table *tb) +{ + struct fdisk_iter itr; + struct fdisk_partition *pa; + + fdisk_reset_iter(&itr, FDISK_ITER_FORWARD); + while (fdisk_table_next_partition(tb, &itr, &pa) == 0) + ul_debugobj(tb, "partition %p [partno=%zu, start=%ju, end=%ju, size=%ju] ", + pa, pa->partno, + (uintmax_t) fdisk_partition_get_start(pa), + (uintmax_t) fdisk_partition_get_end(pa), + (uintmax_t) fdisk_partition_get_size(pa)); + +} + + typedef int (*fdisk_partcmp_t)(struct fdisk_partition *, struct fdisk_partition *); static int cmp_parts_wrapper(struct list_head *a, struct list_head *b, void *data) @@ -319,6 +335,7 @@ static int cmp_parts_wrapper(struct list_head *a, struct list_head *b, void *dat return cmp(pa, pb); } + /** * fdisk_table_sort_partitions: * @tb: table @@ -335,7 +352,14 @@ int fdisk_table_sort_partitions(struct fdisk_table *tb, if (!tb) return -EINVAL; + DBG(TAB, ul_debugobj(tb, "Before sort:")); + ON_DBG(TAB, debug_print_table(tb)); + list_sort(&tb->parts, cmp_parts_wrapper, (void *) cmp); + + DBG(TAB, ul_debugobj(tb, "After sort:")); + ON_DBG(TAB, debug_print_table(tb)); + return 0; } @@ -413,13 +437,14 @@ static int table_add_freespace( } while (fdisk_table_next_partition(tb, &itr, &x) == 0) { - fdisk_sector_t end, best_end; + fdisk_sector_t end, best_end = 0; if (!fdisk_partition_has_end(x)) continue; end = fdisk_partition_get_end(x); - best_end = fdisk_partition_get_end(best); + if (best) + best_end = fdisk_partition_get_end(best); if (end < pa->start && (!best || best_end < end)) best = x; @@ -459,11 +484,21 @@ static int check_container_freespace(struct fdisk_context *cxt, grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1; fdisk_reset_iter(&itr, FDISK_ITER_FORWARD); + DBG(CXT, ul_debugobj(cxt, "initialized: last=%ju, grain=%ju", last, grain)); + while (fdisk_table_next_partition(parts, &itr, &pa) == 0) { + + DBG(CXT, ul_debugobj(cxt, "partno=%zu, start=%ju", pa->partno, pa->start)); + if (!pa->used || !fdisk_partition_is_nested(pa) || !fdisk_partition_has_start(pa)) continue; + DBG(CXT, ul_debugobj(cxt, "freespace container analyze: partno=%zu, start=%ju, end=%ju", + pa->partno, + (uintmax_t) fdisk_partition_get_start(pa), + (uintmax_t) fdisk_partition_get_end(pa))); + lastplusoff = last + cxt->first_lba; if (pa->start > lastplusoff && pa->start - lastplusoff > grain) rc = table_add_freespace(cxt, tb, lastplusoff, pa->start, cont); -- cgit v1.2.3-55-g7522