[gparted] Use newer btrfs multi-tool control command first
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Use newer btrfs multi-tool control command first
- Date: Sun, 13 Nov 2011 16:43:35 +0000 (UTC)
commit a580abbc30e88cb1895af342d43dcbb98183a9d5
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Fri Nov 11 20:50:53 2011 +0000
Use newer btrfs multi-tool control command first
Btrfsctl and btrfs-show were depreciated in October 2011 and have been
superseeded by the newer btrfs multi-tool control command. Use btrfs as
first choice, falling back to btrfsctl and btrfs-show when not found.
src/btrfs.cc | 135 +++++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 100 insertions(+), 35 deletions(-)
---
diff --git a/src/btrfs.cc b/src/btrfs.cc
index 41d38bf..7af0b5e 100644
--- a/src/btrfs.cc
+++ b/src/btrfs.cc
@@ -22,41 +22,68 @@
namespace GParted
{
+bool btrfs_found = false ;
+
FS btrfs::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_BTRFS ;
- if ( ! Glib::find_program_in_path( "btrfs-show" ) .empty() )
- {
- fs .read = GParted::FS::EXTERNAL ;
- fs .read_label = FS::EXTERNAL ;
- }
-
if ( ! Glib::find_program_in_path( "mkfs.btrfs" ) .empty() )
fs .create = GParted::FS::EXTERNAL ;
if ( ! Glib::find_program_in_path( "btrfsck" ) .empty() )
fs .check = GParted::FS::EXTERNAL ;
- //resizing of btrfs requires btrfsctl, mount, and umount
- if ( ! Glib::find_program_in_path( "btrfsctl" ) .empty()
- && ! Glib::find_program_in_path( "mount" ) .empty()
- && ! Glib::find_program_in_path( "umount" ) .empty()
- && fs .check
- )
+ btrfs_found = ( ! Glib::find_program_in_path( "btrfs" ) .empty() ) ;
+ if ( btrfs_found )
{
- fs .grow = FS::EXTERNAL ;
- if ( fs .read ) //needed to determine a minimum file system size.
- fs .shrink = FS::EXTERNAL ;
- }
+ //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 ;
+
+ //Resizing of btrfs requires mount, umount as well as
+ // btrfs filesystem resize
+ if ( ! Glib::find_program_in_path( "mount" ) .empty()
+ && ! Glib::find_program_in_path( "umount" ) .empty()
+ && fs .check
+ )
+ {
+ fs .grow = FS::EXTERNAL ;
+ if ( fs .read ) //needed to determine a minimum file system size.
+ fs .shrink = FS::EXTERNAL ;
+ }
- if ( ! Glib::find_program_in_path( "btrfs" ) .empty() )
- {
//Test for labelling capability in btrfs command
if ( ! Utils::execute_command( "btrfs filesystem label --help", output, error, true ) )
fs .write_label = FS::EXTERNAL;
}
+ 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 ;
+ }
+
+ //Resizing of btrfs requires btrfsctl, mount, and umount
+ if ( ! Glib::find_program_in_path( "btrfsctl" ) .empty()
+ && ! Glib::find_program_in_path( "mount" ) .empty()
+ && ! Glib::find_program_in_path( "umount" ) .empty()
+ && fs .check
+ )
+ {
+ fs .grow = FS::EXTERNAL ;
+ if ( fs .read ) //needed to determine a minimum file system size.
+ fs .shrink = FS::EXTERNAL ;
+ }
+ }
if ( fs .check )
{
@@ -81,7 +108,12 @@ bool btrfs::check_repair( const Partition & partition, OperationDetail & operati
void btrfs::set_used_sectors( Partition & partition )
{
- if ( ! Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) )
+
+ if ( btrfs_found )
+ exit_status = Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
+ else
+ exit_status = Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
+ if ( ! exit_status )
{
Glib::ustring size_label;
if ( ((index = output .find( "FS bytes" )) < output .length()) &&
@@ -148,6 +180,7 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
operationdetail .add_child( OperationDetail( str_temp, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
char dtemplate[] = "/tmp/gparted-XXXXXXXX" ;
Glib::ustring dname = mkdtemp( dtemplate ) ;
+ Glib::ustring str_size ;
if( dname .empty() )
{
//Failed to create temporary directory
@@ -167,20 +200,36 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
if ( exit_status )
{
//Build resize command
- str_temp = "btrfsctl" ;
if ( ! fill_partition )
- {
- str_temp += " -r " + Utils::num_to_str( floor( Utils::sector_to_unit(
- partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
- }
+ str_size = Utils::num_to_str( floor( Utils::sector_to_unit(
+ partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
else
- str_temp += " -r max" ;
- str_temp += " " + dname ;
+ str_size = "max" ;
+
+ if ( btrfs_found )
+ str_temp = "btrfs filesystem resize " + str_size + " " + dname ;
+ else
+ str_temp = "btrfsctl -r " + str_size + " " + dname ;
//Execute the command
exit_status = execute_command( str_temp, operationdetail ) ;
- //Sometimes btrfsctl returns an exit status of 256 on successful resize.
- exit_status = ( exit_status == 0 || exit_status == 256 ) ;
+ //Resizing a btrfs file system for a second time to the
+ // same size results in 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 partition shinks to
+ // fail on the second "grow file system to fill the
+ // partition" resize.
+ exit_status = ( exit_status == 0
+ || ( btrfs_found && exit_status == 30<<8 )
+ || ( ! btrfs_found && exit_status == 1<<8 )
+ ) ;
//Always unmount the file system
str_temp = "umount -v " + dname ;
@@ -196,17 +245,33 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
void btrfs::read_label( Partition & partition )
{
- if ( ! Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) )
+ if ( btrfs_found )
{
- Glib::ustring label = Utils::regexp_label( output, "^Label: (.*) uuid:" ) ;
- //Btrfs-show reports "none" when there is no label, but
- // this is indistinguishable from the label actually
- // being "none". Assume no label case.
- if ( label != "none" )
- partition .label = label ;
+ exit_status = Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
+ if ( ! exit_status )
+ {
+ partition .label = Utils::regexp_label( output, "^Label: '(.*)' uuid:" );
+ //Btrfs filesystem show encloses the label in single
+ // quotes or reports "none" without single quotes, so
+ // the cases are disginguishable and this regexp won't
+ // match the no label case.
+ }
}
else
{
+ exit_status = Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
+ if ( ! exit_status )
+ {
+ Glib::ustring label = Utils::regexp_label( output, "^Label: (.*) uuid:" ) ;
+ //Btrfs-show reports "none" when there is no label, but
+ // this is indistinguishable from the label actually
+ // being "none". Assume no label case.
+ if ( label != "none" )
+ partition .label = label ;
+ }
+ }
+ if ( exit_status )
+ {
if ( ! output .empty() )
partition .messages .push_back( output ) ;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]