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
This commit is contained in:
Mike Fleetwood 2019-05-08 16:29:13 +01:00 committed by Curtis Gedak
parent 45d046fc8b
commit 406beaaed0
3 changed files with 10 additions and 1 deletions

View File

@ -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 );

View File

@ -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 ;

View File

@ -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() ;