[gparted] Use external tools udfinfo and udflabel for UDF file system (#792052)
- From: Mike Fleetwood <mfleetwo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Use external tools udfinfo and udflabel for UDF file system (#792052)
- Date: Thu, 4 Jan 2018 17:03:32 +0000 (UTC)
commit 2f532be9f973e2de9f259ec1c6ec29cff4d32815
Author: Pali Rohár <pali rohar gmail com>
Date: Tue Jan 2 22:13:00 2018 +0100
Use external tools udfinfo and udflabel for UDF file system (#792052)
Those external tools were introduced in version 2.0 of udftools package
and can show or change UDF label, UDF uuid and can provide information
needed for counting total/free sectors.
Bug 792052 - Add support for changing UDF label/uuid and show disk usage
include/udf.h | 5 ++
src/udf.cc | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 120 insertions(+), 4 deletions(-)
---
diff --git a/include/udf.h b/include/udf.h
index 65d1226..c34a8a4 100644
--- a/include/udf.h
+++ b/include/udf.h
@@ -33,6 +33,11 @@ public:
udf() : old_mkudffs( false ) {};
FS get_filesystem_support();
+ void set_used_sectors( Partition & partition );
+ void read_label( Partition & partition );
+ bool write_label( const Partition & partition, OperationDetail & operationdetail );
+ void read_uuid( Partition & partition );
+ bool write_uuid( const Partition & partition, OperationDetail & operationdetail );
bool create( const Partition & new_partition, OperationDetail & operationdetail );
private:
diff --git a/src/udf.cc b/src/udf.cc
index ee0f27b..72d17ca 100644
--- a/src/udf.cc
+++ b/src/udf.cc
@@ -19,12 +19,13 @@
#include "Utils.h"
#include <stddef.h>
+#include <stdlib.h>
#include <glibmm/ustring.h>
namespace GParted
{
-const Byte_Value MIN_UDF_BLOCKS = 282;
+const Byte_Value MIN_UDF_BLOCKS = 300;
const Byte_Value MAX_UDF_BLOCKS = (1LL << 32) - 1;
const Byte_Value MIN_UDF_BLOCKSIZE = 512;
@@ -38,8 +39,6 @@ FS udf::get_filesystem_support()
fs.move = FS::GPARTED;
fs.copy = FS::GPARTED;
fs.online_read = FS::GPARTED;
- fs.MIN = MIN_UDF_BLOCKS * MIN_UDF_BLOCKSIZE;
- fs.MAX = MAX_UDF_BLOCKS * MAX_UDF_BLOCKSIZE;
old_mkudffs = false;
if ( ! Glib::find_program_in_path( "mkudffs" ).empty() )
@@ -52,11 +51,123 @@ FS udf::get_filesystem_support()
old_mkudffs = Utils::regexp_label( output + error, "--label" ).empty();
}
- // NOTE: Other external programs do not exist yet
+ if ( ! Glib::find_program_in_path( "udfinfo" ).empty() )
+ {
+ fs.read = FS::EXTERNAL;
+ fs.read_uuid = FS::EXTERNAL;
+ }
+
+ if ( ! Glib::find_program_in_path( "udflabel" ).empty() )
+ {
+ fs.read_label = FS::EXTERNAL;
+ fs.write_label = FS::EXTERNAL;
+ fs.write_uuid = FS::EXTERNAL;
+ }
+
+ fs.MIN = MIN_UDF_BLOCKS * MIN_UDF_BLOCKSIZE;
+ fs.MAX = MAX_UDF_BLOCKS * MAX_UDF_BLOCKSIZE;
return fs;
}
+void udf::set_used_sectors( Partition & partition )
+{
+ exit_status = Utils::execute_command( "udfinfo --utf8 " + Glib::shell_quote( partition.get_path() ),
+ output, error, true );
+ if ( exit_status != 0 )
+ {
+ if ( ! output.empty() )
+ partition.push_back_message( output );
+
+ if ( ! error.empty() )
+ partition.push_back_message( error );
+ return;
+ }
+
+ // UDF file system block size. All other values are numbers of blocks.
+ const Glib::ustring block_size_str = Utils::regexp_label( output, "^blocksize=([0-9]+)$" );
+ // Number of available blocks on block device usable for UDF
+ const Glib::ustring blocks_str = Utils::regexp_label( output, "^blocks=([0-9]+)$" );
+ // Number of blocks already used for stored files
+ const Glib::ustring used_blocks_str = Utils::regexp_label( output, "^usedblocks=([0-9]+)$" );
+ // Number of blocks which are free for storing new files
+ const Glib::ustring free_blocks_str = Utils::regexp_label( output, "^freeblocks=([0-9]+)$" );
+ // Number of blocks which are after the last block used by UDF
+ const Glib::ustring behind_blocks_str = Utils::regexp_label( output, "^behindblocks=([0-9]+)$" );
+
+ if ( block_size_str.empty() || blocks_str.empty() ||
+ used_blocks_str.empty() || free_blocks_str.empty() || behind_blocks_str.empty() )
+ return;
+
+ unsigned long long int block_size = atoll( block_size_str.c_str() );
+ unsigned long long int blocks = atoll( blocks_str.c_str() );
+ unsigned long long int used_blocks = atoll( used_blocks_str.c_str() );
+ unsigned long long int free_blocks = atoll( free_blocks_str.c_str() );
+ unsigned long long int behind_blocks = atoll( behind_blocks_str.c_str() );
+
+ // Number of blocks used by UDF
+ unsigned long long int udf_blocks = blocks - behind_blocks;
+
+ // Number of used blocks stored in UDF file system does not have to be correct
+ if ( used_blocks > udf_blocks )
+ used_blocks = udf_blocks;
+ if ( free_blocks > udf_blocks - used_blocks )
+ free_blocks = 0;
+
+ Sector total_sectors = ( udf_blocks * block_size + partition.sector_size - 1 ) /
partition.sector_size;
+ Sector free_sectors = ( free_blocks * block_size ) / partition.sector_size;
+
+ partition.set_sector_usage( total_sectors, free_sectors );
+ partition.fs_block_size = block_size;
+}
+
+void udf::read_label( Partition & partition )
+{
+ if ( ! Utils::execute_command( "udflabel --utf8 " + Glib::shell_quote( partition.get_path() ),
+ output, error, true ) )
+ {
+ partition.set_filesystem_label( Utils::trim( output ) );
+ }
+ else
+ {
+ if ( ! output.empty() )
+ partition.push_back_message( output );
+
+ if ( ! error.empty() )
+ partition.push_back_message( error );
+ }
+}
+
+bool udf::write_label( const Partition & partition, OperationDetail & operationdetail )
+{
+ return ! execute_command( "udflabel --utf8 " + Glib::shell_quote( partition.get_path() ) +
+ " " + Glib::shell_quote( partition.get_filesystem_label() ),
+ operationdetail, EXEC_CHECK_STATUS );
+}
+
+void udf::read_uuid( Partition & partition )
+{
+ if ( ! Utils::execute_command( "udfinfo --utf8 " + Glib::shell_quote( partition.get_path() ),
+ output, error, true ) )
+ {
+ partition.uuid = Utils::regexp_label( output, "^uuid=(.*)$" );
+ }
+ else
+ {
+ if ( ! output.empty() )
+ partition.push_back_message( output );
+
+ if ( ! error.empty() )
+ partition.push_back_message( error );
+ }
+}
+
+bool udf::write_uuid( const Partition & partition, OperationDetail & operationdetail )
+{
+ return ! execute_command( "udflabel --utf8 --uuid=random " + Glib::shell_quote( partition.get_path()
),
+ operationdetail, EXEC_CHECK_STATUS );
+}
+
bool udf::create( const Partition & new_partition, OperationDetail & operationdetail )
{
// NOTE: mkudffs from udftools prior to version 1.1 does not check for partition
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]