File parted-improve-fallback-logic-when-placing-partiton.patch of Package parted.3440

From ee555f57174194619bd6950396b12db65139ff7f Mon Sep 17 00:00:00 2001
From: Petr Uzel <petr.uzel@suse.cz>
Date: Mon, 23 Feb 2015 10:11:52 +0100
Subject: [PATCH] parted: Improve fallback logic when placing partiton

When parted fails satisfy contraints when creating the partition, e.g.
if the optimal_io_size is too large, it falls back to logic
which places the partition more or less arbitrarily.

Improve the backup logic - try 1MiB alignment if the previous attempt
failed.

References: https://apibugzilla.novell.com/show_bug.cgi?id=914852
---
 parted/parted.c |   36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

Index: parted-3.1/parted/parted.c
===================================================================
--- parted-3.1.orig/parted/parted.c
+++ parted-3.1/parted/parted.c
@@ -659,6 +659,7 @@ do_mkpart (PedDevice** dev)
         char*                    part_name = NULL;
         char                     *start_usr = NULL, *end_usr = NULL;
         char                     *start_sol = NULL, *end_sol = NULL;
+        bool                    retry_with_1MiB_alignment = false;
 
         disk = ped_disk_new (*dev);
         if (!disk)
@@ -735,6 +736,8 @@ do_mkpart (PedDevice** dev)
                 dev_constraint = ped_device_get_constraint(*dev);
         PED_ASSERT (dev_constraint != NULL);
 
+        retry_with_1MiB_alignment = (dev_constraint->start_align->grain_size > 2048);
+
         final_constraint = ped_constraint_intersect (user_constraint,
                         dev_constraint);
         ped_constraint_destroy (user_constraint);
@@ -749,10 +752,35 @@ do_mkpart (PedDevice** dev)
         if (!added_ok) {
                 ped_exception_leave_all();
 
-                PedConstraint *constraint_any = ped_constraint_any (*dev);
-                added_ok = ped_disk_add_partition (disk, part,
-                                                        constraint_any);
-                ped_constraint_destroy (constraint_any);
+                /* Try again with a constraint corresponding to 1MiB optimal alignment */
+                if (retry_with_1MiB_alignment && alignment == ALIGNMENT_OPTIMAL) {
+
+                        dev_constraint = ped_device_get_optimal_aligned_constraint(*dev);
+                        PED_ASSERT (dev_constraint != NULL);
+
+                        user_constraint = constraint_from_start_end (*dev, range_start, range_end);
+                        PED_ASSERT (user_constraint != NULL);
+
+                        /* Change alignment constraints to multiples of 1MiB */
+                        dev_constraint->start_align->grain_size = 2048;
+                        dev_constraint->end_align->grain_size = 2048;
+
+                        final_constraint = ped_constraint_intersect (user_constraint, dev_constraint);
+
+                        ped_constraint_destroy (user_constraint);
+                        ped_constraint_destroy (dev_constraint);
+
+                        added_ok = ped_disk_add_partition (disk, part, final_constraint);
+                        ped_constraint_destroy (final_constraint);
+                }
+
+                /* Last chance - any constraint */
+                if (!added_ok) {
+                        PedConstraint *constraint_any = ped_constraint_any (*dev);
+                        added_ok = ped_disk_add_partition (disk, part,
+                                                                constraint_any);
+                        ped_constraint_destroy (constraint_any);
+                }
 
                 if (!added_ok)
                         goto error_remove_part;
openSUSE Build Service is sponsored by