[PATCH] Make sure we always create msdos metadata parts.

Joel Andres Granados jgranado at redhat.com
Thu May 7 14:57:02 UTC 2009


If disks did not contain any partitions, parted did not create metadata
partitions for msdos labels.  This lead to inconsistencies when
reporting free space partition ranges.  This patch addresses this issue.

* libparted/labels/dos.c (get_last_part): Erased this function.
* libparted/labels/dos.c (get_start_first_nonfree_part): New function to
  find the start sector of the first non-free partition in disk.
* libparted/labels/dos.c (get_end_last_nonfree_part): New function to
  find the end sector of the last non-free partition in disk.
* libparted/lables/dos.c (add_startend_metadata): Added code that
  handles disks no partitions.  Added check that prevents the metadata
  partitions from being greater than the device length.  Added check
  that prevents metadata partitions from overlapping in small devs.
---
 libparted/labels/dos.c |   92 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 70 insertions(+), 22 deletions(-)

diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c
index d07dcbd..f724722 100644
--- a/libparted/labels/dos.c
+++ b/libparted/labels/dos.c
@@ -2081,16 +2081,52 @@ add_logical_part_metadata (PedDisk* disk, const PedPartition* log_part)
 				  metadata_start, metadata_end);
 }
 
-static PedPartition*
-get_last_part (const PedDisk* disk)
+/*
+ * return 0 if we don't asign sector
+ */
+static int
+get_start_first_nonfree_part(const PedDisk* disk, PedSector *sector)
 {
-	PedPartition* first_part = disk->part_list;
 	PedPartition* walk;
 
-	if (!first_part)
-		return NULL;
-	for (walk = first_part; walk->next; walk = walk->next);
-	return walk;
+	// disk->part_list is the first partition on the disk.
+	if (!disk->part_list)
+		return 0;
+
+	for (walk = disk->part_list; walk; walk = walk->next)
+		if (walk->type == PED_PARTITION_NORMAL ||
+				walk->type == PED_PARTITION_EXTENDED){
+			*sector = walk->geom.start;
+			return 1;
+		}
+	return 0;
+}
+
+/*
+ * return 0 if we don't asign sector
+ */
+static int
+get_end_last_nonfree_part(const PedDisk* disk, PedSector *sector)
+{
+	PedPartition* last_part = NULL;
+	PedPartition* walk;
+
+	// disk->part_list is the first partition on the disk.
+	if (!disk->part_list)
+		return 0;
+
+	for (walk = disk->part_list; walk; walk = walk->next)
+		if (walk->type == PED_PARTITION_NORMAL ||
+				walk->type == PED_PARTITION_EXTENDED){
+			last_part = walk;
+		}
+
+	if (!last_part)
+		return 0;
+	else{
+		*sector = last_part->geom.end;
+		return 1;
+	}
 }
 
 /* Adds metadata placeholder partitions to cover the partition table (and
@@ -2104,25 +2140,37 @@ add_startend_metadata (PedDisk* disk)
 {
 	PedDevice* dev = disk->dev;
 	PedSector cyl_size = dev->bios_geom.sectors * dev->bios_geom.heads;
-	PedPartition* first_part = disk->part_list;
-	PedPartition* last_part = get_last_part (disk);
-	PedSector start, end;
+	PedSector init_start, init_end, final_start, final_end;
 
-	if (!first_part)
-		return 1;
+	// Ranges for the initial and final metadata partition.
+	init_start = 0;
+	if (!get_start_first_nonfree_part(disk, &init_end))
+		init_end = dev->bios_geom.sectors - 1;
+	else
+		init_end = PED_MIN (dev->bios_geom.sectors - 1, init_end - 1);
 
-	start = 0;
-	end = PED_MIN (dev->bios_geom.sectors - 1, first_part->geom.start - 1);
-	if (!add_metadata_part (disk, PED_PARTITION_NORMAL, start, end))
-		return 0;
+	if (!get_end_last_nonfree_part(disk, &final_start))
+		final_start = ped_round_down_to (dev->length, cyl_size);
+	else
+		final_start = PED_MAX (final_start + 1,
+				ped_round_down_to (dev->length, cyl_size));
+	final_end = dev->length - 1;
+
+	// Create the metadata partitions.
+	// init_end <= dev->length for devices that are _real_ small.
+	if (init_start < init_end &&
+			init_end <= dev->length &&
+			!add_metadata_part (disk, PED_PARTITION_NORMAL,
+				init_start, init_end))
+			return 0;
 
-	start = PED_MAX (last_part->geom.end + 1,
-			 ped_round_down_to (dev->length, cyl_size));
-	end = dev->length - 1;
-	if (start < end) {
-		if (!add_metadata_part (disk, PED_PARTITION_NORMAL, start, end))
+	// init_end < final_start so they dont overlap.  For very small devs.
+	if (final_start < final_end &&
+			init_end < final_start &&
+			final_end <= dev->length &&
+			!add_metadata_part (disk, PED_PARTITION_NORMAL,
+				final_start, final_end))
 			return 0;
-	}
 
 	return 1;
 }
-- 
1.6.0.6


--Kj7319i9nmIyA2yE--



More information about the parted-devel mailing list