summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/c.h8
-rw-r--r--libfdisk/src/alignment.c4
-rw-r--r--libfdisk/src/dos.c2
-rw-r--r--libfdisk/src/gpt.c2
-rw-r--r--libfdisk/src/partition.c12
-rw-r--r--libfdisk/src/table.c6
6 files changed, 31 insertions, 3 deletions
diff --git a/include/c.h b/include/c.h
index 0f6e5b29b..142583956 100644
--- a/include/c.h
+++ b/include/c.h
@@ -107,6 +107,14 @@
_max1 > _max2 ? _max1 : _max2; })
#endif
+#ifndef cmp_numbers
+# define cmp_numbers(x, y) __extension__ ({ \
+ __typeof__(x) _a = (x); \
+ __typeof__(y) _b = (y); \
+ (void) (&_a == &_b); \
+ a == b ? 0 : a > b ? 1 : -1; })
+#endif
+
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c
index 93cb80b32..b1f3ee5c3 100644
--- a/libfdisk/src/alignment.c
+++ b/libfdisk/src/alignment.c
@@ -416,6 +416,10 @@ int fdisk_discover_geometry(struct fdisk_context *cxt)
if (!blkdev_get_sectors(cxt->dev_fd, &nsects))
cxt->total_sectors = (nsects / (cxt->sector_size >> 9));
+ DBG(CXT, ul_debugobj(cxt, "total sectors: %ju (ioctl=%ju)",
+ (uintmax_t) cxt->total_sectors,
+ (uintmax_t) nsects));
+
/* what the kernel/bios thinks the geometry is */
blkdev_get_geometry(cxt->dev_fd, &cxt->geom.heads, (unsigned int *) &cxt->geom.sectors);
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c
index abafcc248..16391806e 100644
--- a/libfdisk/src/dos.c
+++ b/libfdisk/src/dos.c
@@ -1985,7 +1985,7 @@ static int cmp_ebr_offsets(const void *a, const void *b)
if (be->offset == 0)
return -1;
- return ae->offset - be->offset;
+ return cmp_numbers(ae->offset, be->offset);
}
/*
diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c
index 6448a054a..fc18441d6 100644
--- a/libfdisk/src/gpt.c
+++ b/libfdisk/src/gpt.c
@@ -2420,7 +2420,7 @@ static int gpt_entry_cmp_start(const void *a, const void *b)
if (bu)
return -1;
- return gpt_partition_start(ae) - gpt_partition_start(be);
+ return cmp_numbers(gpt_partition_start(ae), gpt_partition_start(be));
}
/* sort partition by start sector */
diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c
index 7d4d57669..90276416e 100644
--- a/libfdisk/src/partition.c
+++ b/libfdisk/src/partition.c
@@ -180,7 +180,17 @@ int fdisk_partition_has_start(struct fdisk_partition *pa)
int fdisk_partition_cmp_start(struct fdisk_partition *a,
struct fdisk_partition *b)
{
- return a->start - b->start;
+ int is_a = FDISK_IS_UNDEF(a->start),
+ is_b = FDISK_IS_UNDEF(b->start);
+
+ if (!is_a && !is_b)
+ return 0;
+ if (!is_a)
+ return -1;
+ if (!is_b)
+ return 1;
+
+ return cmp_numbers(a->start, b->start);
}
/**
diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c
index 8adbd7f36..9747f7dc8 100644
--- a/libfdisk/src/table.c
+++ b/libfdisk/src/table.c
@@ -497,13 +497,19 @@ int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
rc = fdisk_get_partitions(cxt, &parts);
if (rc)
goto done;
+
fdisk_table_sort_partitions(parts, fdisk_partition_cmp_start);
fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
last = cxt->first_lba;
grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1;
+ DBG(CXT, ul_debugobj(cxt, "initialized: last=%ju, grain=%ju", last, grain));
+
/* analyze gaps between partitions */
while (rc == 0 && fdisk_table_next_partition(parts, &itr, &pa) == 0) {
+
+ DBG(CXT, ul_debugobj(cxt, "partno=%zu, start=%ju", pa->partno, pa->start));
+
if (!pa->used || pa->wholedisk || fdisk_partition_is_nested(pa)
|| !fdisk_partition_has_start(pa))
continue;