Erase file system signatures before creating a partition table (#743181)

When writing "loop" partition table over the top of some whole disk
device file system types GParted continued to show those whole disk
device file systems rather than the virtual unknown partition from the
"loop" partition table.

This affected btrfs, jfs, reiser4 and reiserfs.  It occurred because of
several factors:
1) Libparted only zeroed the first and last 9.5 KiB (assuming 512 byte
   sectors) of the device before writing a new partition table.  See
   ped_disk_clobber().
2) These file systems have their super blocks and therefore signatures
   after the first 9.5 KiB.
3) Whole disk device file system detection is performed using blkid
   before checking for a libparted "loop" partition table.  See
   GParted_Core::set_devices_thread().

Ref:
libparted 3.2: disk.c:ped_disk_clobber()
http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/disk.c?id=v3.2#n302

Fix by always erasing any possible file system signatures on the device
before creating a new "loop" partition table.

NOTE:
This is typically taking up to 0.5 seconds in my testing on a 5400 RPM
hard drive, during which time the GParted UI is hung and the create
partition table dialog shows the apply button pressed but no other
progress indication.

Bug 743181 - Add unpartitioned drive read-write support
This commit is contained in:
Mike Fleetwood 2015-02-14 20:49:45 +00:00 committed by Curtis Gedak
parent e9a5cf2843
commit e7ed209020
3 changed files with 29 additions and 5 deletions

View File

@ -46,8 +46,9 @@ public:
bool snap_to_mebibyte( const Device & device, Partition & partition, Glib::ustring & error ) ;
bool snap_to_alignment( const Device & device, Partition & partition, Glib::ustring & error ) ;
bool apply_operation_to_disk( Operation * operation );
bool set_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel ) ;
bool set_disklabel( const Device & device, const Glib::ustring & disklabel );
bool new_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel );
bool toggle_flag( const Partition & partition, const Glib::ustring & flag, bool state ) ;

View File

@ -802,10 +802,33 @@ bool GParted_Core::apply_operation_to_disk( Operation * operation )
return succes ;
}
bool GParted_Core::set_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel )
bool GParted_Core::set_disklabel( const Device & device, const Glib::ustring & disklabel )
{
Glib::ustring device_path = device.get_path();
if ( disklabel == "loop" )
{
// Ensure that any previous whole disk device file system can't be
// recognised in preference to the "loop" partition table signature about
// to be written.
OperationDetail dummy_od;
Partition temp_partition;
temp_partition.Set_Unallocated( device_path,
true,
0LL,
device.length - 1LL,
device.sector_size,
false );
erase_filesystem_signatures( temp_partition, dummy_od );
}
return new_disklabel( device_path, disklabel );
}
bool GParted_Core::new_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel )
{
bool return_value = false ;
PedDevice* lp_device = NULL ;
PedDisk* lp_disk = NULL ;
if ( get_device( device_path, lp_device ) )

View File

@ -2396,7 +2396,7 @@ void Win_GParted::activate_disklabel()
if ( dialog .run() == Gtk::RESPONSE_APPLY )
{
if ( ! gparted_core .set_disklabel( devices[ current_device ] .get_path(), dialog .Get_Disklabel() ) )
if ( ! gparted_core.set_disklabel( devices[current_device], dialog.Get_Disklabel() ) )
{
Gtk::MessageDialog dialog( *this,
_("Error while creating partition table"),