2010-01-02 04:11:50 -07:00
|
|
|
/* Copyright (C) 2009,2010 Luca Bruno <lucab@debian.org>
|
2011-10-18 10:14:21 -06:00
|
|
|
* Copyright (C) 2010, 2011 Curtis Gedak
|
2010-01-02 04:11:50 -07:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2014-01-23 03:59:48 -07:00
|
|
|
* GNU General Public License for more details.
|
2010-01-02 04:11:50 -07:00
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2014-01-23 03:59:48 -07:00
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2010-01-02 04:11:50 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "../include/btrfs.h"
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
#include "../include/GParted_Core.h"
|
2015-11-25 07:55:19 -07:00
|
|
|
#include "../include/Partition.h"
|
2010-01-02 04:11:50 -07:00
|
|
|
|
Handle btrfs tools rounding of figures (#499202)
The btrfs programs only provide approximations of file system sizes
because they display figures using binary prefix multipliers to two
decimal places of precision. E.g. 2.00GB. For partition sizes where
the contained file system size rounds upwards, GParted will fail to read
the file system usage and report a warning because the file system will
appear to be larger than the partition.
For example, create a 2047 MiB partition containing a btrfs file system
and display its size.
# btrfs filesystem show
Label: none uuid: 92535375-5e76-4a70-896a-8d796a577993
Total devices 1 FS bytes used 28.00KB
devid 1 size 2.00GB used 240.62MB path /dev/sda12
The file system size appears to be 2048 MiB, but that is larger than the
partition, hence the issue GParted has. (Actually uses the btrfs devid
size which is the size of the btrfs file system within the partition in
question).
This issue is new with the fix for Bug #499202 because it queries the
file system sizes for the first time. The same issue could
theoretically occur previously, but with the used figure (FS bytes
used). This would have been virtually impossible to trigger because
btrfs file system would have to have been greater than 99% full, but
btrfs has been notorious for early reporting of file system full.
The fix is that if a btrfs file system size appears larger than the
partition size, but the minimum possible size which could have been
rounded to the reported figure is within the partition size use the
smaller partition size instead. Apply the method to the used figure
too, in case the file system is 100% full. Also if the btrfs file
system size appears smaller than the partition size, but the maximum
possible size which could have been rounded to the reported figure is
within the partition size use the larger partition size instead to avoid
reporting, presumably false, unallocated space. Not applied to file
system used figure.
Bug 499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-05-30 06:41:59 -06:00
|
|
|
#include <ctype.h>
|
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
namespace GParted
|
|
|
|
{
|
|
|
|
|
2011-11-11 13:50:53 -07:00
|
|
|
bool btrfs_found = false ;
|
2012-02-05 02:08:05 -07:00
|
|
|
bool resize_to_same_size_fails = true ;
|
2011-11-11 13:50:53 -07:00
|
|
|
|
2014-04-10 15:28:40 -06:00
|
|
|
//Cache of required btrfs file system device information by device
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
// E.g. For a single device btrfs on /dev/sda2 and a three device btrfs
|
|
|
|
// on /dev/sd[bcd]1 the cache would be:
|
2014-04-10 15:28:40 -06:00
|
|
|
// btrfs_device_cache["/dev/sda2"] = {devid=1, members=["/dev/sda2"]}
|
|
|
|
// btrfs_device_cache["/dev/sdb1"] = {devid=1, members=["/dev/sdd1", "/dev/sdc1", "/dev/sdb1"]}
|
|
|
|
// btrfs_device_cache["/dev/sdc1"] = {devid=2, members=["/dev/sdd1", "/dev/sdc1", "/dev/sdb1"]}
|
|
|
|
// btrfs_device_cache["/dev/sdd1"] = {devid=3, members=["/dev/sdd1", "/dev/sdc1", "/dev/sdb1"]}
|
|
|
|
std::map<Glib::ustring, BTRFS_Device> btrfs_device_cache ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
FS btrfs::get_filesystem_support()
|
|
|
|
{
|
2015-11-13 14:46:57 -07:00
|
|
|
FS fs( FS_BTRFS );
|
2010-01-02 04:11:50 -07:00
|
|
|
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
fs .busy = FS::EXTERNAL ;
|
2014-02-14 18:26:32 -07:00
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
if ( ! Glib::find_program_in_path( "mkfs.btrfs" ) .empty() )
|
2013-06-05 15:15:47 -06:00
|
|
|
{
|
2010-01-02 04:11:50 -07:00
|
|
|
fs .create = GParted::FS::EXTERNAL ;
|
2013-06-05 15:15:47 -06:00
|
|
|
fs .create_with_label = GParted::FS::EXTERNAL ;
|
|
|
|
}
|
2010-01-02 04:11:50 -07:00
|
|
|
|
|
|
|
if ( ! Glib::find_program_in_path( "btrfsck" ) .empty() )
|
|
|
|
fs .check = GParted::FS::EXTERNAL ;
|
|
|
|
|
2011-11-11 13:50:53 -07:00
|
|
|
btrfs_found = ( ! Glib::find_program_in_path( "btrfs" ) .empty() ) ;
|
|
|
|
if ( btrfs_found )
|
2011-10-18 10:14:21 -06:00
|
|
|
{
|
2011-11-11 13:50:53 -07:00
|
|
|
//Use newer btrfs multi-tool control command. No need
|
|
|
|
// to test for filesystem show and filesystem resize
|
|
|
|
// sub-commands as they were always included.
|
|
|
|
|
|
|
|
fs .read = GParted::FS::EXTERNAL ;
|
|
|
|
fs .read_label = FS::EXTERNAL ;
|
2012-01-22 13:49:52 -07:00
|
|
|
fs .read_uuid = FS::EXTERNAL ;
|
2011-11-11 13:50:53 -07:00
|
|
|
|
2011-12-28 12:54:12 -07:00
|
|
|
//Resizing of btrfs requires mount, umount and kernel
|
|
|
|
// support as well as btrfs filesystem resize
|
2011-11-11 13:50:53 -07:00
|
|
|
if ( ! Glib::find_program_in_path( "mount" ) .empty()
|
|
|
|
&& ! Glib::find_program_in_path( "umount" ) .empty()
|
|
|
|
&& fs .check
|
2011-12-28 12:54:12 -07:00
|
|
|
&& Utils::kernel_supports_fs( "btrfs" )
|
2011-11-11 13:50:53 -07:00
|
|
|
)
|
|
|
|
{
|
|
|
|
fs .grow = FS::EXTERNAL ;
|
|
|
|
if ( fs .read ) //needed to determine a minimum file system size.
|
|
|
|
fs .shrink = FS::EXTERNAL ;
|
|
|
|
}
|
2011-10-18 10:14:21 -06:00
|
|
|
|
2011-11-01 16:52:33 -06:00
|
|
|
//Test for labelling capability in btrfs command
|
|
|
|
if ( ! Utils::execute_command( "btrfs filesystem label --help", output, error, true ) )
|
|
|
|
fs .write_label = FS::EXTERNAL;
|
|
|
|
}
|
2011-11-11 13:50:53 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
//Fall back to using btrfs-show and btrfsctl, which
|
|
|
|
// were depreciated October 2011
|
|
|
|
|
|
|
|
if ( ! Glib::find_program_in_path( "btrfs-show" ) .empty() )
|
|
|
|
{
|
|
|
|
fs .read = GParted::FS::EXTERNAL ;
|
|
|
|
fs .read_label = FS::EXTERNAL ;
|
2013-09-15 05:28:53 -06:00
|
|
|
fs .read_uuid = FS::EXTERNAL ;
|
2011-11-11 13:50:53 -07:00
|
|
|
}
|
|
|
|
|
2011-12-28 12:54:12 -07:00
|
|
|
//Resizing of btrfs requires btrfsctl, mount, umount
|
|
|
|
// and kernel support
|
2011-11-11 13:50:53 -07:00
|
|
|
if ( ! Glib::find_program_in_path( "btrfsctl" ) .empty()
|
|
|
|
&& ! Glib::find_program_in_path( "mount" ) .empty()
|
|
|
|
&& ! Glib::find_program_in_path( "umount" ) .empty()
|
|
|
|
&& fs .check
|
2011-12-28 12:54:12 -07:00
|
|
|
&& Utils::kernel_supports_fs( "btrfs" )
|
2011-11-11 13:50:53 -07:00
|
|
|
)
|
|
|
|
{
|
|
|
|
fs .grow = FS::EXTERNAL ;
|
|
|
|
if ( fs .read ) //needed to determine a minimum file system size.
|
|
|
|
fs .shrink = FS::EXTERNAL ;
|
|
|
|
}
|
|
|
|
}
|
2011-11-01 16:52:33 -06:00
|
|
|
|
2015-06-19 06:02:32 -06:00
|
|
|
if ( ! Glib::find_program_in_path( "btrfstune" ).empty() )
|
|
|
|
{
|
|
|
|
Utils::execute_command( "btrfstune --help", output, error, true );
|
|
|
|
if ( Utils::regexp_label( error, "^[[:blank:]]*(-u)[[:blank:]]" ) == "-u" )
|
|
|
|
fs.write_uuid = FS::EXTERNAL;
|
|
|
|
}
|
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
if ( fs .check )
|
|
|
|
{
|
|
|
|
fs .copy = GParted::FS::GPARTED ;
|
|
|
|
fs .move = GParted::FS::GPARTED ;
|
|
|
|
}
|
|
|
|
|
2014-03-29 15:12:01 -06:00
|
|
|
fs .online_read = FS::EXTERNAL ;
|
2013-11-15 09:27:12 -07:00
|
|
|
#ifdef ENABLE_ONLINE_RESIZE
|
|
|
|
if ( Utils::kernel_version_at_least( 3, 6, 0 ) )
|
|
|
|
{
|
|
|
|
fs .online_grow = fs .grow ;
|
|
|
|
fs .online_shrink = fs .shrink ;
|
|
|
|
}
|
|
|
|
#endif
|
2012-09-10 09:41:58 -06:00
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
fs .MIN = 256 * MEBIBYTE ;
|
|
|
|
|
2012-02-05 02:08:05 -07:00
|
|
|
//Linux before version 3.2 fails when resizing btrfs file system
|
|
|
|
// to the same size.
|
|
|
|
resize_to_same_size_fails = ! Utils::kernel_version_at_least( 3, 2, 0 ) ;
|
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
return fs ;
|
|
|
|
}
|
|
|
|
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
bool btrfs::is_busy( const Glib::ustring & path )
|
|
|
|
{
|
|
|
|
//A btrfs file system is busy if any of the member devices are mounted.
|
|
|
|
// WARNING:
|
|
|
|
// Removal of the mounting device from a btrfs file system makes it impossible to
|
|
|
|
// determine whether the file system is mounted or not for linux <= 3.4. This is
|
|
|
|
// because /proc/mounts continues to show the old device which is no longer a
|
|
|
|
// member of the file system. Fixed in linux 3.5 by commit:
|
|
|
|
// Btrfs: implement ->show_devname
|
|
|
|
// https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
|
2014-03-25 17:03:30 -06:00
|
|
|
return ! get_mount_device( path ) .empty() ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
}
|
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
bool btrfs::create( const Partition & new_partition, OperationDetail & operationdetail )
|
|
|
|
{
|
2014-12-16 15:04:34 -07:00
|
|
|
return ! execute_command( "mkfs.btrfs -L \"" + new_partition.get_filesystem_label() + "\" " +
|
Time and check nearly all file system action commands (#754684)
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-05 02:31:16 -06:00
|
|
|
new_partition.get_path(),
|
|
|
|
operationdetail, EXEC_CHECK_STATUS );
|
2010-01-02 04:11:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool btrfs::check_repair( const Partition & partition, OperationDetail & operationdetail )
|
|
|
|
{
|
Time and check nearly all file system action commands (#754684)
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-05 02:31:16 -06:00
|
|
|
return ! execute_command( "btrfsck " + partition .get_path(), operationdetail, EXEC_CHECK_STATUS );
|
2010-01-02 04:11:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void btrfs::set_used_sectors( Partition & partition )
|
|
|
|
{
|
2014-03-29 15:12:01 -06:00
|
|
|
//Called when the file system is unmounted *and* when mounted.
|
|
|
|
//
|
|
|
|
// Btrfs has a volume manager layer within the file system which allows it to
|
|
|
|
// provide multiple levels of data redundancy, RAID levels, and use multiple
|
|
|
|
// devices both of which can be changed while the file system is mounted. To
|
|
|
|
// achieve this btrfs has to allocate space at two different levels: (1) chunks
|
|
|
|
// of 256 MiB or more at the volume manager level; and (2) extents at the file
|
|
|
|
// data level.
|
|
|
|
// References:
|
|
|
|
// * Btrfs: Working with multiple devices
|
|
|
|
// https://lwn.net/Articles/577961/
|
|
|
|
// * Btrfs wiki: Glossary
|
|
|
|
// https://btrfs.wiki.kernel.org/index.php/Glossary
|
|
|
|
//
|
|
|
|
// This makes the question of how much disk space is being used in an individual
|
|
|
|
// device a complicated question to answer. Further, the current btrfs tools
|
|
|
|
// don't provide the required information.
|
|
|
|
//
|
|
|
|
// Btrfs filesystem show only provides space usage information at the chunk level
|
|
|
|
// per device. At the file extent level only a single figure for the whole file
|
|
|
|
// system is provided. It also reports size of the data and metadata being
|
|
|
|
// stored, not the larger figure of the amount of space taken after redundancy is
|
|
|
|
// applied. So it is impossible to answer the question of how much disk space is
|
|
|
|
// being used in an individual device. Example output:
|
|
|
|
//
|
|
|
|
// Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
// Guesstimate the per device used figure as the fraction of the file system wide
|
|
|
|
// extent usage based on chunk usage per device.
|
|
|
|
//
|
|
|
|
// Positives:
|
|
|
|
// 1) Per device used figure will correctly be between zero and allocated chunk
|
|
|
|
// size.
|
|
|
|
//
|
|
|
|
// Known inaccuracies:
|
|
|
|
// [for single and multi-device btrfs file systems]
|
|
|
|
// 1) Btrfs filesystem show reports file system wide file extent usage without
|
|
|
|
// considering redundancy applied to that data. (By default btrfs stores two
|
|
|
|
// copies of metadata and one copy of data).
|
|
|
|
// 2) At minimum size when all data has been consolidated there will be a few
|
|
|
|
// partly filled chunks of 256 MiB or more for data and metadata of each
|
|
|
|
// storage profile (RAID level).
|
|
|
|
// [for multi-device btrfs file systems only]
|
|
|
|
// 3) Data may be far from evenly distributed between the chunks on multiple
|
|
|
|
// devices.
|
|
|
|
// 4) Extents can be and are relocated to other devices within the file system
|
|
|
|
// when shrinking a device.
|
2011-11-11 13:50:53 -07:00
|
|
|
if ( btrfs_found )
|
2014-07-22 17:56:13 -06:00
|
|
|
Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
|
2011-11-11 13:50:53 -07:00
|
|
|
else
|
2014-07-22 17:56:13 -06:00
|
|
|
Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
|
|
|
|
//In many cases the exit status doesn't reflect valid output or an error condition
|
|
|
|
// so rely on parsing the output to determine success.
|
|
|
|
|
|
|
|
//Extract the per device size figure. Guesstimate the per device used
|
|
|
|
// figure as discussed above. Example output:
|
|
|
|
//
|
|
|
|
// Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
// Calculations:
|
|
|
|
// ptn fs size = devid size
|
|
|
|
// ptn fs used = total fs used * devid used / sum devid used
|
|
|
|
|
|
|
|
Byte_Value ptn_size = partition .get_byte_length() ;
|
|
|
|
Byte_Value total_fs_used = -1 ; //total fs used
|
|
|
|
Byte_Value sum_devid_used = 0 ; //sum devid used
|
|
|
|
Byte_Value devid_used = -1 ; //devid used
|
|
|
|
Byte_Value devid_size = -1 ; //devid size
|
|
|
|
|
|
|
|
//Btrfs file system wide used bytes (extents and items)
|
|
|
|
Glib::ustring str ;
|
|
|
|
if ( ! ( str = Utils::regexp_label( output, "FS bytes used ([0-9\\.]+( ?[KMGTPE]?i?B)?)" ) ) .empty() )
|
|
|
|
total_fs_used = Utils::round( btrfs_size_to_gdouble( str ) ) ;
|
|
|
|
|
|
|
|
Glib::ustring::size_type offset = 0 ;
|
|
|
|
Glib::ustring::size_type index ;
|
|
|
|
while ( ( index = output .find( "devid ", offset ) ) != Glib::ustring::npos )
|
2010-10-03 08:57:42 -06:00
|
|
|
{
|
2014-07-22 17:56:13 -06:00
|
|
|
Glib::ustring devid_path = Utils::regexp_label( output .substr( index ),
|
|
|
|
"devid .* path (/dev/[[:graph:]]+)" ) ;
|
|
|
|
if ( ! devid_path .empty() )
|
2014-03-29 15:12:01 -06:00
|
|
|
{
|
2014-07-22 17:56:13 -06:00
|
|
|
//Btrfs per devid used bytes (chunks)
|
|
|
|
Byte_Value used = -1 ;
|
|
|
|
if ( ! ( str = Utils::regexp_label( output .substr( index ),
|
|
|
|
"devid .* used ([0-9\\.]+( ?[KMGTPE]?i?B)?) path" ) ) .empty() )
|
2014-03-29 15:12:01 -06:00
|
|
|
{
|
2014-07-22 17:56:13 -06:00
|
|
|
used = btrfs_size_to_num( str, ptn_size, false ) ;
|
|
|
|
sum_devid_used += used ;
|
2014-03-29 15:12:01 -06:00
|
|
|
if ( devid_path == partition .get_path() )
|
2014-07-22 17:56:13 -06:00
|
|
|
devid_used = used ;
|
2014-03-29 15:12:01 -06:00
|
|
|
}
|
Query unallocated space for unmounted file systems (#499202)
Update file system specific implementations to set the size and free
space, thus allowing the unallocated space in the partition to be
calculated, for the following unmounted file systems:
btrfs, ext2, ext3, ext4, fat16, fat32, jfs, nilfs2, ntfs, reiserfs,
reiser4, xfs
Bug #499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-01-10 08:19:01 -07:00
|
|
|
|
2014-07-22 17:56:13 -06:00
|
|
|
if ( devid_path == partition .get_path() )
|
|
|
|
{
|
|
|
|
//Btrfs per device size bytes (chunks)
|
|
|
|
if ( ! ( str = Utils::regexp_label( output .substr( index ),
|
|
|
|
"devid .* size ([0-9\\.]+( ?[KMGTPE]?i?B)?) used " ) ) .empty() )
|
|
|
|
devid_size = btrfs_size_to_num( str, ptn_size, true ) ;
|
|
|
|
}
|
2010-10-03 08:57:42 -06:00
|
|
|
}
|
2014-07-22 17:56:13 -06:00
|
|
|
offset = index + 5 ; //Next find starts immediately after current "devid"
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( total_fs_used > -1 && devid_size > -1 && devid_used > -1 && sum_devid_used > 0 )
|
|
|
|
{
|
|
|
|
T = Utils::round( devid_size / double(partition .sector_size) ) ; //ptn fs size
|
|
|
|
double ptn_fs_used = total_fs_used * ( devid_used / double(sum_devid_used) ) ; //ptn fs used
|
|
|
|
N = T - Utils::round( ptn_fs_used / double(partition .sector_size) ) ;
|
|
|
|
partition .set_sector_usage( T, N ) ;
|
2010-10-03 08:57:42 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ! output .empty() )
|
|
|
|
partition .messages .push_back( output ) ;
|
|
|
|
|
|
|
|
if ( ! error .empty() )
|
|
|
|
partition .messages .push_back( error ) ;
|
|
|
|
}
|
2010-01-02 04:11:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool btrfs::write_label( const Partition & partition, OperationDetail & operationdetail )
|
|
|
|
{
|
2014-12-16 15:04:34 -07:00
|
|
|
return ! execute_command( "btrfs filesystem label " + partition.get_path() +
|
Time and check nearly all file system action commands (#754684)
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-05 02:31:16 -06:00
|
|
|
" \"" + partition.get_filesystem_label() + "\"",
|
|
|
|
operationdetail, EXEC_CHECK_STATUS );
|
2010-01-02 04:11:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool btrfs::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
|
|
|
|
{
|
2011-12-28 12:54:12 -07:00
|
|
|
bool success = true ;
|
2014-04-11 04:27:18 -06:00
|
|
|
Glib::ustring path = partition_new .get_path() ;
|
|
|
|
|
|
|
|
BTRFS_Device btrfs_dev = get_cache_entry( path ) ;
|
|
|
|
if ( btrfs_dev .devid == -1 )
|
|
|
|
{
|
|
|
|
operationdetail .add_child( OperationDetail(
|
|
|
|
String::ucompose( _("Failed to find devid for path %1"), path ), STATUS_ERROR ) ) ;
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
Glib::ustring devid_str = Utils::num_to_str( btrfs_dev .devid ) ;
|
2011-10-18 10:14:21 -06:00
|
|
|
|
2013-11-15 09:27:12 -07:00
|
|
|
Glib::ustring mount_point ;
|
|
|
|
if ( ! partition_new .busy )
|
|
|
|
{
|
|
|
|
mount_point = mk_temp_dir( "", operationdetail ) ;
|
|
|
|
if ( mount_point .empty() )
|
|
|
|
return false ;
|
2014-04-11 04:27:18 -06:00
|
|
|
success &= ! execute_command( "mount -v -t btrfs " + path + " " + mount_point,
|
Refactor flags in method FileSystem::execute_command() (#754684)
Change the two optional boolean parameters into a single optional flags
parameter which uses symbolically defined names. Makes reading the
execute_command() calls much easier to understand. (Implemented as bit
field using the same technique as used for Glib::SpawnFlags [1]).
This changes the calls thus:
execute_command(cmd, od) -> (cmd, od)
execute_command(cmd, od, false) -> (cmd, od, EXEC_NONE) // [2]
execute_command(cmd, od, true ) -> (cmd, od, EXEC_CHECK_STATUS)
execute_command(cmd, od, false, true) -> (cmd, od, EXEC_CANCEL_SAFE)
execute_command(cmd, od, true , true) ->
(cmd, od, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE)
[1] SpawnFlags bitwise operators in
/usr/include/glibmm-2.4/glibmm/spawn.h.
[2] False and EXEC_NONE are the default values for the optional third
parameter before and after this change respectively and both mean
the same. This is being used in btrfs::resize() and being kept for
now despite it being the default.
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-08-29 08:15:24 -06:00
|
|
|
operationdetail, EXEC_CHECK_STATUS );
|
2013-11-15 09:27:12 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
mount_point = partition_new .get_mountpoint() ;
|
2011-10-18 10:14:21 -06:00
|
|
|
|
2011-12-28 12:54:12 -07:00
|
|
|
if ( success )
|
2011-10-18 10:14:21 -06:00
|
|
|
{
|
2011-12-28 12:54:12 -07:00
|
|
|
Glib::ustring size ;
|
2011-10-18 10:14:21 -06:00
|
|
|
if ( ! fill_partition )
|
2011-12-28 12:54:12 -07:00
|
|
|
size = Utils::num_to_str( floor( Utils::sector_to_unit(
|
2011-11-11 13:50:53 -07:00
|
|
|
partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
|
2011-10-18 10:14:21 -06:00
|
|
|
else
|
2011-12-28 12:54:12 -07:00
|
|
|
size = "max" ;
|
|
|
|
Glib::ustring cmd ;
|
2011-11-11 13:50:53 -07:00
|
|
|
if ( btrfs_found )
|
2014-04-11 04:27:18 -06:00
|
|
|
cmd = "btrfs filesystem resize " + devid_str + ":" + size + " " + mount_point ;
|
2011-11-11 13:50:53 -07:00
|
|
|
else
|
2014-04-11 04:27:18 -06:00
|
|
|
cmd = "btrfsctl -r " + devid_str + ":" + size + " " + mount_point ;
|
Time and check nearly all file system action commands (#754684)
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-05 02:31:16 -06:00
|
|
|
exit_status = execute_command( cmd, operationdetail );
|
2012-02-05 02:08:05 -07:00
|
|
|
bool resize_succeeded = ( exit_status == 0 ) ;
|
|
|
|
if ( resize_to_same_size_fails )
|
|
|
|
{
|
|
|
|
//Linux before version 3.2 fails when resizing a
|
|
|
|
// btrfs file system to the same size with ioctl()
|
|
|
|
// returning -1 EINVAL (Invalid argument) from the
|
|
|
|
// kernel btrfs code.
|
|
|
|
// * Btrfs filesystem resize reports this as exit
|
|
|
|
// status 30:
|
|
|
|
// ERROR: Unable to resize '/MOUNTPOINT'
|
|
|
|
// * Btrfsctl -r reports this as exit status 1:
|
|
|
|
// ioctl:: Invalid argument
|
|
|
|
// WARNING:
|
|
|
|
// Ignoring these errors could mask real failures,
|
|
|
|
// but not ignoring them will cause resizing to the
|
|
|
|
// same size as part of check operation to fail.
|
|
|
|
resize_succeeded = ( exit_status == 0
|
Implement shell style exit status decoding (#754684)
Command exit status is a 1 byte value between 0 and 255. [1][2] However
at the Unix API level the value is encoded as documented in the
waitpid(2) manual page. This is true for the Glib API too. [3] This is
why, for example, the comment in ext2::check_repair() reported receiving
undocumented exit status 256. It was actually receiving exit status 1
encoded as per the waitpid(2) method.
Add shell style exit status decoding [2] to execution of all external
commands. Return value from Utils::execute_command() and
FileSystem::execute_command() functions are now:
0 - 125 - Exit status from the command
126 - Error executing the command
127 - Command not found
128+N - Command terminated by signal N
255 - Unexpected waitpid(2) condition
Also adjust checking of the returned statuses as necessary.
[1] Advanced Bash-Scripting Guide: Appendix D. Exit Codes With Special
Meanings
http://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/exitcodes.html
[2] Quote from the bash(1) manual page:
EXIT STATUS
... Exit statuses fall between 0 and 255, though as
explained below, the shell may use values above 125
specially. ...
... When a command terminates on a fatal signal N, bash uses
the value of 128+N as the exit status.
If a command is not found, the child process created to
execute it returns a status of 127. If a command is found
but is not executable, the return status is 126.
[3] Quote from the Glib Reference Manual, Spawning Processes section,
for function g_spawn_check_exit_status():
https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html#g-spawn-check-exit-status
The g_spawn_sync() and g_child_watch_add() family of APIs return
an exit status for subprocesses encoded in a platform-specific
way. On Unix, this is guaranteed to be in the same format
waitpid() returns, ...
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-06 07:39:07 -06:00
|
|
|
|| ( btrfs_found && exit_status == 30 )
|
|
|
|
|| ( ! btrfs_found && exit_status == 1 )
|
2012-02-05 02:08:05 -07:00
|
|
|
) ;
|
|
|
|
}
|
Time and check nearly all file system action commands (#754684)
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-05 02:31:16 -06:00
|
|
|
set_status( operationdetail, resize_succeeded );
|
2011-12-28 12:54:12 -07:00
|
|
|
success &= resize_succeeded ;
|
|
|
|
|
2013-11-15 09:27:12 -07:00
|
|
|
if ( ! partition_new .busy )
|
Refactor flags in method FileSystem::execute_command() (#754684)
Change the two optional boolean parameters into a single optional flags
parameter which uses symbolically defined names. Makes reading the
execute_command() calls much easier to understand. (Implemented as bit
field using the same technique as used for Glib::SpawnFlags [1]).
This changes the calls thus:
execute_command(cmd, od) -> (cmd, od)
execute_command(cmd, od, false) -> (cmd, od, EXEC_NONE) // [2]
execute_command(cmd, od, true ) -> (cmd, od, EXEC_CHECK_STATUS)
execute_command(cmd, od, false, true) -> (cmd, od, EXEC_CANCEL_SAFE)
execute_command(cmd, od, true , true) ->
(cmd, od, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE)
[1] SpawnFlags bitwise operators in
/usr/include/glibmm-2.4/glibmm/spawn.h.
[2] False and EXEC_NONE are the default values for the optional third
parameter before and after this change respectively and both mean
the same. This is being used in btrfs::resize() and being kept for
now despite it being the default.
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-08-29 08:15:24 -06:00
|
|
|
success &= ! execute_command( "umount -v " + mount_point, operationdetail,
|
|
|
|
EXEC_CHECK_STATUS );
|
2011-10-18 10:14:21 -06:00
|
|
|
}
|
|
|
|
|
2013-11-15 09:27:12 -07:00
|
|
|
if ( ! partition_new .busy )
|
|
|
|
rm_temp_dir( mount_point, operationdetail ) ;
|
2011-10-18 10:14:21 -06:00
|
|
|
|
2011-12-28 12:54:12 -07:00
|
|
|
return success ;
|
2010-01-02 04:11:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void btrfs::read_label( Partition & partition )
|
|
|
|
{
|
2011-11-11 13:50:53 -07:00
|
|
|
if ( btrfs_found )
|
2014-07-22 17:19:32 -06:00
|
|
|
Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
|
|
|
|
else
|
|
|
|
Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
|
|
|
|
//In many cases the exit status doesn't reflect valid output or an error condition
|
|
|
|
// so rely on parsing the output to determine success.
|
|
|
|
|
|
|
|
if ( output .compare( 0, 18, "Label: none uuid:" ) == 0 )
|
2011-11-01 12:45:14 -06:00
|
|
|
{
|
2014-07-22 17:19:32 -06:00
|
|
|
//Indistinguishable cases of either no label or the label is actually set
|
|
|
|
// to "none". Assume no label case.
|
2014-12-16 15:04:34 -07:00
|
|
|
partition.set_filesystem_label( "" );
|
2011-11-01 12:45:14 -06:00
|
|
|
}
|
|
|
|
else
|
2011-11-11 13:50:53 -07:00
|
|
|
{
|
2014-07-22 17:19:32 -06:00
|
|
|
//Try matching a label enclosed in single quotes, as used by
|
|
|
|
// btrfs filesystem show, then without quotes, as used by btrfs-show.
|
|
|
|
Glib::ustring label = Utils::regexp_label( output, "^Label: '(.*)' uuid:" ) ;
|
|
|
|
if ( label .empty() )
|
|
|
|
label = Utils::regexp_label( output, "^Label: (.*) uuid:" ) ;
|
|
|
|
|
|
|
|
if ( ! label .empty() )
|
2014-12-16 15:04:34 -07:00
|
|
|
partition.set_filesystem_label( label );
|
2014-07-22 17:19:32 -06:00
|
|
|
else
|
2011-11-11 13:50:53 -07:00
|
|
|
{
|
2014-07-22 17:19:32 -06:00
|
|
|
if ( ! output .empty() )
|
|
|
|
partition .messages .push_back( output ) ;
|
2010-01-02 04:11:50 -07:00
|
|
|
|
2014-07-22 17:19:32 -06:00
|
|
|
if ( ! error .empty() )
|
|
|
|
partition .messages .push_back( error ) ;
|
|
|
|
}
|
2011-11-01 12:45:14 -06:00
|
|
|
}
|
2010-01-02 04:11:50 -07:00
|
|
|
}
|
|
|
|
|
2012-01-22 13:49:52 -07:00
|
|
|
void btrfs::read_uuid( Partition & partition )
|
|
|
|
{
|
|
|
|
if ( btrfs_found )
|
2014-07-22 10:57:33 -06:00
|
|
|
Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
|
|
|
|
else
|
|
|
|
Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
|
|
|
|
//In many cases the exit status doesn't reflect valid output or an error condition
|
|
|
|
// so rely on parsing the output to determine success.
|
|
|
|
|
|
|
|
Glib::ustring uuid_str = Utils::regexp_label( output, "uuid:[[:blank:]]*(" RFC4122_NONE_NIL_UUID_REGEXP ")" ) ;
|
|
|
|
if ( ! uuid_str .empty() )
|
|
|
|
partition .uuid = uuid_str ;
|
2012-01-22 13:49:52 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ! output .empty() )
|
|
|
|
partition .messages .push_back( output ) ;
|
|
|
|
|
|
|
|
if ( ! error .empty() )
|
|
|
|
partition .messages .push_back( error ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-19 06:02:32 -06:00
|
|
|
bool btrfs::write_uuid( const Partition & partition, OperationDetail & operationdetail )
|
|
|
|
{
|
Time and check nearly all file system action commands (#754684)
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
2015-09-05 02:31:16 -06:00
|
|
|
return ! execute_command( "btrfstune -f -u " + partition.get_path(), operationdetail, EXEC_CHECK_STATUS );
|
2015-06-19 06:02:32 -06:00
|
|
|
}
|
|
|
|
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
void btrfs::clear_cache()
|
|
|
|
{
|
|
|
|
btrfs_device_cache .clear() ;
|
|
|
|
}
|
|
|
|
|
2014-03-25 17:03:30 -06:00
|
|
|
//Return the device which is mounting the btrfs in this partition.
|
|
|
|
// Return empty string if not found (not mounted).
|
|
|
|
Glib::ustring btrfs::get_mount_device( const Glib::ustring & path )
|
|
|
|
{
|
2014-04-10 15:28:40 -06:00
|
|
|
BTRFS_Device btrfs_dev = get_cache_entry( path ) ;
|
2014-04-20 12:56:12 -06:00
|
|
|
if ( btrfs_dev .devid == -1 || btrfs_dev .members .empty() )
|
|
|
|
{
|
|
|
|
//WARNING:
|
|
|
|
// No btrfs device cache entry found or entry without any member devices.
|
|
|
|
// Use fallback busy detection method which can only determine if the
|
|
|
|
// mounting device is mounted or not, not any of the other members of a
|
|
|
|
// multi-device btrfs file system.
|
|
|
|
if ( GParted_Core::is_dev_mounted( path ) )
|
|
|
|
return path ;
|
|
|
|
return "" ;
|
|
|
|
}
|
|
|
|
|
2014-04-10 15:28:40 -06:00
|
|
|
for ( unsigned int i = 0 ; i < btrfs_dev .members .size() ; i ++ )
|
|
|
|
if ( GParted_Core::is_dev_mounted( btrfs_dev .members[ i ] ) )
|
|
|
|
return btrfs_dev .members[ i ] ;
|
2014-03-25 17:03:30 -06:00
|
|
|
return "" ;
|
|
|
|
}
|
|
|
|
|
2014-05-16 13:32:37 -06:00
|
|
|
std::vector<Glib::ustring> btrfs::get_members( const Glib::ustring & path )
|
|
|
|
{
|
|
|
|
BTRFS_Device btrfs_dev = get_cache_entry( path ) ;
|
|
|
|
return btrfs_dev .members ;
|
|
|
|
}
|
|
|
|
|
Handle btrfs tools rounding of figures (#499202)
The btrfs programs only provide approximations of file system sizes
because they display figures using binary prefix multipliers to two
decimal places of precision. E.g. 2.00GB. For partition sizes where
the contained file system size rounds upwards, GParted will fail to read
the file system usage and report a warning because the file system will
appear to be larger than the partition.
For example, create a 2047 MiB partition containing a btrfs file system
and display its size.
# btrfs filesystem show
Label: none uuid: 92535375-5e76-4a70-896a-8d796a577993
Total devices 1 FS bytes used 28.00KB
devid 1 size 2.00GB used 240.62MB path /dev/sda12
The file system size appears to be 2048 MiB, but that is larger than the
partition, hence the issue GParted has. (Actually uses the btrfs devid
size which is the size of the btrfs file system within the partition in
question).
This issue is new with the fix for Bug #499202 because it queries the
file system sizes for the first time. The same issue could
theoretically occur previously, but with the used figure (FS bytes
used). This would have been virtually impossible to trigger because
btrfs file system would have to have been greater than 99% full, but
btrfs has been notorious for early reporting of file system full.
The fix is that if a btrfs file system size appears larger than the
partition size, but the minimum possible size which could have been
rounded to the reported figure is within the partition size use the
smaller partition size instead. Apply the method to the used figure
too, in case the file system is 100% full. Also if the btrfs file
system size appears smaller than the partition size, but the maximum
possible size which could have been rounded to the reported figure is
within the partition size use the larger partition size instead to avoid
reporting, presumably false, unallocated space. Not applied to file
system used figure.
Bug 499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-05-30 06:41:59 -06:00
|
|
|
//Private methods
|
|
|
|
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
//Return btrfs device cache entry, incrementally loading cache as required
|
2014-04-10 15:28:40 -06:00
|
|
|
const BTRFS_Device & btrfs::get_cache_entry( const Glib::ustring & path )
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
{
|
2014-04-10 15:28:40 -06:00
|
|
|
std::map<Glib::ustring, BTRFS_Device>::const_iterator bd_iter = btrfs_device_cache .find( path ) ;
|
|
|
|
if ( bd_iter != btrfs_device_cache .end() )
|
|
|
|
return bd_iter ->second ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
|
|
|
|
Glib::ustring output, error ;
|
2014-04-10 15:28:40 -06:00
|
|
|
std::vector<int> devid_list ;
|
|
|
|
std::vector<Glib::ustring> path_list ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
if ( btrfs_found )
|
2014-07-23 04:26:11 -06:00
|
|
|
Utils::execute_command( "btrfs filesystem show " + path, output, error, true ) ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
else
|
2014-07-23 04:26:11 -06:00
|
|
|
Utils::execute_command( "btrfs-show " + path, output, error, true ) ;
|
|
|
|
//In many cases the exit status doesn't reflect valid output or an error condition
|
|
|
|
// so rely on parsing the output to determine success.
|
|
|
|
|
|
|
|
//Extract devid and path for each device from output like this:
|
|
|
|
// Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
|
|
|
|
// 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
|
|
|
|
Glib::ustring::size_type offset = 0 ;
|
|
|
|
Glib::ustring::size_type index ;
|
|
|
|
while ( ( index = output .find( "devid ", offset ) ) != Glib::ustring::npos )
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
{
|
2014-07-23 04:26:11 -06:00
|
|
|
int devid = -1 ;
|
|
|
|
sscanf( output .substr( index ) .c_str(), "devid %d", &devid ) ;
|
|
|
|
Glib::ustring devid_path = Utils::regexp_label( output .substr( index ),
|
|
|
|
"devid .* path (/dev/[[:graph:]]+)" ) ;
|
|
|
|
if ( devid > -1 && ! devid_path .empty() )
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
{
|
2014-07-23 04:26:11 -06:00
|
|
|
devid_list .push_back( devid ) ;
|
|
|
|
path_list .push_back( devid_path ) ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
}
|
2014-07-23 04:26:11 -06:00
|
|
|
offset = index + 5 ; //Next find starts immediately after current "devid"
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
}
|
|
|
|
//Add cache entries for all found devices
|
2014-04-10 15:28:40 -06:00
|
|
|
for ( unsigned int i = 0 ; i < devid_list .size() ; i ++ )
|
|
|
|
{
|
|
|
|
BTRFS_Device btrfs_dev ;
|
|
|
|
btrfs_dev .devid = devid_list[ i ] ;
|
|
|
|
btrfs_dev .members = path_list ;
|
|
|
|
btrfs_device_cache[ path_list[ i ] ] = btrfs_dev ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bd_iter = btrfs_device_cache .find( path ) ;
|
|
|
|
if ( bd_iter != btrfs_device_cache .end() )
|
|
|
|
return bd_iter ->second ;
|
|
|
|
|
2014-07-23 04:26:11 -06:00
|
|
|
//If for any reason we fail to parse the information return an "unknown" record
|
2014-04-10 15:28:40 -06:00
|
|
|
static BTRFS_Device btrfs_dev = { -1, } ;
|
|
|
|
return btrfs_dev ;
|
Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
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
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
2014-02-17 15:39:34 -07:00
|
|
|
}
|
|
|
|
|
Handle btrfs tools rounding of figures (#499202)
The btrfs programs only provide approximations of file system sizes
because they display figures using binary prefix multipliers to two
decimal places of precision. E.g. 2.00GB. For partition sizes where
the contained file system size rounds upwards, GParted will fail to read
the file system usage and report a warning because the file system will
appear to be larger than the partition.
For example, create a 2047 MiB partition containing a btrfs file system
and display its size.
# btrfs filesystem show
Label: none uuid: 92535375-5e76-4a70-896a-8d796a577993
Total devices 1 FS bytes used 28.00KB
devid 1 size 2.00GB used 240.62MB path /dev/sda12
The file system size appears to be 2048 MiB, but that is larger than the
partition, hence the issue GParted has. (Actually uses the btrfs devid
size which is the size of the btrfs file system within the partition in
question).
This issue is new with the fix for Bug #499202 because it queries the
file system sizes for the first time. The same issue could
theoretically occur previously, but with the used figure (FS bytes
used). This would have been virtually impossible to trigger because
btrfs file system would have to have been greater than 99% full, but
btrfs has been notorious for early reporting of file system full.
The fix is that if a btrfs file system size appears larger than the
partition size, but the minimum possible size which could have been
rounded to the reported figure is within the partition size use the
smaller partition size instead. Apply the method to the used figure
too, in case the file system is 100% full. Also if the btrfs file
system size appears smaller than the partition size, but the maximum
possible size which could have been rounded to the reported figure is
within the partition size use the larger partition size instead to avoid
reporting, presumably false, unallocated space. Not applied to file
system used figure.
Bug 499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-05-30 06:41:59 -06:00
|
|
|
//Return the value of a btrfs tool formatted size, including reversing
|
|
|
|
// changes in certain cases caused by using binary prefix multipliers
|
|
|
|
// and rounding to two decimal places of precision. E.g. "2.00GB".
|
2012-07-07 05:23:01 -06:00
|
|
|
Byte_Value btrfs::btrfs_size_to_num( Glib::ustring str, Byte_Value ptn_bytes, bool scale_up )
|
Handle btrfs tools rounding of figures (#499202)
The btrfs programs only provide approximations of file system sizes
because they display figures using binary prefix multipliers to two
decimal places of precision. E.g. 2.00GB. For partition sizes where
the contained file system size rounds upwards, GParted will fail to read
the file system usage and report a warning because the file system will
appear to be larger than the partition.
For example, create a 2047 MiB partition containing a btrfs file system
and display its size.
# btrfs filesystem show
Label: none uuid: 92535375-5e76-4a70-896a-8d796a577993
Total devices 1 FS bytes used 28.00KB
devid 1 size 2.00GB used 240.62MB path /dev/sda12
The file system size appears to be 2048 MiB, but that is larger than the
partition, hence the issue GParted has. (Actually uses the btrfs devid
size which is the size of the btrfs file system within the partition in
question).
This issue is new with the fix for Bug #499202 because it queries the
file system sizes for the first time. The same issue could
theoretically occur previously, but with the used figure (FS bytes
used). This would have been virtually impossible to trigger because
btrfs file system would have to have been greater than 99% full, but
btrfs has been notorious for early reporting of file system full.
The fix is that if a btrfs file system size appears larger than the
partition size, but the minimum possible size which could have been
rounded to the reported figure is within the partition size use the
smaller partition size instead. Apply the method to the used figure
too, in case the file system is 100% full. Also if the btrfs file
system size appears smaller than the partition size, but the maximum
possible size which could have been rounded to the reported figure is
within the partition size use the larger partition size instead to avoid
reporting, presumably false, unallocated space. Not applied to file
system used figure.
Bug 499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-05-30 06:41:59 -06:00
|
|
|
{
|
|
|
|
Byte_Value size_bytes = Utils::round( btrfs_size_to_gdouble( str ) ) ;
|
|
|
|
gdouble delta = btrfs_size_max_delta( str ) ;
|
|
|
|
Byte_Value upper_size = size_bytes + ceil( delta ) ;
|
|
|
|
Byte_Value lower_size = size_bytes - floor( delta ) ;
|
|
|
|
|
|
|
|
if ( size_bytes > ptn_bytes && lower_size <= ptn_bytes )
|
|
|
|
{
|
|
|
|
//Scale value down to partition size:
|
|
|
|
// The btrfs tool reported size appears larger than the partition
|
|
|
|
// size, but the minimum possible size which could have been rounded
|
|
|
|
// to the reported figure is within the partition size so use the
|
|
|
|
// smaller partition size instead. Applied to FS device size and FS
|
|
|
|
// wide used bytes.
|
|
|
|
// ............| ptn_bytes
|
|
|
|
// [ x ) size_bytes with upper & lower size
|
|
|
|
// x scaled down size_bytes
|
|
|
|
// Do this to avoid the FS size or used bytes being larger than the
|
|
|
|
// partition size and GParted failing to read the file system usage and
|
|
|
|
// report a warning.
|
|
|
|
size_bytes = ptn_bytes ;
|
|
|
|
}
|
|
|
|
else if ( scale_up && size_bytes < ptn_bytes && upper_size > ptn_bytes )
|
|
|
|
{
|
|
|
|
//Scale value up to partition size:
|
|
|
|
// The btrfs tool reported size appears smaller than the partition
|
|
|
|
// size, but the maximum possible size which could have been rounded
|
|
|
|
// to the reported figure is within the partition size so use the
|
|
|
|
// larger partition size instead. Applied to FS device size only.
|
|
|
|
// ............| ptn_bytes
|
|
|
|
// [ x ) size_bytes with upper & lower size
|
|
|
|
// x scaled up size_bytes
|
|
|
|
// Make an assumption that the file system actually fills the
|
|
|
|
// partition, rather than is slightly smaller to avoid false reporting
|
|
|
|
// of unallocated space.
|
|
|
|
size_bytes = ptn_bytes ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return size_bytes ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Return maximum delta for which num +/- delta would be rounded by btrfs
|
|
|
|
// tools to str. E.g. btrfs_size_max_delta("2.00GB") -> 5368709.12
|
2012-07-07 05:23:01 -06:00
|
|
|
gdouble btrfs::btrfs_size_max_delta( Glib::ustring str )
|
Handle btrfs tools rounding of figures (#499202)
The btrfs programs only provide approximations of file system sizes
because they display figures using binary prefix multipliers to two
decimal places of precision. E.g. 2.00GB. For partition sizes where
the contained file system size rounds upwards, GParted will fail to read
the file system usage and report a warning because the file system will
appear to be larger than the partition.
For example, create a 2047 MiB partition containing a btrfs file system
and display its size.
# btrfs filesystem show
Label: none uuid: 92535375-5e76-4a70-896a-8d796a577993
Total devices 1 FS bytes used 28.00KB
devid 1 size 2.00GB used 240.62MB path /dev/sda12
The file system size appears to be 2048 MiB, but that is larger than the
partition, hence the issue GParted has. (Actually uses the btrfs devid
size which is the size of the btrfs file system within the partition in
question).
This issue is new with the fix for Bug #499202 because it queries the
file system sizes for the first time. The same issue could
theoretically occur previously, but with the used figure (FS bytes
used). This would have been virtually impossible to trigger because
btrfs file system would have to have been greater than 99% full, but
btrfs has been notorious for early reporting of file system full.
The fix is that if a btrfs file system size appears larger than the
partition size, but the minimum possible size which could have been
rounded to the reported figure is within the partition size use the
smaller partition size instead. Apply the method to the used figure
too, in case the file system is 100% full. Also if the btrfs file
system size appears smaller than the partition size, but the maximum
possible size which could have been rounded to the reported figure is
within the partition size use the larger partition size instead to avoid
reporting, presumably false, unallocated space. Not applied to file
system used figure.
Bug 499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-05-30 06:41:59 -06:00
|
|
|
{
|
|
|
|
Glib::ustring limit_str ;
|
|
|
|
//Create limit_str. E.g. str = "2.00GB" -> limit_str = "0.005GB"
|
|
|
|
for ( Glib::ustring::iterator p = str .begin() ; p != str .end() ; p ++ )
|
|
|
|
{
|
|
|
|
if ( isdigit( *p ) )
|
|
|
|
limit_str .append( "0" ) ;
|
|
|
|
else if ( *p == '.' )
|
|
|
|
limit_str .append( "." ) ;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
limit_str .append( "5" ) ;
|
|
|
|
limit_str .append( p, str .end() ) ;
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gdouble max_delta = btrfs_size_to_gdouble( limit_str ) ;
|
|
|
|
return max_delta ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Return the value of a btrfs tool formatted size.
|
|
|
|
// E.g. btrfs_size_to_gdouble("2.00GB") -> 2147483648.0
|
2012-07-07 05:23:01 -06:00
|
|
|
gdouble btrfs::btrfs_size_to_gdouble( Glib::ustring str )
|
Query unallocated space for unmounted file systems (#499202)
Update file system specific implementations to set the size and free
space, thus allowing the unallocated space in the partition to be
calculated, for the following unmounted file systems:
btrfs, ext2, ext3, ext4, fat16, fat32, jfs, nilfs2, ntfs, reiserfs,
reiser4, xfs
Bug #499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-01-10 08:19:01 -07:00
|
|
|
{
|
|
|
|
gchar * suffix ;
|
|
|
|
gdouble rawN = g_ascii_strtod( str .c_str(), & suffix ) ;
|
2013-08-27 08:29:26 -06:00
|
|
|
while ( isspace( suffix[0] ) ) //Skip white space before suffix
|
|
|
|
suffix ++ ;
|
Query unallocated space for unmounted file systems (#499202)
Update file system specific implementations to set the size and free
space, thus allowing the unallocated space in the partition to be
calculated, for the following unmounted file systems:
btrfs, ext2, ext3, ext4, fat16, fat32, jfs, nilfs2, ntfs, reiserfs,
reiser4, xfs
Bug #499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-01-10 08:19:01 -07:00
|
|
|
unsigned long long mult ;
|
|
|
|
switch ( suffix[0] )
|
|
|
|
{
|
|
|
|
case 'K': mult = KIBIBYTE ; break ;
|
|
|
|
case 'M': mult = MEBIBYTE ; break ;
|
|
|
|
case 'G': mult = GIBIBYTE ; break ;
|
|
|
|
case 'T': mult = TEBIBYTE ; break ;
|
2013-08-27 08:29:26 -06:00
|
|
|
case 'P': mult = PEBIBYTE ; break ;
|
|
|
|
case 'E': mult = EXBIBYTE ; break ;
|
Query unallocated space for unmounted file systems (#499202)
Update file system specific implementations to set the size and free
space, thus allowing the unallocated space in the partition to be
calculated, for the following unmounted file systems:
btrfs, ext2, ext3, ext4, fat16, fat32, jfs, nilfs2, ntfs, reiserfs,
reiser4, xfs
Bug #499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-01-10 08:19:01 -07:00
|
|
|
default: mult = 1 ; break ;
|
|
|
|
}
|
Handle btrfs tools rounding of figures (#499202)
The btrfs programs only provide approximations of file system sizes
because they display figures using binary prefix multipliers to two
decimal places of precision. E.g. 2.00GB. For partition sizes where
the contained file system size rounds upwards, GParted will fail to read
the file system usage and report a warning because the file system will
appear to be larger than the partition.
For example, create a 2047 MiB partition containing a btrfs file system
and display its size.
# btrfs filesystem show
Label: none uuid: 92535375-5e76-4a70-896a-8d796a577993
Total devices 1 FS bytes used 28.00KB
devid 1 size 2.00GB used 240.62MB path /dev/sda12
The file system size appears to be 2048 MiB, but that is larger than the
partition, hence the issue GParted has. (Actually uses the btrfs devid
size which is the size of the btrfs file system within the partition in
question).
This issue is new with the fix for Bug #499202 because it queries the
file system sizes for the first time. The same issue could
theoretically occur previously, but with the used figure (FS bytes
used). This would have been virtually impossible to trigger because
btrfs file system would have to have been greater than 99% full, but
btrfs has been notorious for early reporting of file system full.
The fix is that if a btrfs file system size appears larger than the
partition size, but the minimum possible size which could have been
rounded to the reported figure is within the partition size use the
smaller partition size instead. Apply the method to the used figure
too, in case the file system is 100% full. Also if the btrfs file
system size appears smaller than the partition size, but the maximum
possible size which could have been rounded to the reported figure is
within the partition size use the larger partition size instead to avoid
reporting, presumably false, unallocated space. Not applied to file
system used figure.
Bug 499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-05-30 06:41:59 -06:00
|
|
|
return rawN * mult ;
|
Query unallocated space for unmounted file systems (#499202)
Update file system specific implementations to set the size and free
space, thus allowing the unallocated space in the partition to be
calculated, for the following unmounted file systems:
btrfs, ext2, ext3, ext4, fat16, fat32, jfs, nilfs2, ntfs, reiserfs,
reiser4, xfs
Bug #499202 - gparted does not see the difference if partition size
differs from filesystem size
2012-01-10 08:19:01 -07:00
|
|
|
}
|
2012-01-22 13:49:52 -07:00
|
|
|
|
2010-01-02 04:11:50 -07:00
|
|
|
} //GParted
|