[gparted] Switch to faster ntfsinfo to read NTFS usage (#47)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Switch to faster ntfsinfo to read NTFS usage (#47)
- Date: Wed, 17 Apr 2019 17:18:16 +0000 (UTC)
commit ef4d4cb100156a13b6b64641010e88b8899c8b12
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Sun Apr 14 10:20:04 2019 +0100
Switch to faster ntfsinfo to read NTFS usage (#47)
A user reported GParted was slow to refresh and timing ntfsresize to
query his file systems found that it was taking 4.7 seconds and 9.2
seconds for sizes 31.7 GiB and 49 GiB NTFS file systems respectively.
Almost 14 seconds just to read the usage.
Created a 4 GiB NTFS and filled it with as many 4 KiB files as possible,
just over 800,000 files.
# df -k /mnt/2
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sdb2 4194300 4193860 440 100% /mnt/2
# df -i /mnt/2
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sdb2 819640 808591 11049 99% /mnt/2
Testing perform of ntfsresize:
# time ntfsresize --info --force --no-progress-bar /dev/sdb2 | \
> egrep 'Current volume size|resize at|Cluster size'
Cluster size : 4096 bytes
Current volume size: 4294963712 bytes (4295 MB)
You might resize at 4294516736 bytes (freeing 450560 bytes).
real 0m5.231s
user 0m2.072s
sys 0m3.014s
Computation of figures:
Clusters per volume = 4294963712 / 4096 = 1048575.125
Free clusters = (4294963712 - 4294516736) / 4096 = 109.125
Testing performance of ntfscluster, as used before this commit [1] from
GParted 0.3 in 2006:
# time ntfscluster --force /dev/sdb2 | \
> egrep 'bytes per cluster|bytes per volume|clusters per volume|clusters of free space'
...
bytes per cluster : 4096
bytes per volume : 4294963200
clusters per volume : 131071
clusters of free space : 110
real 0m4.243s
user 0m1.629s
sys 0m2.587s
Note that the clusters per volume figure reported by ntfscluster is
wrong. 4294963200 / 4096 = 1048575, not 131071.
Testing performance using ntfsinfo:
# time ntfsinfo --mft /dev/sdb2 | \
egrep 'Cluster Size|Volume Size in Clusters|Free Clusters'
Cluster Size: 4096
Volume Size in Clusters: 1048575
Free Clusters: 110 (0.0%)
real 0m0.022s
user 0m0.012s
sys 0m0.018s
Repeating the above tests while also using 'btrace /dev/sdb2' and Ctrl-C
around each test via a separate terminal, reports these numbers of I/Os
being performed:
Command Read requests Read bytes
- ntfsresize 2,695 1116 MiB
- ntfscluster 2,685 1116 MiB
- ntfsinfo 13 2208 KiB
No wonder that ntfsresize and ntfscluster take a long time, they read
just over 1 GiB of data from the 4 GiB file system, where as ntfsinfo
only reads just over 2 MiB.
Switch to using ntfsinfo to report file system usage.
[1] 9d956594d6acf0d983ae9105df2f3772194a5404
replaced ntfscluster with ntfsresize (see #350789)
Closes #47 - GParted is slow refreshing NTFS file systems
src/ntfs.cc | 76 +++++++++++++++++++++++++++----------------------------------
1 file changed, 33 insertions(+), 43 deletions(-)
---
diff --git a/src/ntfs.cc b/src/ntfs.cc
index ed54b98c..f93172c3 100644
--- a/src/ntfs.cc
+++ b/src/ntfs.cc
@@ -62,11 +62,11 @@ FS ntfs::get_filesystem_support()
fs .busy = FS::GPARTED ;
- if ( ! Glib::find_program_in_path( "ntfsresize" ) .empty() )
- {
+ if (! Glib::find_program_in_path("ntfsinfo").empty())
fs.read = FS::EXTERNAL;
+
+ if (! Glib::find_program_in_path("ntfsresize").empty())
fs.check = FS::EXTERNAL;
- }
if ( ! Glib::find_program_in_path( "ntfslabel" ) .empty() ) {
Glib::ustring version ;
@@ -93,7 +93,7 @@ FS ntfs::get_filesystem_support()
}
//resizing is a delicate process ...
- if ( fs .read && fs .check )
+ if (fs.check)
{
fs.grow = FS::EXTERNAL;
@@ -101,7 +101,6 @@ FS ntfs::get_filesystem_support()
fs.shrink = FS::EXTERNAL;
}
- //we need ntfsresize to set correct used/unused after cloning
if ( ! Glib::find_program_in_path( "ntfsclone" ) .empty() )
fs.copy = FS::EXTERNAL;
@@ -120,47 +119,38 @@ FS ntfs::get_filesystem_support()
void ntfs::set_used_sectors( Partition & partition )
{
- exit_status = Utils::execute_command( "ntfsresize --info --force --no-progress-bar " +
- Glib::shell_quote( partition.get_path() ),
- output, error, true );
- if ( exit_status == 0 || exit_status == 1 )
+ exit_status = Utils::execute_command("ntfsinfo --mft " + Glib::shell_quote(partition.get_path()),
+ output, error, true);
+ if (exit_status != 0)
{
- Glib::ustring::size_type index = output.find( "Current volume size:" );
- if ( index >= output .length() ||
- sscanf( output.substr( index ).c_str(), "Current volume size: %lld", &T ) != 1 )
- T = -1 ;
-
- index = output .find( "resize at" ) ;
- if ( index >= output .length() ||
- sscanf( output.substr( index ).c_str(), "resize at %lld", &N ) != 1 )
- N = -1 ;
- //For an absolutely full NTFS, "ntfsresize --info" exits
- // with status 1 and reports this message instead
- index = output .find( "ERROR: Volume is full" ) ;
- if ( index < output .length() )
- N = T ;
-
- index = output.find( "Cluster size" );
- if ( index >= output.length() ||
- sscanf( output.substr( index ).c_str(), "Cluster size : %lld", &S ) != 1 )
- S = -1;
-
- if ( T > -1 && N > -1 )
- {
- T = Utils::round( T / double(partition .sector_size) ) ;
- N = Utils::round( N / double(partition .sector_size) ) ;
- partition .set_sector_usage( T, T - N );
- }
- if ( S > -1 )
- partition.fs_block_size = S;
+ if (! output.empty())
+ partition.push_back_message(output);
+ if (! error.empty())
+ partition.push_back_message(output);
+ return;
}
- else
+
+ long long cluster_size = -1;
+ Glib::ustring::size_type index = output.find("Cluster Size:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "Cluster Size: %lld", &cluster_size);
+
+ long long volume_size = -1;
+ index = output.find("Volume Size in Clusters:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "Volume Size in Clusters: %lld", &volume_size);
+
+ long long free_clusters = -1;
+ index = output.find("Free Clusters:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "Free Clusters: %lld", &free_clusters);
+
+ if (cluster_size > -1 && volume_size > -1 && free_clusters > -1)
{
- if ( ! output .empty() )
- partition.push_back_message( output );
-
- if ( ! error .empty() )
- partition.push_back_message( error );
+ Sector fs_size = volume_size * cluster_size / partition.sector_size;
+ Sector fs_free = free_clusters * cluster_size / partition.sector_size;
+ partition.set_sector_usage(fs_size, fs_free);
+ partition.fs_block_size = cluster_size;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]