libfdisk: fix bug in cmp_numbers() and partitions sorting

Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1170191
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2014-12-04 13:06:03 +01:00
parent bbfc24298f
commit 764b697c56
3 changed files with 43 additions and 8 deletions

View File

@ -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

View File

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

View File

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