Snap partition boundaries before dialogs update FS usage (#48)
Move snap_to_*() method calls from the point when all operations are added to the list, to earlier when Resize/Move, Paste (into new) and Create New dialogs are composing the new partition objects. In particular for the Resize/Move operation, to just before updating the file system usage. This change finally resolves this bug. Because of the dialog call chains into Dialog_Base_Partition, snap_to_alignment() must be added into: * Dialog_Base_Partition::prepare_new_partition() for the Resize/Move and Paste (into new) dialogs; and * Dialog_Partition_New::Get_New_Partition() for the Create New dialog. Closes #48 - Error when moving locked LUKS-encrypted partition
This commit is contained in:
parent
3222c8dd1a
commit
7c94b7d920
|
@ -59,6 +59,9 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
void prepare_new_partition();
|
void prepare_new_partition();
|
||||||
|
static void snap_to_alignment(const Device& device, Partition& partition);
|
||||||
|
static void snap_to_cylinder(const Device& device, Partition& partition);
|
||||||
|
static void snap_to_mebibyte(const Device& device, Partition& partition);
|
||||||
|
|
||||||
void Set_Confirm_Button( CONFIRMBUTTON button_type ) ;
|
void Set_Confirm_Button( CONFIRMBUTTON button_type ) ;
|
||||||
void Set_MinMax_Text( Sector min, Sector max ) ;
|
void Set_MinMax_Text( Sector min, Sector max ) ;
|
||||||
|
|
|
@ -51,9 +51,6 @@ public:
|
||||||
void set_devices_thread( std::vector<Device> * pdevices );
|
void set_devices_thread( std::vector<Device> * pdevices );
|
||||||
void guess_partition_table(const Device & device, Glib::ustring &buff);
|
void guess_partition_table(const Device & device, Glib::ustring &buff);
|
||||||
|
|
||||||
void snap_to_cylinder(const Device& device, Partition& partition);
|
|
||||||
void snap_to_mebibyte(const Device& device, Partition& partition);
|
|
||||||
void snap_to_alignment(const Device& device, Partition& partition);
|
|
||||||
bool valid_partition(const Device& device, Partition& partition, Glib::ustring& error);
|
bool valid_partition(const Device& device, Partition& partition, Glib::ustring& error);
|
||||||
bool apply_operation_to_disk( Operation * operation );
|
bool apply_operation_to_disk( Operation * operation );
|
||||||
|
|
||||||
|
|
|
@ -200,8 +200,7 @@ void Dialog_Base_Partition::prepare_new_partition()
|
||||||
// If partition size is not an integer multiple of MiB or
|
// If partition size is not an integer multiple of MiB or
|
||||||
// the start or end sectors are not MiB aligned, and space
|
// the start or end sectors are not MiB aligned, and space
|
||||||
// is available, then add 1 MiB to partition so requested
|
// is available, then add 1 MiB to partition so requested
|
||||||
// size is kept after GParted_Core::snap_to_mebibyte
|
// size is kept after snap_to_mebibyte() method rounding.
|
||||||
// method rounding.
|
|
||||||
Sector partition_size = new_partition->sector_end - new_partition->sector_start + 1;
|
Sector partition_size = new_partition->sector_end - new_partition->sector_start + 1;
|
||||||
Sector sectors_in_mib = MEBIBYTE / new_partition->sector_size;
|
Sector sectors_in_mib = MEBIBYTE / new_partition->sector_size;
|
||||||
if ( ( ( partition_size % sectors_in_mib > 0 )
|
if ( ( ( partition_size % sectors_in_mib > 0 )
|
||||||
|
@ -228,6 +227,8 @@ void Dialog_Base_Partition::prepare_new_partition()
|
||||||
if ( ORIG_BEFORE == spinbutton_before .get_value_as_int() )
|
if ( ORIG_BEFORE == spinbutton_before .get_value_as_int() )
|
||||||
new_partition->strict_start = TRUE;
|
new_partition->strict_start = TRUE;
|
||||||
|
|
||||||
|
snap_to_alignment(m_device, *new_partition);
|
||||||
|
|
||||||
//update partition usage
|
//update partition usage
|
||||||
if ( new_partition->sector_usage_known() )
|
if ( new_partition->sector_usage_known() )
|
||||||
{
|
{
|
||||||
|
@ -250,6 +251,222 @@ void Dialog_Base_Partition::prepare_new_partition()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dialog_Base_Partition::snap_to_alignment(const Device& device, Partition& partition)
|
||||||
|
{
|
||||||
|
if (partition.alignment == ALIGN_CYLINDER)
|
||||||
|
snap_to_cylinder(device, partition);
|
||||||
|
else if (partition.alignment == ALIGN_MEBIBYTE)
|
||||||
|
snap_to_mebibyte(device, partition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dialog_Base_Partition::snap_to_cylinder(const Device& device, Partition& partition)
|
||||||
|
{
|
||||||
|
Sector diff = 0;
|
||||||
|
|
||||||
|
//Determine if partition size is less than half a disk cylinder
|
||||||
|
bool less_than_half_cylinder = false;
|
||||||
|
if ( ( partition .sector_end - partition .sector_start ) < ( device .cylsize / 2 ) )
|
||||||
|
less_than_half_cylinder = true;
|
||||||
|
|
||||||
|
if ( partition.type == TYPE_LOGICAL ||
|
||||||
|
partition.sector_start == device .sectors
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//Must account the relative offset between:
|
||||||
|
// (A) the Extended Boot Record sector and the next track of the
|
||||||
|
// logical partition (usually 63 sectors), and
|
||||||
|
// (B) the Master Boot Record sector and the next track of the first
|
||||||
|
// primary partition
|
||||||
|
diff = (partition .sector_start - device .sectors) % device .cylsize ;
|
||||||
|
}
|
||||||
|
else if ( partition.sector_start == 34 )
|
||||||
|
{
|
||||||
|
// (C) the GUID Partition Table (GPT) and the start of the data
|
||||||
|
// partition at sector 34
|
||||||
|
diff = (partition .sector_start - 34 ) % device .cylsize ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
diff = partition .sector_start % device .cylsize ;
|
||||||
|
}
|
||||||
|
if ( diff && ! partition .strict_start )
|
||||||
|
{
|
||||||
|
if ( diff < ( device .cylsize / 2 ) || less_than_half_cylinder )
|
||||||
|
partition .sector_start -= diff ;
|
||||||
|
else
|
||||||
|
partition .sector_start += (device .cylsize - diff ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff = (partition .sector_end +1) % device .cylsize ;
|
||||||
|
if ( diff )
|
||||||
|
{
|
||||||
|
if ( diff < ( device .cylsize / 2 ) && ! less_than_half_cylinder )
|
||||||
|
partition .sector_end -= diff ;
|
||||||
|
else
|
||||||
|
partition .sector_end += (device .cylsize - diff ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dialog_Base_Partition::snap_to_mebibyte(const Device& device, Partition& partition)
|
||||||
|
{
|
||||||
|
Sector diff = 0;
|
||||||
|
if ( partition .sector_start < 2 || partition .type == TYPE_LOGICAL )
|
||||||
|
{
|
||||||
|
//Must account the relative offset between:
|
||||||
|
// (A) the Master Boot Record sector and the first primary/extended partition, and
|
||||||
|
// (B) the Extended Boot Record sector and the logical partition
|
||||||
|
|
||||||
|
//If strict_start is set then do not adjust sector start.
|
||||||
|
//If this partition is not simply queued for a reformat then
|
||||||
|
// add space minimum to force alignment to next mebibyte.
|
||||||
|
if ( (! partition .strict_start)
|
||||||
|
&& (partition .free_space_before == 0)
|
||||||
|
&& ( partition .status != STAT_FORMATTED)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//Unless specifically told otherwise, the Linux kernel considers extended
|
||||||
|
// boot records to be two sectors long, in order to "leave room for LILO".
|
||||||
|
partition .sector_start += 2 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calculate difference offset from Mebibyte boundary
|
||||||
|
diff = Sector(partition .sector_start % ( MEBIBYTE / partition .sector_size ));
|
||||||
|
|
||||||
|
//Align start sector only if permitted to change start sector
|
||||||
|
if ( diff && ( (! partition .strict_start)
|
||||||
|
|| ( partition .strict_start
|
||||||
|
&& ( partition .status == STAT_NEW
|
||||||
|
|| partition .status == STAT_COPY
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
partition .sector_start += ( (MEBIBYTE / partition .sector_size) - diff) ;
|
||||||
|
|
||||||
|
//If this is an extended partition then check to see if sufficient space is
|
||||||
|
// available for any following logical partition Extended Boot Record
|
||||||
|
if ( partition .type == TYPE_EXTENDED )
|
||||||
|
{
|
||||||
|
//If there is logical partition that starts less than 2 sectors
|
||||||
|
// from the start of this partition, then reserve a mebibyte for the EBR.
|
||||||
|
int index_extended = find_extended_partition( device.partitions );
|
||||||
|
if ( index_extended >= 0 )
|
||||||
|
{
|
||||||
|
for ( unsigned int t = 0; t < device .partitions[ index_extended ] .logicals .size(); t++ )
|
||||||
|
{
|
||||||
|
if ( ( device .partitions[ index_extended ] .logicals[ t ] .type == TYPE_LOGICAL )
|
||||||
|
&& ( ( ( device .partitions[ index_extended ] .logicals[ t ] .sector_start )
|
||||||
|
- ( partition .sector_start )
|
||||||
|
)
|
||||||
|
//Unless specifically told otherwise, the Linux kernel considers extended
|
||||||
|
// boot records to be two sectors long, in order to "leave room for LILO".
|
||||||
|
< 2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
partition .sector_start -= (MEBIBYTE / partition .sector_size) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Align end sector
|
||||||
|
diff = (partition .sector_end + 1) % ( MEBIBYTE / partition .sector_size);
|
||||||
|
if ( diff )
|
||||||
|
partition .sector_end -= diff ;
|
||||||
|
|
||||||
|
//If this is a logical partition not at end of drive then check to see if space is
|
||||||
|
// required for a following logical partition Extended Boot Record
|
||||||
|
if ( partition .type == TYPE_LOGICAL )
|
||||||
|
{
|
||||||
|
//If there is a following logical partition that starts less than 2 sectors from
|
||||||
|
// the end of this partition, then reserve at least a mebibyte for the EBR.
|
||||||
|
int index_extended = find_extended_partition( device.partitions );
|
||||||
|
if ( index_extended >= 0 )
|
||||||
|
{
|
||||||
|
for ( unsigned int t = 0; t < device .partitions[ index_extended ] .logicals .size(); t++ )
|
||||||
|
{
|
||||||
|
if ( ( device .partitions[ index_extended ] .logicals[ t ] .type == TYPE_LOGICAL )
|
||||||
|
&& ( device .partitions[ index_extended ] .logicals[ t ] .sector_start > partition .sector_end )
|
||||||
|
&& ( ( device .partitions[ index_extended ] .logicals[ t ] .sector_start - partition .sector_end )
|
||||||
|
//Unless specifically told otherwise, the Linux kernel considers extended
|
||||||
|
// boot records to be two sectors long, in order to "leave room for LILO".
|
||||||
|
< 2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
partition .sector_end -= ( MEBIBYTE / partition .sector_size ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the logical partition end is beyond the end of the extended partition
|
||||||
|
// then reduce logical partition end by a mebibyte to address the overlap.
|
||||||
|
if ( ( index_extended != -1 )
|
||||||
|
&& ( partition .sector_end > device .partitions[ index_extended ] .sector_end )
|
||||||
|
)
|
||||||
|
partition .sector_end -= ( MEBIBYTE / partition .sector_size ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If this is a primary or an extended partition and the partition overlaps
|
||||||
|
// the start of the next primary or extended partition then subtract a
|
||||||
|
// mebibyte from the end of the partition to address the overlap.
|
||||||
|
if ( partition .type == TYPE_PRIMARY || partition .type == TYPE_EXTENDED )
|
||||||
|
{
|
||||||
|
for ( unsigned int t = 0 ; t < device .partitions .size() ; t++ )
|
||||||
|
{
|
||||||
|
if ( ( device .partitions[ t ] .type == TYPE_PRIMARY
|
||||||
|
|| device .partitions[ t ] .type == TYPE_EXTENDED
|
||||||
|
)
|
||||||
|
&& ( //For a change to an existing partition, (e.g., move or resize)
|
||||||
|
// skip comparing to original partition and
|
||||||
|
// only compare to other existing partitions
|
||||||
|
partition .status == STAT_REAL
|
||||||
|
&& partition .partition_number != device. partitions[ t ] .partition_number
|
||||||
|
)
|
||||||
|
&& ( device .partitions[ t ] .sector_start > partition .sector_start )
|
||||||
|
&& ( device .partitions[ t ] .sector_start <= partition .sector_end )
|
||||||
|
)
|
||||||
|
partition .sector_end -= ( MEBIBYTE / partition .sector_size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If this is an extended partition then check to see if the end of the
|
||||||
|
// extended partition encompasses the end of the last logical partition.
|
||||||
|
if ( partition .type == TYPE_EXTENDED )
|
||||||
|
{
|
||||||
|
//If there is logical partition that has an end sector beyond the
|
||||||
|
// end of the extended partition, then set the extended partition
|
||||||
|
// end sector to be the same as the end of the logical partition.
|
||||||
|
for ( unsigned int t = 0; t < partition .logicals .size(); t++ )
|
||||||
|
{
|
||||||
|
if ( ( partition .logicals[ t ] .type == TYPE_LOGICAL )
|
||||||
|
&& ( ( partition .logicals[ t ] .sector_end )
|
||||||
|
> ( partition .sector_end )
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
partition .sector_end = partition .logicals[ t ] .sector_end ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If this is a GPT partition table and the partition ends less than 34 sectors
|
||||||
|
// from the end of the device, then reserve at least a mebibyte for the
|
||||||
|
// backup partition table
|
||||||
|
if ( device .disktype == "gpt"
|
||||||
|
&& ( ( device .length - partition .sector_end ) < 34 )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
partition .sector_end -= ( MEBIBYTE / partition .sector_size ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type )
|
void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type )
|
||||||
{
|
{
|
||||||
switch( button_type )
|
switch( button_type )
|
||||||
|
|
|
@ -319,6 +319,8 @@ const Partition & Dialog_Partition_New::Get_New_Partition()
|
||||||
new_partition->logicals.push_back_adopt( unallocated );
|
new_partition->logicals.push_back_adopt( unallocated );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dialog_Base_Partition::snap_to_alignment(m_device, *new_partition);
|
||||||
|
|
||||||
return *new_partition;
|
return *new_partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,225 +329,8 @@ Glib::ustring GParted_Core::get_thread_status_message( )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GParted_Core::snap_to_cylinder(const Device& device, Partition& partition)
|
|
||||||
{
|
|
||||||
Sector diff = 0;
|
|
||||||
|
|
||||||
//Determine if partition size is less than half a disk cylinder
|
|
||||||
bool less_than_half_cylinder = false;
|
|
||||||
if ( ( partition .sector_end - partition .sector_start ) < ( device .cylsize / 2 ) )
|
|
||||||
less_than_half_cylinder = true;
|
|
||||||
|
|
||||||
if ( partition.type == TYPE_LOGICAL ||
|
|
||||||
partition.sector_start == device .sectors
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//Must account the relative offset between:
|
|
||||||
// (A) the Extended Boot Record sector and the next track of the
|
|
||||||
// logical partition (usually 63 sectors), and
|
|
||||||
// (B) the Master Boot Record sector and the next track of the first
|
|
||||||
// primary partition
|
|
||||||
diff = (partition .sector_start - device .sectors) % device .cylsize ;
|
|
||||||
}
|
|
||||||
else if ( partition.sector_start == 34 )
|
|
||||||
{
|
|
||||||
// (C) the GUID Partition Table (GPT) and the start of the data
|
|
||||||
// partition at sector 34
|
|
||||||
diff = (partition .sector_start - 34 ) % device .cylsize ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
diff = partition .sector_start % device .cylsize ;
|
|
||||||
}
|
|
||||||
if ( diff && ! partition .strict_start )
|
|
||||||
{
|
|
||||||
if ( diff < ( device .cylsize / 2 ) || less_than_half_cylinder )
|
|
||||||
partition .sector_start -= diff ;
|
|
||||||
else
|
|
||||||
partition .sector_start += (device .cylsize - diff ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff = (partition .sector_end +1) % device .cylsize ;
|
|
||||||
if ( diff )
|
|
||||||
{
|
|
||||||
if ( diff < ( device .cylsize / 2 ) && ! less_than_half_cylinder )
|
|
||||||
partition .sector_end -= diff ;
|
|
||||||
else
|
|
||||||
partition .sector_end += (device .cylsize - diff ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GParted_Core::snap_to_mebibyte(const Device& device, Partition& partition)
|
|
||||||
{
|
|
||||||
Sector diff = 0;
|
|
||||||
if ( partition .sector_start < 2 || partition .type == TYPE_LOGICAL )
|
|
||||||
{
|
|
||||||
//Must account the relative offset between:
|
|
||||||
// (A) the Master Boot Record sector and the first primary/extended partition, and
|
|
||||||
// (B) the Extended Boot Record sector and the logical partition
|
|
||||||
|
|
||||||
//If strict_start is set then do not adjust sector start.
|
|
||||||
//If this partition is not simply queued for a reformat then
|
|
||||||
// add space minimum to force alignment to next mebibyte.
|
|
||||||
if ( (! partition .strict_start)
|
|
||||||
&& (partition .free_space_before == 0)
|
|
||||||
&& ( partition .status != STAT_FORMATTED)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//Unless specifically told otherwise, the Linux kernel considers extended
|
|
||||||
// boot records to be two sectors long, in order to "leave room for LILO".
|
|
||||||
partition .sector_start += 2 ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Calculate difference offset from Mebibyte boundary
|
|
||||||
diff = Sector(partition .sector_start % ( MEBIBYTE / partition .sector_size ));
|
|
||||||
|
|
||||||
//Align start sector only if permitted to change start sector
|
|
||||||
if ( diff && ( (! partition .strict_start)
|
|
||||||
|| ( partition .strict_start
|
|
||||||
&& ( partition .status == STAT_NEW
|
|
||||||
|| partition .status == STAT_COPY
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
partition .sector_start += ( (MEBIBYTE / partition .sector_size) - diff) ;
|
|
||||||
|
|
||||||
//If this is an extended partition then check to see if sufficient space is
|
|
||||||
// available for any following logical partition Extended Boot Record
|
|
||||||
if ( partition .type == TYPE_EXTENDED )
|
|
||||||
{
|
|
||||||
//If there is logical partition that starts less than 2 sectors
|
|
||||||
// from the start of this partition, then reserve a mebibyte for the EBR.
|
|
||||||
int index_extended = find_extended_partition( device.partitions );
|
|
||||||
if ( index_extended >= 0 )
|
|
||||||
{
|
|
||||||
for ( unsigned int t = 0; t < device .partitions[ index_extended ] .logicals .size(); t++ )
|
|
||||||
{
|
|
||||||
if ( ( device .partitions[ index_extended ] .logicals[ t ] .type == TYPE_LOGICAL )
|
|
||||||
&& ( ( ( device .partitions[ index_extended ] .logicals[ t ] .sector_start )
|
|
||||||
- ( partition .sector_start )
|
|
||||||
)
|
|
||||||
//Unless specifically told otherwise, the Linux kernel considers extended
|
|
||||||
// boot records to be two sectors long, in order to "leave room for LILO".
|
|
||||||
< 2
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
partition .sector_start -= (MEBIBYTE / partition .sector_size) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Align end sector
|
|
||||||
diff = (partition .sector_end + 1) % ( MEBIBYTE / partition .sector_size);
|
|
||||||
if ( diff )
|
|
||||||
partition .sector_end -= diff ;
|
|
||||||
|
|
||||||
//If this is a logical partition not at end of drive then check to see if space is
|
|
||||||
// required for a following logical partition Extended Boot Record
|
|
||||||
if ( partition .type == TYPE_LOGICAL )
|
|
||||||
{
|
|
||||||
//If there is a following logical partition that starts less than 2 sectors from
|
|
||||||
// the end of this partition, then reserve at least a mebibyte for the EBR.
|
|
||||||
int index_extended = find_extended_partition( device.partitions );
|
|
||||||
if ( index_extended >= 0 )
|
|
||||||
{
|
|
||||||
for ( unsigned int t = 0; t < device .partitions[ index_extended ] .logicals .size(); t++ )
|
|
||||||
{
|
|
||||||
if ( ( device .partitions[ index_extended ] .logicals[ t ] .type == TYPE_LOGICAL )
|
|
||||||
&& ( device .partitions[ index_extended ] .logicals[ t ] .sector_start > partition .sector_end )
|
|
||||||
&& ( ( device .partitions[ index_extended ] .logicals[ t ] .sector_start - partition .sector_end )
|
|
||||||
//Unless specifically told otherwise, the Linux kernel considers extended
|
|
||||||
// boot records to be two sectors long, in order to "leave room for LILO".
|
|
||||||
< 2
|
|
||||||
)
|
|
||||||
)
|
|
||||||
partition .sector_end -= ( MEBIBYTE / partition .sector_size ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//If the logical partition end is beyond the end of the extended partition
|
|
||||||
// then reduce logical partition end by a mebibyte to address the overlap.
|
|
||||||
if ( ( index_extended != -1 )
|
|
||||||
&& ( partition .sector_end > device .partitions[ index_extended ] .sector_end )
|
|
||||||
)
|
|
||||||
partition .sector_end -= ( MEBIBYTE / partition .sector_size ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If this is a primary or an extended partition and the partition overlaps
|
|
||||||
// the start of the next primary or extended partition then subtract a
|
|
||||||
// mebibyte from the end of the partition to address the overlap.
|
|
||||||
if ( partition .type == TYPE_PRIMARY || partition .type == TYPE_EXTENDED )
|
|
||||||
{
|
|
||||||
for ( unsigned int t = 0 ; t < device .partitions .size() ; t++ )
|
|
||||||
{
|
|
||||||
if ( ( device .partitions[ t ] .type == TYPE_PRIMARY
|
|
||||||
|| device .partitions[ t ] .type == TYPE_EXTENDED
|
|
||||||
)
|
|
||||||
&& ( //For a change to an existing partition, (e.g., move or resize)
|
|
||||||
// skip comparing to original partition and
|
|
||||||
// only compare to other existing partitions
|
|
||||||
partition .status == STAT_REAL
|
|
||||||
&& partition .partition_number != device. partitions[ t ] .partition_number
|
|
||||||
)
|
|
||||||
&& ( device .partitions[ t ] .sector_start > partition .sector_start )
|
|
||||||
&& ( device .partitions[ t ] .sector_start <= partition .sector_end )
|
|
||||||
)
|
|
||||||
partition .sector_end -= ( MEBIBYTE / partition .sector_size );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//If this is an extended partition then check to see if the end of the
|
|
||||||
// extended partition encompasses the end of the last logical partition.
|
|
||||||
if ( partition .type == TYPE_EXTENDED )
|
|
||||||
{
|
|
||||||
//If there is logical partition that has an end sector beyond the
|
|
||||||
// end of the extended partition, then set the extended partition
|
|
||||||
// end sector to be the same as the end of the logical partition.
|
|
||||||
for ( unsigned int t = 0; t < partition .logicals .size(); t++ )
|
|
||||||
{
|
|
||||||
if ( ( partition .logicals[ t ] .type == TYPE_LOGICAL )
|
|
||||||
&& ( ( partition .logicals[ t ] .sector_end )
|
|
||||||
> ( partition .sector_end )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
partition .sector_end = partition .logicals[ t ] .sector_end ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//If this is a GPT partition table and the partition ends less than 34 sectors
|
|
||||||
// from the end of the device, then reserve at least a mebibyte for the
|
|
||||||
// backup partition table
|
|
||||||
if ( device .disktype == "gpt"
|
|
||||||
&& ( ( device .length - partition .sector_end ) < 34 )
|
|
||||||
)
|
|
||||||
{
|
|
||||||
partition .sector_end -= ( MEBIBYTE / partition .sector_size ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GParted_Core::snap_to_alignment(const Device& device, Partition& partition)
|
|
||||||
{
|
|
||||||
if ( partition .alignment == ALIGN_CYLINDER )
|
|
||||||
snap_to_cylinder(device, partition);
|
|
||||||
else if ( partition .alignment == ALIGN_MEBIBYTE )
|
|
||||||
snap_to_mebibyte(device, partition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool GParted_Core::valid_partition(const Device& device, Partition& partition, Glib::ustring& error)
|
bool GParted_Core::valid_partition(const Device& device, Partition& partition, Glib::ustring& error)
|
||||||
{
|
{
|
||||||
snap_to_alignment(device, partition);
|
|
||||||
|
|
||||||
//Ensure that partition start and end are not beyond the ends of the disk device
|
//Ensure that partition start and end are not beyond the ends of the disk device
|
||||||
if ( partition .sector_start < 0 )
|
if ( partition .sector_start < 0 )
|
||||||
partition .sector_start = 0 ;
|
partition .sector_start = 0 ;
|
||||||
|
|
Loading…
Reference in New Issue