From 483a31aefdb5993f86cbbbf1131f097a562fcda9 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 9 Nov 2011 11:18:46 -0500 Subject: [PATCH] When creating a GPT partition, don't insist that the size is divisible by 1 MiB ... only insist that the partition start is. Also take the last 33 LBAs into account - this is not space we can use. Signed-off-by: David Zeuthen --- src/udiskslinuxpartitiontable.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/udiskslinuxpartitiontable.c b/src/udiskslinuxpartitiontable.c index 940a10f..8a46f61 100644 --- a/src/udiskslinuxpartitiontable.c +++ b/src/udiskslinuxpartitiontable.c @@ -327,7 +327,7 @@ handle_create_partition (UDisksPartitionTable *table, if (g_strcmp0 (table_type, "gpt") == 0) { guint64 start_mib; - guint64 end_mib; + guint64 end_bytes; gchar *escaped_name; gchar *escaped_escaped_name; @@ -338,28 +338,33 @@ handle_create_partition (UDisksPartitionTable *table, escaped_name = g_strescape (name, NULL); escaped_escaped_name = g_strescape (escaped_name, NULL); - /* round to MiB for alignment purposes and round up so we _start_ and _end_ at MiB spots */ + /* round to MiB for alignment purposes and round up so we _start_ at MiB granularity + * since that ensures optimal IO + */ start_mib = offset / MIB_SIZE + 1L; - end_mib = start_mib + (size / MIB_SIZE + 1L); + end_bytes = start_mib * MIB_SIZE + size; /* reduce size until we are not overlapping - * - neighboring partitions (leave 1MiB wiggle room at the end); or - * - the end of the disk + * - neighboring partitions; or + * - the end of the disk (note: the 33 LBAs is the Secondary GPT) */ - while (end_mib > start_mib && (have_partition_in_range (table, - start_mib * MIB_SIZE, - (end_mib + 1) * MIB_SIZE) || - (end_mib * MIB_SIZE > udisks_block_get_size (block)))) + while (end_bytes > start_mib * MIB_SIZE && (have_partition_in_range (table, + start_mib * MIB_SIZE, + end_bytes) || + (end_bytes > udisks_block_get_size (block) - 33*512))) { - end_mib -= 1L; + /* TODO: if end_bytes is sufficiently big this could be *a lot* of loop iterations + * and thus a potential DoS attack... + */ + end_bytes -= 512L; } - wait_data->pos_to_wait_for = (start_mib + end_mib) * MIB_SIZE / 2L; + wait_data->pos_to_wait_for = (start_mib*MIB_SIZE + end_bytes) / 2L; command_line = g_strdup_printf ("parted --align optimal --script \"%s\" " - "\"mkpart \\\"%s\\\" ext2 %" G_GUINT64_FORMAT "MiB %" G_GUINT64_FORMAT "MiB\"", + "\"mkpart \\\"%s\\\" ext2 %" G_GUINT64_FORMAT "MiB %" G_GUINT64_FORMAT "b\"", escaped_device, escaped_escaped_name, start_mib, - end_mib); + end_bytes); g_free (escaped_escaped_name); g_free (escaped_name); } -- 2.7.4