[gparted] Flush device after wiping a file system (#688882)



commit 797f0b8eeb61f81da1791c3cf048b5c0abf9a550
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Tue Jan 15 13:51:04 2013 +0000

    Flush device after wiping a file system (#688882)
    
    When just formatting an existing partition to "cleared", GParted just
    uses wipefs to clear the file system signatures.  Afterwards parted/
    libparted still detect the file system and GParted shows errors from the
    file system specific tools reporting the file system doesn't exist.
    
        # wipefs /dev/sda7
        offset               type
        ----------------------------------------------------------------
        0x0                  xfs   [filesystem]
                             UUID:  28399a74-83a5-4ed7-aaf8-c76ac449fb57
        # wipefs -a /dev/sda7
        4 bytes were erased at offset 0x0 (xfs)
        they were: 58 46 53 42
        # parted /dev/sda print
        Model: ATA SAMSUNG HM500JI (scsi)
        Disk /dev/sda: 500GB
        Sector size (logical/physical): 512B/512B
        Partition Table: msdos
    
        Number  Start   End     Size    Type      File system     Flags
         1      1049kB  538MB   537MB   primary   ext4            boot
         2      538MB   5907MB  5369MB  primary   linux-swap(v1)
         3      5907MB  32.8GB  26.8GB  primary   ext4
         4      32.8GB  500GB   467GB   extended
         5      32.8GB  355GB   322GB   logical   ext3
         6      355GB   356GB   1074MB  logical
         7      356GB   357GB   1074MB  logical   xfs
        # xfs_db -c 'sb 0' -c 'print blocksize' -c 'print dblocks' -c 'print fdblocks' -r /dev/sda7
        xfs_db: /dev/sda7 is not a valid XFS filesystem (unexpected SB magic number 0x00000000)
    
    Wipefs was run on the partition specific block device (/dev/sda7) where
    as libparted reads the disk using the whole disk device (/dev/sda).
    However as the Linux buffer cache does not provide cache coherency, the
    xfs file system can still be found in the cache of /dev/sda.
    
    Fix this by calling ped_device_sync() after wipefs as it guarantees
    cache coherency.
    
    (As documented in erase_filesystem_signatures() there are cases when
    calling ped_device_sync() isn't necessary, but testing shows that the
    whole processes takes at most 0.15 seconds.  As this is in the middle of
    applying an operation, uses won't notice this extra time so just always
    call ped_device_sync()).
    
    Bug #688882 - Improve clearing of file system signatures

 src/GParted_Core.cc |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)
---
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index fe5bd5a..e15d5c3 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -3147,6 +3147,41 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
                od .set_status( exit_status == 0 ? STATUS_SUCCES : STATUS_N_A ) ;
        }
 
+       //Linux kernel doesn't maintain buffer cache coherency between the whole disk
+       //  device and partition devices.  So even though the file system signatures
+       //  have been overwritten on the disk via a partition device, libparted reading
+       //  via the whole disk device will read the old data and report the file system
+       //  as still existing.
+       //
+       //  Libparted >= 2.0 works around this by calling ioctl(fd, BLKFLSBUF) to flush
+       //  the cache when opening the whole disk device, but only for kernels before
+       //  2.6.0.
+       //  Ref: parted v3.1-52-g1c659d5 ./libparted/arch/linux.c linux_open()
+       //  1657         /* With kernels < 2.6 flush cache for cache coherence issues */
+       //  1658         if (!_have_kern26())
+       //  1659                 _flush_cache (dev);
+       //
+       //  Calling ped_device_sync() to flush the cache is required when the partition is
+       //  just being cleared.  However the sync can be skipped when the wipe is being
+       //  performed as part of writing a new file system as the partition type is also
+       //  changed, which modified the partition table so GParted calls
+       //  ped_disk_commit_to_os().  This instructs the kernel to remove all non-busy
+       //  partitions on the disk and re-adds them, thus effectively flushing the cache
+       //  of the disk.
+       //
+       //  Opening the device and calling ped_device_sync() took 0.15 seconds or less on
+       //  a 5400 RPM laptop hard drive.  For now just always call ped_device_sync() as
+       //  it doesn't add much time to the overall operation.
+       PedDevice * lp_device = ped_device_get( partition .device_path .c_str() ) ;
+       if ( lp_device != NULL )
+       {
+               if ( ped_device_open( lp_device ) )
+               {
+                       ped_device_sync( lp_device ) ;
+                       ped_device_close( lp_device ) ;
+               }
+               ped_device_destroy( lp_device ) ;
+       }
        return true ;
 }
 


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