[gparted] Fix problem with logical partition move overwriting EBR (#623630)



commit c3a06ffd6c410463cca9d10472fcb8a9bcddefb6
Author: Curtis Gedak <gedakc gmail com>
Date:   Thu Jul 22 17:12:57 2010 -0600

    Fix problem with logical partition move overwriting EBR (#623630)
    
    Prevent overwriting meta data (Extended Boot Rectors) for logical
    partitions by temporarily increasing the size of the logical
    partition to encompass all of the space involved in the move
    operation.  The libparted library will move the EBR as needed to
    permit this to happen.  After the move the logical partition is
    set to the proper size.
    
    This fixes bug #623630 - Move logical partition to right yields
    invalid partition table on /dev/sda - wrong signature 0

 src/GParted_Core.cc |   46 +++++++++++++++++++++++++++++-----------------
 1 files changed, 29 insertions(+), 17 deletions(-)
---
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 966900a..3009b6f 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1721,29 +1721,41 @@ bool GParted_Core::move( const Device & device,
 	bool succes = false ;
 	if ( check_repair_filesystem( partition_old, operationdetail ) )
 	{
-		//NOTE: logical partitions are preceeded by metadata. To prevent this metadata from being
-		//overwritten we move the partition first and only then the file system when moving to the left.
-		//(maybe i should do some reading on how non-msdos disklabels deal with metadata....)
-		if ( partition_new .sector_start < partition_old .sector_start )
+		//NOTE: Logical partitions are preceded by meta data.  To prevent this
+		//      meta data from being overwritten we first expand the partition to
+		//      encompass all of the space involved in the move.  In this way we
+		//      prevent overwriting the meta data for this partition when we move
+		//      this partition to the left.  We also prevent overwriting the meta
+		//      data of a following partition when we move this partition to the
+		//      right.
+		Partition partition_all_space = partition_old ;
+		partition_all_space .alignment = ALIGN_STRICT ;
+		if ( partition_new .sector_start < partition_all_space. sector_start )
+			partition_all_space .sector_start = partition_new. sector_start ;
+		if ( partition_new .sector_end > partition_all_space.sector_end )
+			partition_all_space .sector_end = partition_new. sector_end ;
+
+		//Make old partition all encompassing and if move file system fails
+		//  then return partition table to original state
+		if ( resize_move_partition( partition_old, partition_all_space, operationdetail ) )
 		{
-			if ( resize_move_partition( partition_old, partition_new, operationdetail ) )
+			//Note move of file system is from old values to new values, not from
+			//  the all encompassing values.
+			if ( ! move_filesystem( partition_old, partition_new, operationdetail ) )
 			{
-				if ( ! move_filesystem( partition_old, partition_new, operationdetail ) )
-				{
-					operationdetail .add_child( OperationDetail( _("rollback last change to the partition table") ) ) ;
+				operationdetail .add_child( OperationDetail( _("rollback last change to the partition table") ) ) ;
 
-					if ( resize_move_partition( partition_new, partition_old, operationdetail .get_last_child() ) )
-						operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
-					else
-						operationdetail .get_last_child() .set_status( STATUS_ERROR ) ;
-				}
+				if ( resize_move_partition( partition_all_space, partition_old, operationdetail .get_last_child() ) )
+					operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
 				else
-					succes = true ;
+					operationdetail .get_last_child() .set_status( STATUS_ERROR ) ;
 			}
+			else
+				succes = true ;
 		}
-		else
-			succes = move_filesystem( partition_old, partition_new, operationdetail ) &&
-				resize_move_partition( partition_old, partition_new, operationdetail ) ;
+
+		//Make new partition from all encompassing partition
+		succes =  succes && resize_move_partition( partition_all_space, partition_new, operationdetail ) ;
 
 		succes = succes &&
 			update_bootsector( partition_new, operationdetail ) &&



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