From 406beaaed0c5ba938a96528156d423db437f1b65 Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Wed, 8 May 2019 16:29:13 +0100 Subject: [PATCH] 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() ;