And here comes the patch to solve this issue. Comments greatly appreciated.
regards. On Wed, May 06, 2009 at 01:31:48PM +0200, Joel Granados wrote: > Hi list. > > The question of the day is: Where does an msdos label begin? In sector > 0 or in sector 32 or in sector 63? The answer is: It all depends on > what partitions you have in the table. > > little script to prove my point (This is run under latest git master > branch) > > <snip> > #!/bin/bash > parted="/usr/local/sbin/parted" > dd if=/dev/zero of=test bs=1M count=100 > $parted test mklabel msdos > $parted test unit s print free > $parted test mkpart primary 50M 100M > $parted test unit s print free > rm test > </snip> > > Notice that the first time the script prints the free space, it starts > in sector 0. And the second time it prints the free space it begins in > sector 32. Why, I don't know yet. Going to start to investigate. IMO > parted should be consistent as to where the free space begins regardless > of the number of partitions in the table. > > Comments appreciated. > > Regards. > > -- > Joel Andres Granados > Brno, Czech Republic, Red Hat. > > _______________________________________________ > parted-devel mailing list > [email protected] > http://lists.alioth.debian.org/mailman/listinfo/parted-devel -- Joel Andres Granados Brno, Czech Republic, Red Hat.
>From 71c6d979c51b9e7b9d1823baf3fbfe7c1d5ce98e Mon Sep 17 00:00:00 2001 From: Joel Andres Granados <[email protected]> Date: Thu, 7 May 2009 16:57:02 +0200 Subject: [PATCH] Make sure we always create msdos metadata parts. 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
_______________________________________________ parted-devel mailing list [email protected] http://lists.alioth.debian.org/mailman/listinfo/parted-devel

