[gparted] Use previous unallocated partition when determining 1 MiB reservation in resize/move dialog



commit eaaa5719f76d4ad8af74c3e95baa9a7d37716f40
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Wed Oct 20 22:33:03 2021 +0100

    Use previous unallocated partition when determining 1 MiB reservation in resize/move dialog
    
    The create new and paste into new dialogs are both composing a new
    partition into the unallocated selected_partition they are passed.  The
    starting sector of this unallocated partition is the first sector the
    newly composed partition could possibly have.  To ensure it doesn't
    overlay with the partition table or EBR (Extended Boot Records) it calls
    MB_Needed_for_Boot_Record() to indicate if the first 1 MiB needs to be
    reserved in the dialog or not.
    
    Code:
        Dialog_Partition_New::set_data(..., selected_partition, ...)
            ...
            MIN_SPACE_BEFORE_MB = Dialog_Base_Partition::MB_Needed_for_Boot_Record(selected_partition);
    
        Dialog_Partition_Copy::set_data(selected_partition, ...)
            ...
            MIN_SPACE_BEFORE_MB = Dialog_Base_Partition::MB_Needed_for_Boot_Record(selected_partition);
    
    However the resize/move dialog is different.  It is passed the existing
    selected_partition object and the vector of partitions from which it
    determines if there is a previous unallocated partition object or not.
    When there is no previous unallocated partition object, there is no need
    to reserve 1 MiB because the selected_partition can't be moved further
    to the left.  In the other case when there is a previous unallocated
    partition object the start of the existing selected_partition can be
    moved to the left.  However the code passes the selected_partition
    object to MB_Needed_for_Boot_Record() so doesn't have the first sector
    the newly composed partition could possibly have so doesn't reserve the
    first 1 MiB to prevent it overlapping with the partition table at the
    start of the drive.  These two commits addressed this limitation:
    * Ensure 1 MiB reserved when moving extended partition to start of drive
    * Ensure 1 MiB reserved when moving partition to start of disk
    
    Code:
        Dialog_Partition_Resize_Move::set_data(selected_partition, ...)
            new_partition = selected_partition.clone();
            if (selected_partition.type == TYPE_EXTENDED)
                Resize_Move_Extended(...);
            else
                Resoze_Move_Normal(...);
    
        Dialog_Partition_Resize_Move::Resize_Move_Normal(...)
            ...
            if (previous <= 0)
                MIN_SPACE_BEFORE_MB = 0;
            else
            {
                if (START < MEBIBYTE / new_partition->sector_size)
                    MIN_SPACE_BEFORE_MB = 1;
                else
                    MIN_SPACE_BEFORE_MB = Dialog_Base_Partition::MB_Needed_for_Boot_Record(*new_partition);
            }
    
        Dialog_Partition_Resize_Move::Resize_Move_Extended(...)
            ...
            if (previous <= 0)
                MIN_SPACE_BEFORE_MB = 0;
            else
            {
                if (START < MEBIBYTE / new_partition->sector_size)
                    MIN_SPACE_BEFORE_MB = 1;
                else
                    MIN_SPACE_BEFORE_MB = Dialog_Base_Partition::MB_Needed_for_Boot_Record(*new_partition);
            }
    
    So instead pass the previous unallocated partition object as that
    contains the left most start sector the newly composed partition could
    possibly have, therefore the check for overlapping the partition table
    in the first 1 MiB of the drive can succeed.

 src/Dialog_Partition_Resize_Move.cc | 37 +++++++++++++++++--------------------
 1 file changed, 17 insertions(+), 20 deletions(-)
---
diff --git a/src/Dialog_Partition_Resize_Move.cc b/src/Dialog_Partition_Resize_Move.cc
index 3064ea1b..dd5bd85d 100644
--- a/src/Dialog_Partition_Resize_Move.cc
+++ b/src/Dialog_Partition_Resize_Move.cc
@@ -118,11 +118,13 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const PartitionVector & p
 
        Sector previous, next ;
        previous = next = 0 ;
