[gparted] Workaround not so old wipefs only erasing 1 of 3 vfat signatures (#688882)



commit 6982f68e21b5c1cfdd0c4f61ace83772152ad5d2
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sun Feb 17 15:13:34 2013 +0000

    Workaround not so old wipefs only erasing 1 of 3 vfat signatures (#688882)
    
    Before util-linux 2.21.0, released Feb 2012, wipefs only cleared one of
    the three vfat (fat16/fat32) signatures it can be detected by each time
    wipefs was run.  Also if a nilfs2 file system was created before all
    three signatures were cleared the partition was still recognised as a
    vfat file system, albeit a corrupted one, rather than as a nilfs2 file
    system.
    
    Old wipefs clearing vfat signatures:
        # wipefs --version
        wipefs from util-linux 2.20.1
        # wipefs -a /dev/sda7
        8 bytes were erased at offset 0x52 (vfat)
        they were: 46 41 54 33 32 20 20 20
        # wipefs -a /dev/sda7
        1 bytes were erased at offset 0x0 (vfat)
        they were: eb
        # wipefs -a /dev/sda7
        2 bytes were erased at offset 0x1fe (vfat)
        they were: 55 aa
    
    New wipefs clearing vfat signatures:
        # wipefs --version
        wipefs from util-linux 2.21.2
        # wipefs -a /dev/sda12
        8 bytes were erased at offset 0x00000052 (vfat): 46 41 54 33 32 20 20 20
        1 bytes were erased at offset 0x00000000 (vfat): eb
        2 bytes were erased at offset 0x000001fe (vfat): 55 aa
    
    Workaround by calling "wipefs -a" three times if the output indicated
    only one vfat signature was cleared.
    
    Bug #688882 - Improve clearing of file system signatures

 include/GParted_Core.h |    2 ++
 src/GParted_Core.cc    |   45 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 38 insertions(+), 9 deletions(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index da4b0c0..9892a65 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -179,6 +179,8 @@ private:
                                   OperationDetail & operationdetail ) ;
        FileSystem* set_proper_filesystem( const FILESYSTEM & filesystem ) ;
        bool erase_filesystem_signatures( const Partition & partition, OperationDetail & operationdetail ) ;
+       bool wipe_filesystem_signatures( const Glib::ustring & device_path,
+                                        OperationDetail & operationdetail, Glib::ustring & output ) ;
        bool update_bootsector( const Partition & partition, OperationDetail & operationdetail ) ;
 
        //general..     
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index e15d5c3..16c04b8 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -3130,21 +3130,27 @@ bool GParted_Core::filesystem_resize_disallowed( const Partition & partition )
 
 bool GParted_Core::erase_filesystem_signatures( const Partition & partition, OperationDetail & 
operationdetail )
 {
+       bool success = true ;
        if ( ! Glib::find_program_in_path( "wipefs" ) .empty() )
        {
+               Glib::ustring output ;
                operationdetail .add_child( OperationDetail(
                                String::ucompose( _("clear old file system signatures in %1"),
                                                  partition .get_path() ) ) ) ;
                OperationDetail & od = operationdetail .get_last_child() ;
-               Glib::ustring output, error ;
-               Glib::ustring command = "wipefs -a " + partition .get_path() ;
-               od .add_child( OperationDetail( command, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
-               int exit_status = Utils::execute_command( command, output, error, true ) ;
-               if ( ! output .empty() )
-                       od .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) 
) ;
-               if ( ! error .empty() )
-                       od .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) 
;
-               od .set_status( exit_status == 0 ? STATUS_SUCCES : STATUS_N_A ) ;
+               success &= wipe_filesystem_signatures( partition .get_path(), od, output ) ;
+
+               //Before util-linux 2.21.0, released Feb 2012, wipefs only erased 1 of
+               //  the 3 vfat (fat16/fat32) signatures each time it was called.  If only
+               //  one vfat signature was wiped, found "(vfat)" only once in the output,
+               //  execute wipefs 2 more time.
+               Glib::ustring::size_type p1 = output .find( "(vfat)" ) ;
+               if (    p1 != Glib::ustring::npos
+                    && output .find( "(vfat)", p1+6 ) == Glib::ustring::npos )
+               {
+                       success &= wipe_filesystem_signatures( partition .get_path(), od, output ) ;
+                       success &= wipe_filesystem_signatures( partition .get_path(), od, output ) ;
+               }
        }
 
        //Linux kernel doesn't maintain buffer cache coherency between the whole disk
@@ -3182,9 +3188,30 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
                }
                ped_device_destroy( lp_device ) ;
        }
+
+       operationdetail .get_last_child() .set_status( success ? STATUS_SUCCES : STATUS_N_A ) ;
        return true ;
 }
 
+bool GParted_Core::wipe_filesystem_signatures( const Glib::ustring & path,
+                                               OperationDetail & operationdetail, Glib::ustring & output )
+{
+       bool success ;
+       Glib::ustring error ;
+       Glib::ustring command = "wipefs -a " + path ;
+
+       operationdetail .add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) ) ;
+       int exit_status = Utils::execute_command( command, output, error, true ) ;
+       if ( ! output .empty() )
+               operationdetail .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, 
FONT_ITALIC ) ) ;
+       if ( ! error .empty() )
+               operationdetail .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, 
FONT_ITALIC ) ) ;
+       success = ( 0 == exit_status ) ;
+       operationdetail .get_last_child() .set_status( success ? STATUS_SUCCES : STATUS_N_A ) ;
+
+       return success ;
+}
+
 bool GParted_Core::update_bootsector( const Partition & partition, OperationDetail & operationdetail ) 
 {
        //only for ntfs atm...


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