[gparted] Preview resize/move operation of encrypted file systems (#774818)



commit ee1b2257d2b248f44c48af567d2dcd2af03da420
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sun Nov 13 16:59:18 2016 +0000

    Preview resize/move operation of encrypted file systems (#774818)
    
    Changing the Resize/Move dialog code to also handle PartitionLUKS
    objects was considered too complicated.  Instead create an unencrypted
    equivalent using clone_as_plain(), pass that to the Resize/Move dialog
    and finally apply the change back using Partition*::resize().
    
    Bug 774818 - Implement LUKS read-write actions NOT requiring a
                 passphrase

 include/PartitionLUKS.h |    2 +
 src/Win_GParted.cc      |   58 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 51 insertions(+), 9 deletions(-)
---
diff --git a/include/PartitionLUKS.h b/include/PartitionLUKS.h
index 7acc86b..9cefaee 100644
--- a/include/PartitionLUKS.h
+++ b/include/PartitionLUKS.h
@@ -44,6 +44,8 @@ public:
        Partition & get_encrypted()              { return encrypted; };
        const Partition & get_encrypted() const  { return encrypted; };
 
+       Sector get_header_size() const           { return header_size; };
+
        virtual bool sector_usage_known() const;
        virtual Sector estimated_min_size() const;
        virtual Sector get_sectors_used() const;
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index 9478906..9d63874 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -1790,16 +1790,56 @@ void Win_GParted::activate_resize()
                display_partitions_ptr = &display_partitions[ext].logicals;
        }
 
-       Dialog_Partition_Resize_Move dialog( gparted_core.get_fs( selected_partition_ptr->filesystem ),
-                                            *selected_partition_ptr,
-                                            *display_partitions_ptr );
+       FS fs_cap = gparted_core.get_fs( selected_partition_ptr->get_filesystem_partition().filesystem );
+       Partition * working_ptn;
+       if ( selected_partition_ptr->filesystem == FS_LUKS && selected_partition_ptr->busy )
+       {
+               const FS & enc_cap = gparted_core.get_fs( FS_LUKS );
+
+               // For an open LUKS mapping containing a file system being resized/moved
+               // create a plain Partition object with the equivalent usage for the
+               // Resize/Move dialog to work with.
+               working_ptn = static_cast<const PartitionLUKS *>( selected_partition_ptr )->clone_as_plain();
+
+               // Construct common capabilities from the file system ones.
+               // Open LUKS encryption mapping can't be moved.
+               fs_cap.move = FS::NONE;
+               // Mask out resizing not also supported by open LUKS mapping.
+               if ( ! enc_cap.online_grow )
+               {
+                       fs_cap.grow        = FS::NONE;
+                       fs_cap.online_grow = FS::NONE;
+               }
+               if ( ! enc_cap.online_shrink )
+               {
+                       fs_cap.shrink        = FS::NONE;
+                       fs_cap.online_shrink = FS::NONE;
+               }
+               // Adjust file system size limits accounting for LUKS encryption overhead.
+               Sector luks_header_size = static_cast<const PartitionLUKS *>( selected_partition_ptr 
)->get_header_size();
+               fs_cap.MIN = luks_header_size * working_ptn->sector_size +
+                            ( fs_cap.MIN < MEBIBYTE ) ? MEBIBYTE : fs_cap.MIN;
+               if ( fs_cap.MAX > 0 )
+                       fs_cap.MAX += luks_header_size * working_ptn->sector_size;
+       }
+       else
+       {
+               working_ptn = selected_partition_ptr->clone();
+       }
+
+       Dialog_Partition_Resize_Move dialog( fs_cap, *working_ptn, *display_partitions_ptr );
        dialog .set_transient_for( *this ) ;    
-                       
+
+       delete working_ptn;
+       working_ptn = NULL;
+
        if ( dialog .run() == Gtk::RESPONSE_OK )
        {
                dialog .hide() ;
 
-               Partition * part_temp = dialog.Get_New_Partition().clone();
+               // Apply resize/move from the dialog to a copy of the selected partition.
+               Partition * resized_ptn = selected_partition_ptr->clone();
+               resized_ptn->resize( dialog.Get_New_Partition() );
 
                // When resizing/moving a partition which already exists on the disk all
                // possible operations could be pending so only try merging with the
@@ -1810,7 +1850,7 @@ void Win_GParted::activate_resize()
                // it again with the new size and position ( unless it's an EXTENDED )
                if ( selected_partition_ptr->status == STAT_NEW && selected_partition_ptr->type != 
TYPE_EXTENDED )
                {
-                       part_temp->status = STAT_NEW;
+                       resized_ptn->status = STAT_NEW;
                        // On a partition which is pending creation only resize/move and
                        // format operations are possible.  These operations are always
                        // mergeable with the pending operation which will create the
@@ -1821,11 +1861,11 @@ void Win_GParted::activate_resize()
 
                Operation * operation = new OperationResizeMove( devices[current_device],
                                                                 *selected_partition_ptr,
-                                                                *part_temp );
+                                                                *resized_ptn );
                operation->icon = render_icon( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_MENU );
 
-               delete part_temp;
-               part_temp = NULL;
+               delete resized_ptn;
+               resized_ptn = NULL;
 
                // Display warning if moving a non-extended partition which already exists
                // on the disk.


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