[gparted] Reorder cases in set_device_and_disk() and use if fail return early (#152)



commit c830c6770d87246ee3b8a63a55adc54ca261e0fb
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sat Apr 10 20:48:24 2021 +0100

    Reorder cases in set_device_and_disk() and use if fail return early (#152)
    
    The previous commit "Resolve empty drive displayed as blank minor logic
    issue (#152)" left the code in set_device_and_disk() some what
    unsightly.
    
    Refactor the whole function.  Use if fail return early pattern for
    failure of the get_device() call at the start of the function.  Reorder
    the 4 cases into a single depth if then else if chain.  Hopefully this
    is a little easier to follow.
    
    Closes #152 - GParted crashed when trying to probe an encrypted
                  partition containing content that libparted doesn't
                  recognise

 src/GParted_Core.cc | 218 +++++++++++++++++++++++++++-------------------------
 1 file changed, 113 insertions(+), 105 deletions(-)
---
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index b3ee68bf..dbc11048 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -646,126 +646,134 @@ Glib::ustring GParted_Core::get_partition_path(const PedPartition *lp_partition)
        return partition_path ;
 }
 
+
 void GParted_Core::set_device_from_disk( Device & device, const Glib::ustring & device_path )
 {
        PedDevice* lp_device = NULL;
        PedDisk* lp_disk = NULL;
-       if ( get_device( device_path, lp_device, true ) )
-       {
-               device.Reset();
-
-               // Device info ...
-               device.set_path( device_path );
-               device.model       = lp_device->model;
-               device.length      = lp_device->length;
-               device.sector_size = lp_device->sector_size;
-               device.heads       = lp_device->bios_geom.heads;
-               device.sectors     = lp_device->bios_geom.sectors;
-               device.cylinders   = lp_device->bios_geom.cylinders;
-               device.cylsize     = device.heads * device.sectors;
-               set_device_serial_number( device );
-
-               // Make sure cylsize is at least 1 MiB
-               if ( device.cylsize < (MEBIBYTE / device.sector_size) )
-                       device.cylsize = MEBIBYTE / device.sector_size;
-
-               std::vector<Glib::ustring> messages;
-               FSType fstype = detect_filesystem( lp_device, NULL, messages );
-               // FS_Info (blkid) recognised file system signature on whole disk device.
-               // Need to detect before libparted reported partitioning to avoid bug in
-               // libparted 1.9.0 to 2.3 inclusive which recognised FAT file systems as
-               // MSDOS partition tables.  Fixed in parted 2.4 by commit:
+
+       if (! get_device(device_path, lp_device, true))
+               return;
+
+       device.Reset();
+
+       // Device info ...
+       device.set_path(device_path);
+       device.model       = lp_device->model;
+       device.length      = lp_device->length;
+       device.sector_size = lp_device->sector_size;
+       device.heads       = lp_device->bios_geom.heads;
+       device.sectors     = lp_device->bios_geom.sectors;
+       device.cylinders   = lp_device->bios_geom.cylinders;
+       device.cylsize     = device.heads * device.sectors;
+       set_device_serial_number(device);
+
+       // Make sure cylsize is at least 1 MiB
+       if (device.cylsize < (MEBIBYTE / device.sector_size))
+               device.cylsize = MEBIBYTE / device.sector_size;
+
+       std::vector<Glib::ustring> messages;
+       FSType fstype = detect_filesystem(lp_device, NULL, messages);
+
+       if (fstype != FS_UNKNOWN)
+       {
+               // Case 1/4: Recognised whole disk device file system
+               //
+               // FS_Info (blkid) or GParted internal detection recognised file system
+               // signature on whole disk device.  Need to detect before libparted
+               // reported partitioning to avoid bug in libparted 1.9.0 to 2.3 inclusive
+               // which recognised FAT file systems as MSDOS partition tables.  Fixed in
+               // parted 2.4 by commit:
                //     616a2a1659d89ff90f9834016a451da8722df509
                //     libparted: avoid regression when processing a whole-disk FAT partition
-               if ( fstype != FS_UNKNOWN )
-               {
-                       // Clear the possible "unrecognised disk label" message
-                       libparted_messages.clear();
 
-                       device.disktype = "none";
-                       device.max_prims = 1;
-                       set_device_one_partition( device, lp_device, fstype, messages );
-               }
-               // Partitioned drive
-               else
-               {
-                       get_disk(lp_device, lp_disk);
+               // Clear the possible "unrecognised disk label" message
+               libparted_messages.clear();
 
-                       // Partitioned drive (excluding "loop"), as recognised by libparted
-                       if ( lp_disk && lp_disk->type && lp_disk->type->name &&
-                            strcmp( lp_disk->type->name, "loop" ) != 0         )
-                       {
-                               device.disktype = lp_disk->type->name;
-                               device.max_prims = ped_disk_get_max_primary_partition_count( lp_disk );
+               device.disktype = "none";
+               device.max_prims = 1;
+               set_device_one_partition(device, lp_device, fstype, messages);
+       }
+       else if (! get_disk(lp_device, lp_disk))
+       {
+               // Case 2/4: Empty drive
+               //
+               // Empty drive without a disk label (partition table).
 
-                               // Determine if partition naming is supported.
-                               if ( ped_disk_type_check_feature( lp_disk->type, PED_DISK_TYPE_PARTITION_NAME 
) )
-                               {
-                                       device.enable_partition_naming(
-                                                       Utils::get_max_partition_name_length( device.disktype 
) );
-                               }
+               device.disktype =
+                       /* TO TRANSLATORS:   unrecognized
+                        * means that the partition table for this disk device is unknown
+                        * or not recognized.
+                        */
+                       _("unrecognized");
+               device.max_prims = 1;
+
+               Partition* partition_temp = new Partition();
+               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();
+               device.partitions.push_back_adopt(partition_temp);
+       }
+       else if (lp_disk && lp_disk->type && lp_disk->type->name &&
+                strcmp(lp_disk->type->name, "loop") == 0          )
+       {
+               // Case 3/4: Libparted "loop" signature only
+               //
+               // Drive just containing libparted "loop" signature and nothing else.
+               // (Actually any drive reported by libparted as "loop" but not recognised
+               // in case 1/4 as whole disk device file system).
+
+               device.disktype = lp_disk->type->name;
+               device.max_prims = 1;
+
+               // Create virtual partition covering the whole disk device with unknown
+               // contents.
+               Partition* partition_temp = new Partition();
+               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);
+       }
+       else
+       {
+               // Case 4/4: Partitioned drive
+               //
+               // (excluding libparted "loop" recognised in case 3/4).
 
-                               set_device_partitions( device, lp_device, lp_disk );
+               device.disktype = lp_disk->type->name;
+               device.max_prims = ped_disk_get_max_primary_partition_count(lp_disk);
 
-                               if ( device.highest_busy )
-                               {
-                                       device.readonly = ! commit_to_os( lp_disk, 
SETTLE_DEVICE_PROBE_MAX_WAIT_SECONDS );
-                                       // Clear libparted messages.  Typically these are:
-                                       //     The kernel was unable to re-read the partition table...
-                                       libparted_messages.clear();
-                               }
-                       }
-                       // Drive just containing libparted "loop" signature and nothing
-                       // else.  (Actually any drive reported by libparted as "loop" but
-                       // not recognised by blkid on the whole disk device).
-                       else if ( lp_disk && lp_disk->type && lp_disk->type->name &&
-                                 strcmp( lp_disk->type->name, "loop" ) == 0         )
-                       {
-                               device.disktype = lp_disk->type->name;
-                               device.max_prims = 1;
-
-                               // Create virtual partition covering the whole disk device
-                               // with unknown contents.
-                               Partition * partition_temp = new Partition();
-                               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 );
-                       }
-                       // Unrecognised, unpartitioned drive.
-                       else
-                       {
-                               device.disktype =
-                                       /* TO TRANSLATORS:  unrecognized
-                                        * means that the partition table for this disk
-                                        * device is unknown or not recognized.
-                                        */
-                                       _("unrecognized");
-                               device.max_prims = 1;
-
-                               Partition * partition_temp = new Partition();
-                               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();
-                               device.partitions.push_back_adopt( partition_temp );
-                       }
-               }
+               // Determine if partition naming is supported.
+               if (ped_disk_type_check_feature(lp_disk->type, PED_DISK_TYPE_PARTITION_NAME))
+                       device.enable_partition_naming(Utils::get_max_partition_name_length(device.disktype));
 
-               destroy_device_and_disk( lp_device, lp_disk);
+               set_device_partitions(device, lp_device, lp_disk);
+
+               if (device.highest_busy)
+               {
+                       device.readonly = ! commit_to_os(lp_disk, SETTLE_DEVICE_PROBE_MAX_WAIT_SECONDS);
+                       // Clear libparted messages.  Typically these are:
+                       //     The kernel was unable to re-read the partition table...
+                       libparted_messages.clear();
+               }
        }
+
+       destroy_device_and_disk(lp_device, lp_disk);
+       return;
 }
 
+
 void GParted_Core::set_device_serial_number( Device & device )
 {
        if ( ! hdparm_found )


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]