Fix snap-to-alignment of operations creating partitions (#779339)

Using the default MiB alignment, creating an MSDOS logical partition
between two other existing logical partitions fails with this error
dialog:

    (-) <b>An error occurred while applying the operations</b>
        See the details for more information.
        <b>IMPORTANT</b>
        If you want support, you need to provide the saved details!
        See http://gparted.org/save-details.htm for more information.
                                                               [ OK ]

and these operation details:

    + libparted messages
      - Unable to satisfy all constraints on the partition.

This bug was introduced by this commit included in GParted 0.23.0:
    90e3ed68fc
    Shallow copy Device object into Operation object (#750168)

The commit message claimed that the deep copied Partition objects inside
the Device inside the Operation object are never accessed.  This turned
out not to be true.  Win_GParted::Add_Operation() uses them as part of
snap_to_alignment() which updates requested partition boundaries to
account for alignment requirements and the space needed for EBR
(Extended Boot Record) preceding logical partitions.

In this case the new logical partition was trying to be created over the
top of the EBR for the following logical partition because
snap_to_alignment() wasn't aware of its existence.

Fix by making Add_Operation() and snap_to_alignment() refer to the
current device, as displayed in the UI, rather than the shallow copy
included in the Operation object.  Hopefully now it is true that the
not copied vector of Partition objects in the Device object in each
Operation object are never accessed.

Bug 779339 - enforce at least 1 MiB "free space following"
This commit is contained in:
Mike Fleetwood 2017-04-21 08:30:39 +01:00 committed by Curtis Gedak
parent e31c96adc8
commit 75131d85a5
2 changed files with 13 additions and 13 deletions

View File

@ -70,7 +70,7 @@ private:
//Fill txtview_device_info_buffer with some information about the selected device
void Fill_Label_Device_Info( bool clear = false );
void Add_Operation( Operation * operation );
void Add_Operation( const Device & device, Operation * operation );
bool merge_two_operations( unsigned int first, unsigned int second );
void merge_operations( MergeType mergetype );
void Refresh_Visual();

View File

@ -711,7 +711,7 @@ bool Win_GParted::on_delete_event( GdkEventAny *event )
return ! Quit_Check_Operations();
}
void Win_GParted::Add_Operation( Operation * operation )
void Win_GParted::Add_Operation( const Device & device, Operation * operation )
{
if ( operation )
{
@ -726,7 +726,7 @@ void Win_GParted::Add_Operation( Operation * operation )
operation ->type == OPERATION_CHANGE_UUID ||
operation ->type == OPERATION_LABEL_FILESYSTEM ||
operation ->type == OPERATION_NAME_PARTITION ||
gparted_core.snap_to_alignment( operation->device, operation->get_partition_new(), error )
gparted_core.snap_to_alignment( device, operation->get_partition_new(), error )
)
{
operation ->create_description() ;
@ -1895,7 +1895,7 @@ void Win_GParted::activate_resize()
dialog.run();
}
Add_Operation( operation );
Add_Operation( devices[current_device], operation );
merge_operations( mergetype );
}
@ -1962,7 +1962,7 @@ void Win_GParted::activate_paste()
String::ucompose( _("Copy of %1"),
copy_op->get_partition_copied().get_path() ) );
Add_Operation( operation ) ;
Add_Operation( devices[current_device], operation );
}
}
}
@ -2045,7 +2045,7 @@ void Win_GParted::activate_paste()
delete partition_new;
partition_new = NULL;
Add_Operation( operation ) ;
Add_Operation( devices[current_device], operation );
if ( ! shown_dialog )
{
@ -2102,7 +2102,7 @@ void Win_GParted::activate_new()
dialog.Get_New_Partition() );
operation ->icon = render_icon( Gtk::Stock::NEW, Gtk::ICON_SIZE_MENU );
Add_Operation( operation );
Add_Operation( devices[current_device], operation );
show_operationslist() ;
}
@ -2216,7 +2216,7 @@ void Win_GParted::activate_delete()
Operation * operation = new OperationDelete( devices[ current_device ], *selected_partition_ptr );
operation ->icon = render_icon( Gtk::Stock::DELETE, Gtk::ICON_SIZE_MENU ) ;
Add_Operation( operation ) ;
Add_Operation( devices[current_device], operation );
}
show_operationslist() ;
@ -2363,7 +2363,7 @@ void Win_GParted::activate_format( GParted::FILESYSTEM new_fs )
delete temp_ptn;
temp_ptn = NULL;
Add_Operation( operation );
Add_Operation( devices[current_device], operation );
merge_operations( mergetype );
show_operationslist() ;
@ -2814,7 +2814,7 @@ void Win_GParted::activate_check()
operation ->icon = render_icon( Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU );
Add_Operation( operation ) ;
Add_Operation( devices[current_device], operation );
// Try to merge this check operation with all previous operations.
merge_operations( MERGE_LAST_WITH_ANY );
@ -2846,7 +2846,7 @@ void Win_GParted::activate_label_filesystem()
delete part_temp;
part_temp = NULL;
Add_Operation( operation ) ;
Add_Operation( devices[current_device], operation );
// Try to merge this label file system operation with all previous
// operations.
merge_operations( MERGE_LAST_WITH_ANY );
@ -2880,7 +2880,7 @@ void Win_GParted::activate_name_partition()
delete part_temp;
part_temp = NULL;
Add_Operation( operation );
Add_Operation( devices[current_device], operation );
// Try to merge this name partition operation with all previous
// operations.
merge_operations( MERGE_LAST_WITH_ANY );
@ -2938,7 +2938,7 @@ void Win_GParted::activate_change_uuid()
delete temp_ptn;
temp_ptn = NULL;
Add_Operation( operation ) ;
Add_Operation( devices[current_device], operation );
// Try to merge this change UUID operation with all previous operations.
merge_operations( MERGE_LAST_WITH_ANY );