From 400864a65e1bd270f326617536fac4597a25b033 Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Sat, 13 Aug 2016 13:28:58 +0100 Subject: [PATCH] Add and use Partition::set_unpartitioned() method (#788308) PATCHSET OVERVIEW: When unpartitioned drive read-write support was added this commit added a whole_device flag: 5098744f9aa958ba18d2a4657ea4345e275c885b Add whole_device flag to the partition object (#743181) Using a whole_device flags now seems not the correct way to model unpartitioned drives. GParted models an uninitialised drive as: .path = _("uninitialized") .type = TYPE_UNALLOCATED .whole_device = true .filesystem = FS_UNALLOCATED and a whole drive file system, using ext4 for example, as: .path = "/dev/sdb" .type = TYPE_PRIMARY .whole_device = true .filesystem = FS_EXT4 No partitioning changed yet the type of the partition in the model changed between TYPE_UNALLOCATED and TYPE_PRIMARY depending on whether the whole drive contains a recognised file system or not. The partition object describing a file system within a LUKS encryption mapping is another case of the model not matching reality. .path = /dev/mapper/crypt_sdb1_crypt .type = TYPE_PRIMARY .whole_device = true .filesystem = FS_EXT4 There is no partition table within the encryption mapping, the file system fills it, but GParted records it as a primary partition. Make TYPE_UNALLOCATED and TYPE_PRIMARY be reserved for representing unallocated space and primary partitions within a partitioned disk drive and introduce new TYPE_UNPARTITIONED for all cases of an unpartitioned whole disk drive. The GParted UI does differentiate between an unallocated whole disk device and anything else by requiring a partition table to be created first, even if that is just the loop partition table. That determination can simply look for the partition object containing file system type FS_UNALLOCATED instead. THIS PATCH: Create set_unpartitioned() helper method to set a partition object to represent a whole disk drive and use everywhere such an object is modelled. This matches what existing methods Set_Unallocated() and indeed Set() do for unallocated space and any type of partition respectively. For now the partition type is still set to either TYPE_UNALLOCATED or TYPE_PRIMARY so the rest of the code base remains the same. TYPE_UNPARTITIONED will be introduced later. Bug 788308 - Remove whole_device partition flag --- include/Partition.h | 6 +++++ src/GParted_Core.cc | 58 +++++++++++++++++------------------------- src/OperationFormat.cc | 12 ++++----- src/Partition.cc | 33 ++++++++++++++++++++++++ src/PartitionLUKS.cc | 25 ++++++++---------- 5 files changed, 79 insertions(+), 55 deletions(-) diff --git a/include/Partition.h b/include/Partition.h index 8475d696..0b6ac871 100644 --- a/include/Partition.h +++ b/include/Partition.h @@ -98,6 +98,12 @@ public: Sector sector_end, Byte_Value sector_size, bool inside_extended ); + void set_unpartitioned( const Glib::ustring & device_path, + const Glib::ustring & partition_path, + FILESYSTEM fstype, + Sector length, + Byte_Value sector_size, + bool busy ); //update partition number (used when a logical partition is deleted) void Update_Number( int new_number ); diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index 5a9c7725..bbb125e0 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -707,12 +707,12 @@ bool GParted_Core::set_disklabel( const Device & device, const Glib::ustring & d // preference to any partition table 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 ); + temp_partition.set_unpartitioned( device_path, + "", + FS_UNALLOCATED, + device.length, + device.sector_size, + false ); erase_filesystem_signatures( temp_partition, dummy_od ); return new_disklabel( device_path, disklabel ); @@ -953,17 +953,12 @@ void GParted_Core::set_device_from_disk( Device & device, const Glib::ustring & // Create virtual partition covering the whole disk device // with unknown contents. Partition * partition_temp = new Partition(); - partition_temp->Set( device.get_path(), - lp_device->path, - 1, - TYPE_PRIMARY, - true, - FS_UNKNOWN, - 0LL, - device.length - 1LL, - device.sector_size, - false, - false ); + partition_temp->set_unpartitioned( device.get_path(), + lp_device->path, + FS_UNKNOWN, + device.length, + device.sector_size, + false ); // Place unknown file system message in this partition. partition_temp->append_messages( messages ); device.partitions.push_back_adopt( partition_temp ); @@ -980,12 +975,12 @@ void GParted_Core::set_device_from_disk( Device & device, const Glib::ustring & device.max_prims = 1; Partition * partition_temp = new Partition(); - partition_temp->Set_Unallocated( device.get_path(), - true, - 0LL, - device.length - 1LL, - device.sector_size, - false ); + partition_temp->set_unpartitioned( device.get_path(), + "", // Overridden with "unallocated" + FS_UNALLOCATED, + device.length, + device.sector_size, + false ); // Place libparted messages in this unallocated partition partition_temp->append_messages( libparted_messages ); libparted_messages.clear(); @@ -1210,17 +1205,12 @@ void GParted_Core::set_device_one_partition( Device & device, PedDevice * lp_dev partition_temp = new PartitionLUKS(); else partition_temp = new Partition(); - partition_temp->Set( device.get_path(), - path, - 1, - TYPE_PRIMARY, - true, - fstype, - 0LL, - device.length - 1LL, - device.sector_size, - false, - partition_is_busy ); + partition_temp->set_unpartitioned( device.get_path(), + path, + fstype, + device.length, + device.sector_size, + partition_is_busy ); partition_temp->append_messages( messages ); diff --git a/src/OperationFormat.cc b/src/OperationFormat.cc index a6a4d0e5..710893bf 100644 --- a/src/OperationFormat.cc +++ b/src/OperationFormat.cc @@ -52,12 +52,12 @@ void OperationFormat::apply_to_visual( PartitionVector & partitions ) partitions.clear(); Partition * temp_partition = new Partition(); - temp_partition->Set_Unallocated( device.get_path(), - true, - 0LL, - device.length -1LL, - device.sector_size, - false ); + temp_partition->set_unpartitioned( device.get_path(), + "", // Overridden with "unallocated" + FS_UNALLOCATED, + device.length, + device.sector_size, + false ); partitions.push_back_adopt( temp_partition ); } else diff --git a/src/Partition.cc b/src/Partition.cc index b5c5967e..6194985f 100644 --- a/src/Partition.cc +++ b/src/Partition.cc @@ -201,6 +201,39 @@ void Partition::Set_Unallocated( const Glib::ustring & device_path, status = GParted::STAT_REAL ; } +void Partition::set_unpartitioned( const Glib::ustring & device_path, + const Glib::ustring & partition_path, + FILESYSTEM fstype, + Sector length, + Byte_Value sector_size, + bool busy ) +{ + Reset(); + Set( device_path, + // The path from the parent Device object and this child Partition object + // spanning the whole device would appear to be the same. However the former + // may have come from the command line and the later is the canonicalised + // name returned from libparted. (See GParted_Core::set_device_from_disk() + // "loop" table and GParted_Core::set_device_one_partition() calls to + // set_unpartitioned()). Therefore they can be different. + // + // For unrecognised whole disk device partitions use "unallocated" as the + // partition path to match what Set_Unallocated() does when it created such + // whole disk device partitions. + ( fstype == FS_UNALLOCATED ) ? Utils::get_filesystem_string( FS_UNALLOCATED ) + : partition_path, + 1, + // FIXME: Replace with TYPE_UNPARTITIONED when whole_device member is removed + ( fstype == FS_UNALLOCATED ) ? TYPE_UNALLOCATED : TYPE_PRIMARY, + true, + fstype, + 0LL, + length - 1LL, + sector_size, + false, + busy ); +} + void Partition::Update_Number( int new_number ) { unsigned int index = path.rfind( Utils::num_to_str( partition_number ) ); diff --git a/src/PartitionLUKS.cc b/src/PartitionLUKS.cc index 3ac67564..ae08ac69 100644 --- a/src/PartitionLUKS.cc +++ b/src/PartitionLUKS.cc @@ -65,10 +65,10 @@ Partition * PartitionLUKS::clone_as_plain() const return plain_ptn; } -// Mostly a convenience method calling Partition::Set() on the encrypted Partition but -// also sets private header_size. Makes encrypted Partition object look like a whole disk -// device as /dev/mapper/CRYPTNAME contains no partition table and the file system starts -// from sector 0 going to the very end. +// Mostly a convenience method calling Partition::set_unpartitioned() on the encrypted +// Partition but also sets private header_size. Makes encrypted Partition object look +// like a whole disk device as /dev/mapper/CRYPTNAME contains no partition table and the +// file system starts from sector 0 going to the very end. void PartitionLUKS::set_luks( const Glib::ustring & path, FILESYSTEM fstype, Sector header_size, @@ -76,17 +76,12 @@ void PartitionLUKS::set_luks( const Glib::ustring & path, Byte_Value sector_size, bool busy ) { - encrypted.Set( path, - path, - 1, - TYPE_PRIMARY, - true, - fstype, - 0LL, - mapping_size - 1LL, - sector_size, - false, - busy ); + encrypted.set_unpartitioned( path, + path, + fstype, + mapping_size, + sector_size, + busy ); this->header_size = header_size; }