From 86111fe12a26d23d9fc2a9e2d19281290ecaf985 Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Sun, 5 Jan 2014 00:32:54 -0500 Subject: [PATCH] Use e2image to move/copy ext[234] file systems (#721516) Use e2image features added in e2fsprogs 1.42.9 to move/copy an ext[234] file system more efficiently by skipping unused blocks. Fall back to the internal copy algorithm if e2image is not found or does not support move/copy. Bug #721516 - Use e2image to move/copy ext[234] filesystems --- include/ext2.h | 6 ++++++ src/ext2.cc | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/include/ext2.h b/include/ext2.h index b9c7af45..778720aa 100644 --- a/include/ext2.h +++ b/include/ext2.h @@ -38,6 +38,12 @@ public: bool create( const Partition & new_partition, OperationDetail & operationdetail ) ; bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ; bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ; + bool move( const Partition & partition_new, + const Partition & partition_old, + OperationDetail & operationdetail ); + bool copy( const Partition & partition_new, + Partition & partition_old, + OperationDetail & operationdetail ); }; } //GParted diff --git a/src/ext2.cc b/src/ext2.cc index c77d49ac..505bcb38 100644 --- a/src/ext2.cc +++ b/src/ext2.cc @@ -60,8 +60,18 @@ FS ext2::get_filesystem_support() if ( fs .check ) { - fs .copy = FS::GPARTED ; - fs .move = FS::GPARTED ; + fs.copy = fs.move = FS::GPARTED ; + + //If supported, use e2image to copy/move the file system as it + // only copies used blocks, skipping unused blocks. This is more + // efficient than copying all blocks used by GParted's internal + // method. + if ( ! Glib::find_program_in_path( "e2image" ) .empty() ) + { + Utils::execute_command( "e2image", output, error, true ) ; + if ( Utils::regexp_label( error, "(-o src_offset)" ) == "-o src_offset" ) + fs.copy = fs.move = FS::EXTERNAL ; + } } fs .online_read = FS::EXTERNAL ; @@ -205,6 +215,29 @@ bool ext2::check_repair( const Partition & partition, OperationDetail & operatio return ( exit_status == 0 || exit_status == 1 || exit_status == 2 || exit_status == 256 ) ; } +bool ext2::move( const Partition & partition_new, + const Partition & partition_old, + OperationDetail & operationdetail ) +{ + Sector distance; + Glib::ustring offset; + distance = partition_old.sector_start - partition_new.sector_start; + offset = Utils::num_to_str( llabs(distance) * partition_new.sector_size ); + if ( distance < 0 ) + return ! execute_command( "e2image -ra -p -o " + offset + " " + partition_new.get_path(), + operationdetail, true, true ); + else + return ! execute_command( "e2image -ra -p -O " + offset + " " + partition_new.get_path(), + operationdetail, true, true ); + +} + +bool ext2::copy( const Partition & src_part, + Partition & dest_part, + OperationDetail & operationdetail ) +{ + return ! execute_command( "e2image -ra -p " + src_part.get_path() + " " + dest_part.get_path(), + operationdetail, true, true ); +} + } //GParted - -