diff mbox series

diskpart: fix comparison for automatically size partitions

Message ID 20210516100617.37101-1-stefano.babic@babic.homelinux.org
State Rejected
Headers show
Series diskpart: fix comparison for automatically size partitions | expand

Commit Message

Stefano Babic May 16, 2021, 10:06 a.m. UTC
From: Stefano Babic <sbabic@denx.de>

The comparison does not work for automatically sized partitions (last
partition on the disk). Size is not defined in sw-descritpion and the
test forces to write the table.

Check if size is not set and that there is no free space on the disk and
skip size comparison.

Signed-off-by: Stefano Babic <sbabic@denx.de>
Reported-by: James Hilliard <james.hilliard1@gmail.com>
---
 handlers/diskpart_handler.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/handlers/diskpart_handler.c b/handlers/diskpart_handler.c
index b10ffc6..7842806 100644
--- a/handlers/diskpart_handler.c
+++ b/handlers/diskpart_handler.c
@@ -131,10 +131,24 @@  static int diskpart_set_partition(struct fdisk_partition *pa,
 	return ret;
 }
 
+static bool is_disk_full(struct fdisk_context *cxt)
+{
+	struct fdisk_table *tb = NULL;
+	int ret;
+
+	ret = fdisk_get_freespaces(cxt, &tb);
+	if (ret)
+		fdisk_unref_table(tb);
+	return (ret == 0);
+}
+
 /*
  * Return true if partition differs
  */
-static bool diskpart_partition_cmp(const char *lbtype, struct fdisk_partition *firstpa, struct fdisk_partition *secondpa)
+static bool diskpart_partition_cmp(const char *lbtype,
+					struct fdisk_partition *firstpa,
+					struct fdisk_partition *secondpa,
+					bool skipsize)
 {
 	if (!firstpa || !secondpa)
 		return true;
@@ -150,7 +164,7 @@  static bool diskpart_partition_cmp(const char *lbtype, struct fdisk_partition *f
 		(!strcmp(lbtype, "dos") &&
 			fdisk_parttype_get_code(fdisk_partition_get_type(firstpa)) !=
 			fdisk_parttype_get_code(fdisk_partition_get_type(secondpa))) ||
-		fdisk_partition_get_size(firstpa) != fdisk_partition_get_size(secondpa))) {
+		(!skipsize && fdisk_partition_get_size(firstpa) != fdisk_partition_get_size(secondpa)))) {
 		TRACE("Partition differ : %s(%llu) <--> %s(%llu)",
 			fdisk_partition_get_name (firstpa) ? fdisk_partition_get_name(firstpa) : "",
 			(long long unsigned)fdisk_partition_get_size(firstpa),
@@ -388,14 +402,27 @@  static int diskpart(struct img_type *img,
 			while (i < numpartondisk && !createtable) {
 				newpa=NULL;
 				pa = NULL;
+				size_t unrefsize = 0;
 				if (fdisk_table_next_partition (tb, itr, &newpa) ||
 					fdisk_table_next_partition (oldtb, olditr, &pa)) {
 					TRACE("Partition not found, something went wrong %lu !", i);
 					ret = -EFAULT;
 					goto handler_exit;
 				}
-				if (diskpart_partition_cmp(lbtype, pa, newpa)) {
+				if (diskpart_partition_cmp(lbtype, pa, newpa, false)) {
 					createtable = true;
+					/*
+					 * if this is the last partition, size can be set
+					 * to take all the remaining on the disk, then checks
+					 * that disk is full and skip size from comparison
+					 */
+					if ((i == (numpartondisk -1)) &&
+						(fdisk_partition_get_size(newpa) == LIBFDISK_INIT_UNDEF(unrefsize)) &&
+						 (is_disk_full(cxt))) {
+						TRACE("Disk full partitioned, do not check size for last part");
+						createtable = diskpart_partition_cmp(lbtype, pa, newpa, true);
+					} else
+						createtable = true;
 				}
 
 				fdisk_unref_partition(newpa);