[gparted] Separate partition alignment from validation (#48)



commit 406beaaed0c5ba938a96528156d423db437f1b65
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Wed May 8 16:29:13 2019 +0100

    Separate partition alignment from validation (#48)
    
    PATCHSET OVERVIEW
    
    A user had 2 adjacent partitions which were aligned to multiples of
    33553920 bytes (32 MiB - 512 bytes), not MiB or cylinders.  As far as
    GParted is concerned this is not aligned.  The second partition
    contained closed LUKS encrypted data.  Recreate this setup with:
    
        # truncate -s 200G /tmp/disk.img
        # losetup -f --show /tmp/disk.img
        /dev/loop0
        # sfdisk -u S /dev/loop0 << EOF
        65535 2162655 83
        2228190 78904140 83
        EOF
        # partprobe /dev/loop0
        # echo -n badpassword | cryptsetup luksFormat /dev/loop0p2 -
    
    When trying to move the second LUKS encrypted partition to the right by
    any amount, with the default MiB alignment, GParted displays this error
    dialog and fails to even queue the operation:
    
        Could not add this operation to the list
        A partition with used sectors (78907392) greater than its
        length (78905344) is not valid
        [                       OK                               ]
    
    Overview of the steps involved:
    
    1. The Resize/Move dialog composed a new partition to start a whole
       multiple of MiB after the end of the previous non-aligned partition.
       The new partition also had it's size increased to a whole multiple of
       MiB, to 78907392 sectors (38529 MiB) which was 1.59 MiB larger than
       before.  Neither the start or end of the new partition are aligned at
       this point.
    
    2. Win_GParted::activate_resize() applied the change back to the closed
       LUKS partition object, additionally making the used sectors equal to
       the partition size.
       (To match the fact that when opened the LUKS mapping it will
       automatically fill the new larger partition size).
    
    3. GParted_Core::snap_to_mebibyte() then aligned the partition start and
       end to whole MiB boundaries, reducing the partition size in the
       process to 78905344 (38528 MiB).
    
    4. GParted_Core::snap_to_alignment() reported the error saying that it
       couldn't add the operation to the list because it was invalid to have
       the file system used sectors larger than the partition size.
    
    Fix this by having the snap to alignment adjustments applied before the
    dialogs update any associated file system usage.  Specifically the
    Resize/Move, Paste (into new) and Create New dialogs as these are the
    only ones which either create or modify partition boundaries.
    Validation done by snap_to_alignment() will continue to occur at the
    current point when the operation is added to the list.
    
    THIS COMMIT
    
    snap_to_alignment() is doing two different jobs, it is (1) optionally
    adjusting the new partition boundaries for MiB or Cylinder alignment;
    and (2) checking that the partition boundaries and file system usage are
    valid.
    
    Split those into two different functions (1) snap_to_alignment() and
    (2) valid_partition().  For now valid_partition() still calls
    snap_to_alignment() so there is no functional change with this commit.
    
    Closes #48 - Error when moving locked LUKS-encrypted partition

 include/GParted_Core.h | 1 +
 src/GParted_Core.cc    | 8 ++++++++
 src/Win_GParted.cc     | 2 +-
 3 files changed, 10 insertions(+), 1 deletion(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index f598651d..ba445d17 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -54,6 +54,7 @@ public:
        bool snap_to_cylinder( const Device & device, Partition & partition, Glib::ustring & error ) ;
        bool snap_to_mebibyte( const Device & device, Partition & partition, Glib::ustring & error ) ;
        bool snap_to_alignment( const Device & device, Partition & partition, Glib::ustring & error ) ;
+       bool valid_partition(const Device& device, Partition& partition, Glib::ustring& error);
        bool apply_operation_to_disk( Operation * operation );
 
        bool set_disklabel( const Device & device, const Glib::ustring & disklabel );
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 0f547b89..110c7fbd 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -545,6 +545,14 @@ bool GParted_Core::snap_to_alignment( const Device & device, Partition & partiti
        else if ( partition .alignment == ALIGN_MEBIBYTE )
                rc = snap_to_mebibyte( device, partition, error ) ;
 
+       return rc;
+}
+
+
+bool GParted_Core::valid_partition(const Device& device, Partition& partition, Glib::ustring& error)
+{
+       bool rc = snap_to_alignment(device, partition, error);
+
        //Ensure that partition start and end are not beyond the ends of the disk device
        if ( partition .sector_start < 0 )
                partition .sector_start = 0 ;
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index b5288e82..7e2d7138 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -841,7 +841,7 @@ void Win_GParted::Add_Operation( const Device & device, Operation * operation )
                     operation ->type == OPERATION_CHANGE_UUID ||
                     operation ->type == OPERATION_LABEL_FILESYSTEM ||
                     operation ->type == OPERATION_NAME_PARTITION ||
-                    gparted_core.snap_to_alignment( device, operation->get_partition_new(), error )
+                    gparted_core.valid_partition(device, operation->get_partition_new(), error)
                   )
                {
                        operation ->create_description() ;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]