Flush devices when scanning to prevent reading stale signatures (#723842)
While one partition is busy, reformat another partition from the command
line. Afterwards parted/libparted still detects the original file
system and GParted shows errors from the file system specific tools
reporting the new file system doesn't exist. Only limitation is that
the new new file system must be recognised by libparted (or by GParted's
fallback file system signature detection).
Case #1, File system reformatting:
# parted /dev/sdb print
Model: ATA SAMSUNG SSD UM41 (scsi)
Disk /dev/sdb: 8012MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 2149MB 2147MB primary ext2
2 2149MB 4296MB 2147MB primary ext2
# mount | fgrep sdb
/dev/sdb1 on /mnt/1 type ext2 (rw)
# mkfs.xfs -f /dev/sdb2
# blkid /dev/sdb2
/dev/sdb2: UUID="c31823a2-b81b-46fa-8246-0a59695e4834" TYPE="xfs"
# parted /dev/sdb print
Model: ATA SAMSUNG SSD UM41 (scsi)
Disk /dev/sdb: 8012MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 2149MB 2147MB primary ext2
2 2149MB 4296MB 2147MB primary ext2
# e2label /dev/sdb2
e2label: Bad magic number in super-block while trying to open /dev/sdb2
Couldn't find valid filesystem superblock.
# dumpe2fs /dev/sdb2
dumpe2fs 1.41.12 (17-May-2010)
dumpe2fs: Bad magic number in super-block while trying to open /dev/sdb2
Couldn't find valid filesystem superblock.
Case #2, Removing device from multi-device btrfs:
# btrfs filesystem show /dev/sdb1
Label: none uuid: a05db434-efd5-4e8c-902f-05f89a88b610
Total devices 2 FS bytes used 156.00KB
devid 2 size 2.00GB used 512.00MB path /dev/sdb2
devid 1 size 2.00GB used 240.75MB path /dev/sdb1
# mount /dev/sdb1 /mnt/1
# btrfs device delete /dev/sdb2
# btrfs filesystem show /dev/sdb1
Label: none uuid: a05db434-efd5-4e8c-902f-05f89a88b610
Total devices 1 FS bytes used 92.00KB
devid 1 size 2.00GB used 714.25MB path /dev/sdb1
# btrfs filesystem show /dev/sdb2
and GParted reports this error for partition /dev/sdb2:
Unable to read the contents of this file system!
Because of this some operations may be unavailable.
The cause might be a missing software package.
The following list of software packages is required for btrfs
file system support: btrfs-tools.
This is another case of libparted reading from the whole disk device
(/dev/sdb) yet the file system tools use the partition specific block
device (/dev/sdb2), and the Linux buffer cache not providing cache
coherency. Previous scenario was fixed with:
797f0b8eeb
Flush device after wiping a file system (#688882)
This affects libparted 2.0 to 3.1 inclusive and is fixed by:
http://git.savannah.gnu.org/cgit/parted.git/commit/?id=fb99ba5ebd0dc34204fc9f1014131d5d494805bc
Revert "linux-commit: do not unnecessarily open partition device nodes"
Fix by calling ped_device_sync() to guarantee cache coherency for each
device during scanning.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
This commit is contained in:
parent
20f52e2866
commit
3bea067596
|
@ -183,8 +183,9 @@ private:
|
||||||
bool update_bootsector( const Partition & partition, OperationDetail & operationdetail ) ;
|
bool update_bootsector( const Partition & partition, OperationDetail & operationdetail ) ;
|
||||||
|
|
||||||
//general..
|
//general..
|
||||||
|
bool flush_device( PedDevice * lp_device ) ;
|
||||||
bool get_device_and_disk( const Glib::ustring & device_path,
|
bool get_device_and_disk( const Glib::ustring & device_path,
|
||||||
PedDevice*& lp_device, PedDisk*& lp_disk, bool strict = true ) ;
|
PedDevice*& lp_device, PedDisk*& lp_disk, bool strict = true, bool flush = false ) ;
|
||||||
void destroy_device_and_disk( PedDevice*& lp_device, PedDisk*& lp_disk ) ;
|
void destroy_device_and_disk( PedDevice*& lp_device, PedDisk*& lp_disk ) ;
|
||||||
bool commit( PedDisk* lp_disk ) ;
|
bool commit( PedDisk* lp_disk ) ;
|
||||||
bool commit_to_os( PedDisk* lp_disk, std::time_t timeout ) ;
|
bool commit_to_os( PedDisk* lp_disk, std::time_t timeout ) ;
|
||||||
|
|
|
@ -288,7 +288,7 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
|
||||||
set_thread_status_message( String::ucompose ( _("Searching %1 partitions"), device_paths[ t ] ) ) ;
|
set_thread_status_message( String::ucompose ( _("Searching %1 partitions"), device_paths[ t ] ) ) ;
|
||||||
PedDevice* lp_device = NULL ;
|
PedDevice* lp_device = NULL ;
|
||||||
PedDisk* lp_disk = NULL ;
|
PedDisk* lp_disk = NULL ;
|
||||||
if ( get_device_and_disk( device_paths[ t ], lp_device, lp_disk, false ) )
|
if ( get_device_and_disk( device_paths[ t ], lp_device, lp_disk, false, true ) )
|
||||||
{
|
{
|
||||||
temp_device .Reset() ;
|
temp_device .Reset() ;
|
||||||
|
|
||||||
|
@ -3393,14 +3393,6 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
|
||||||
// via the whole disk device will read the old data and report the file system
|
// via the whole disk device will read the old data and report the file system
|
||||||
// as still existing.
|
// 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
|
// 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
|
// 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
|
// performed as part of writing a new file system as the partition type is also
|
||||||
|
@ -3521,12 +3513,42 @@ bool GParted_Core::update_bootsector( const Partition & partition, OperationDeta
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Flush the Linux kernel caches, and therefore ensure coherency between the caches of the
|
||||||
|
// whole disk device and the partition devices.
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
//
|
||||||
|
// Libparted >= v3.1-61-gfb99ba5 works around this for all kernel versions.
|
||||||
|
// Ref: parted v3.1-61-gfb99ba5 ./libparted/arch/linux.c linux_open()
|
||||||
|
// 1640 _flush_cache (dev);
|
||||||
|
bool GParted_Core::flush_device( PedDevice * lp_device )
|
||||||
|
{
|
||||||
|
bool success = false ;
|
||||||
|
if ( ped_device_open( lp_device ) )
|
||||||
|
{
|
||||||
|
success = ped_device_sync( lp_device ) ;
|
||||||
|
ped_device_close( lp_device ) ;
|
||||||
|
}
|
||||||
|
return success ;
|
||||||
|
}
|
||||||
|
|
||||||
bool GParted_Core::get_device_and_disk( const Glib::ustring & device_path,
|
bool GParted_Core::get_device_and_disk( const Glib::ustring & device_path,
|
||||||
PedDevice*& lp_device, PedDisk*& lp_disk, bool strict )
|
PedDevice*& lp_device, PedDisk*& lp_disk, bool strict, bool flush )
|
||||||
{
|
{
|
||||||
lp_device = ped_device_get( device_path .c_str() ) ;
|
lp_device = ped_device_get( device_path .c_str() ) ;
|
||||||
if ( lp_device )
|
if ( lp_device )
|
||||||
{
|
{
|
||||||
|
if ( flush )
|
||||||
|
//Force cache coherency before reading the partition table so that
|
||||||
|
// libparted reading the whole disk device and the file system
|
||||||
|
// tools reading the partition devices read the same data.
|
||||||
|
flush_device( lp_device ) ;
|
||||||
|
|
||||||
lp_disk = ped_disk_new( lp_device );
|
lp_disk = ped_disk_new( lp_device );
|
||||||
|
|
||||||
//if ! disk and writeable it's probably a HD without disklabel.
|
//if ! disk and writeable it's probably a HD without disklabel.
|
||||||
|
|
Loading…
Reference in New Issue