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
This commit is contained in:
Curtis Gedak 2010-07-22 17:12:57 -06:00
parent a92f2dad39
commit c3a06ffd6c
1 changed files with 31 additions and 19 deletions

View File

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