[gparted] Add exFAT file system usage reporting (!67)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Add exFAT file system usage reporting (!67)
- Date: Wed, 17 Feb 2021 17:36:17 +0000 (UTC)
commit 57507e21e2bd15095ce2ec50ee943689eacf8fbb
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Mon Feb 8 11:39:13 2021 +0000
Add exFAT file system usage reporting (!67)
exfatprogs 1.1.0 released 2021-02-09 [1] has gained support for
reporting file system usage [2][3] so add that capability to GParted.
It works like this:
# dump.exfat /dev/sdb1 | egrep 'Volume Length\(sectors\):|Sector Size Bits:|Sector per Cluster
bits:|Free Clusters:'
Volume Length(sectors): 524288
Sector Size Bits: 9
Sector per Cluster bits: 3
Free Clusters: 23585
Unfortunately dump.exfat returns a non-zero status on success so that
can't be used to check for failure:
# dump.exfat /dev/sdb1
exfatprogs version : 1.1.0
-------------- Dump Boot sector region --------------
Volume Length(sectors): 524288
...
# echo $?
192
dump.exfat only writes errors to stderr, so use this to identify failure:
# dump.exfat /dev/sdb1 1> /dev/null
# echo $?
192
# dump.exfat /dev/zero 1> /dev/null
invalid block device size(/dev/zero)
bogus sector size bits : 0
# echo $?
234
[1] exfatprogs-1.1.0 version released
http://github.com/exfaoprogs/exfatprogs/releases/tag/1.1.0
[2] [feature request] File system usage reporting
https://github.com/exfatprogs/exfatprogs/issues/139
[3] exfatprogs: add dump.exfat
https://github.com/exfatprogs/exfatprogs/commit/7ce9b2336b06e76521f7e041d8f0712b2d98a15b
Closes !67 - Add support for reading exFAT usage and updating the UUID
include/exfat.h | 1 +
src/exfat.cc | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)
---
diff --git a/include/exfat.h b/include/exfat.h
index aa6f1d62..ea8b7794 100644
--- a/include/exfat.h
+++ b/include/exfat.h
@@ -31,6 +31,7 @@ class exfat : public FileSystem
{
public:
FS get_filesystem_support();
+ void set_used_sectors(Partition& partition);
bool create(const Partition& new_partition, OperationDetail& operationdetail);
void read_label(Partition& partition);
bool write_label(const Partition& partition, OperationDetail& operationdetail);
diff --git a/src/exfat.cc b/src/exfat.cc
index c0eab9a2..4d82ff38 100644
--- a/src/exfat.cc
+++ b/src/exfat.cc
@@ -37,6 +37,9 @@ FS exfat::get_filesystem_support()
fs .move = FS::GPARTED ;
fs .online_read = FS::GPARTED ;
+ if (! Glib::find_program_in_path("dump.exfat").empty())
+ fs.read = FS::EXTERNAL;
+
if (! Glib::find_program_in_path("mkfs.exfat").empty())
{
Utils::execute_command("mkfs.exfat -V", output, error, true);
@@ -61,6 +64,70 @@ FS exfat::get_filesystem_support()
}
+void exfat::set_used_sectors(Partition& partition)
+{
+ Utils::execute_command("dump.exfat " + Glib::shell_quote(partition.get_path()), output, error, true);
+ // dump.exfat returns non-zero status for both success and failure. Instead use
+ // non-empty stderr to identify failure.
+ if (! error.empty())
+ {
+ if (! output.empty())
+ partition.push_back_message(output);
+ if (! error.empty())
+ partition.push_back_message(error);
+ return;
+ }
+
+ // Example output (lines of interest only):
+ // $ dump.exfat /dev/sdb1
+ // Volume Length(sectors): 524288
+ // Sector Size Bits: 9
+ // Sector per Cluster bits: 3
+ // Free Clusters: 23585
+ //
+ // "exFAT file system specification"
+ // https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
+ // Section 3.1.5 VolumeLength field
+ // Section 3.1.14 BytesPerSectorShift field
+ // Section 3.1.15 SectorsPerClusterShift field
+
+ // FS size in [FS] sectors
+ long long volume_length = -1;
+ Glib::ustring::size_type index = output.find("Volume Length(sectors):");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "Volume Length(sectors): %lld", &volume_length);
+
+ // FS sector size = 2^(bytes_per_sector_shift)
+ long long bytes_per_sector_shift = -1;
+ index = output.find("Sector Size Bits:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "Sector Size Bits: %lld", &bytes_per_sector_shift);
+
+ // Cluster size = sector_size * 2^(sectors_per_cluster_shift)
+ long long sectors_per_cluster_shift = -1;
+ index = output.find("Sector per Cluster bits:");
+ if (index < output.length())
+ sscanf(output.substr(index).c_str(), "Sector per Cluster bits: %lld",
§ors_per_cluster_shift);
+
+ // Free clusters
+ 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 ( volume_length > -1 && bytes_per_sector_shift > -1 &&
+ sectors_per_cluster_shift > -1 && free_clusters > -1 )
+ {
+ Byte_Value sector_size = 1 << bytes_per_sector_shift;
+ Byte_Value cluster_size = sector_size * (1 << sectors_per_cluster_shift);
+ Sector fs_free = free_clusters * cluster_size / partition.sector_size;
+ Sector fs_size = volume_length * sector_size / partition.sector_size;
+ partition.set_sector_usage(fs_size, fs_free);
+ partition.fs_block_size = cluster_size;
+ }
+}
+
+
bool exfat::create(const Partition& new_partition, OperationDetail& operationdetail)
{
return ! execute_command("mkfs.exfat -L " + Glib::shell_quote(new_partition.get_filesystem_label()) +
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]