+       const Partition* prev_unalloc_partition = NULL;
        //also check the partitions file system ( if this is a 'resize-only' then previous should be 0 )      
  
        if (t >= 1 && partitions[t-1].type == TYPE_UNALLOCATED && ! this->fixed_start)
        { 
                previous = partitions[t -1] .get_sector_length() ;
                START = partitions[t -1] .sector_start ;
+               prev_unalloc_partition = &partitions[t-1];
        } 
        else
                START = new_partition->sector_start;
@@ -152,18 +154,14 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const PartitionVector & p
                }
        }
 
-       //Only calculate MIN_SPACE_BEFORE_MB if we have a previous (unallocated) partition.
-       //  Otherwise there will not be enough graphical space to reserve a full 1 MiB for MBR/EBR.
-       //  Since this is an existing partition, if an MBR/EBR was needed then it already exists with enough 
space.
-       if ( previous <= 0 )
+       // Only need to use MIN_SPACE_BEFORE_MB to reserve 1 MiB to protect the partition
+       // table or EBR if there is a previous unallocated partition allowing the start of
+       // this selected partition to be resize/moved to the left.
+       if (prev_unalloc_partition == NULL)
                MIN_SPACE_BEFORE_MB = 0 ;
        else
-       {
-               if (START < MEBIBYTE / new_partition->sector_size)
-                       MIN_SPACE_BEFORE_MB = 1 ;
-               else
-                       MIN_SPACE_BEFORE_MB = Dialog_Base_Partition::MB_Needed_for_Boot_Record( 
*new_partition );
-       }
+               MIN_SPACE_BEFORE_MB = 
Dialog_Base_Partition::MB_Needed_for_Boot_Record(*prev_unalloc_partition);
+
        total_length = previous + new_partition->get_sector_length() + next;
        TOTAL_MB = Utils::round( Utils::sector_to_unit( total_length, new_partition->sector_size, UNIT_MIB ) 
);
        
@@ -245,11 +243,13 @@ void Dialog_Partition_Resize_Move::Resize_Move_Extended( const PartitionVector &
 
        Sector previous, next ;
        previous = next = 0 ;
+       const Partition* prev_unalloc_partition = NULL;
        //calculate length and start of previous
        if (t > 0 && partitions[t-1].type == TYPE_UNALLOCATED)
        {
                previous = partitions[t -1] .get_sector_length() ;
                START = partitions[t -1] .sector_start ;
+               prev_unalloc_partition = &partitions[t-1];
        } 
        else
                START = new_partition->sector_start;
@@ -259,18 +259,15 @@ void Dialog_Partition_Resize_Move::Resize_Move_Extended( const PartitionVector &
                next = partitions[ t +1 ] .get_sector_length() ;
                
        //now we have enough data to calculate some important values..
-       //Only calculate MIN_SPACE_BEFORE_MB if we have a previous (unallocated) partition.
-       //  Otherwise there will not be enough graphical space to reserve a full 1 MiB for MBR/EBR.
-       //  Since this is an existing partition, if an MBR/EBR was needed then it already exists with enough 
space.
-       if ( previous <= 0 )
+
+       // Only need to use MIN_SPACE_BEFORE_MB to reserve 1 MiB to protect the partition
+       // table or EBR if there is a previous unallocated partition allowing the start of
+       // this selected partition to be resize/moved to the left.
+       if (prev_unalloc_partition == NULL)
                MIN_SPACE_BEFORE_MB = 0 ;
        else
-       {
-               if (START < MEBIBYTE / new_partition->sector_size)
-                       MIN_SPACE_BEFORE_MB = 1;
-               else
-                       MIN_SPACE_BEFORE_MB = 
Dialog_Base_Partition::MB_Needed_for_Boot_Record(*new_partition);
-       }
+               MIN_SPACE_BEFORE_MB = 
Dialog_Base_Partition::MB_Needed_for_Boot_Record(*prev_unalloc_partition);
+
        total_length = previous + new_partition->get_sector_length() + next;
        TOTAL_MB = Utils::round( Utils::sector_to_unit( total_length, new_partition->sector_size, UNIT_MIB ) 
);
        MB_PER_PIXEL = TOTAL_MB / 500.00 ;


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