]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: fix bug in cmp_numbers() and partitions sorting
authorKarel Zak <kzak@redhat.com>
Thu, 4 Dec 2014 12:06:03 +0000 (13:06 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 4 Dec 2014 12:06:03 +0000 (13:06 +0100)
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1170191
Signed-off-by: Karel Zak <kzak@redhat.com>
include/c.h
libfdisk/src/partition.c
libfdisk/src/table.c

index 1425839563105c5b678b41d875aa4c6df6b4356d..068e2676a9c2989d87565ba5eec980fdd7eefc7d 100644 (file)
        __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
index 8ebdb4682e82a959fc62d179ae1fd9dd5436efe2..8f8402716211582ac36ea396e903fa34a72603e4 100644 (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);
index 18944e0c44eb873784c3cccb3436a69ca73146ff..1add09fca2a2e5b05529ed7ee85eccd3ca4daa63 100644 (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);