diff --git a/src/plugins/fs/exfat.c b/src/plugins/fs/exfat.c index bf9140d0e..3557bff2f 100644 --- a/src/plugins/fs/exfat.c +++ b/src/plugins/fs/exfat.c @@ -147,6 +147,8 @@ G_GNUC_INTERNAL BDExtraArg ** bd_fs_exfat_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra) { GPtrArray *options_array = g_ptr_array_new (); const BDExtraArg **extra_p = NULL; + UtilDep dep = {"mkfs.exfat", "1.4.0", "--version", "exfatprogs version[:\\s]+([\\d\\.]+).+"}; + gboolean new_exfat = FALSE; if (options->label && g_strcmp0 (options->label, "") != 0) g_ptr_array_add (options_array, bd_extra_arg_new ("-n", options->label)); @@ -156,6 +158,15 @@ bd_fs_exfat_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra) { g_ptr_array_add (options_array, bd_extra_arg_copy ((BDExtraArg *) *extra_p)); } + if (options->no_pt) { + /* only exfatprogs >= 1.4.0 (sometimes) creates the partition table */ + new_exfat = bd_utils_check_util_version (dep.name, dep.version, + dep.ver_arg, dep.ver_regexp, + NULL); + if (new_exfat) + g_ptr_array_add (options_array, bd_extra_arg_new ("-P", "none")); + } + g_ptr_array_add (options_array, NULL); return (BDExtraArg **) g_ptr_array_free (options_array, FALSE); diff --git a/src/plugins/fs/generic.c b/src/plugins/fs/generic.c index 104cae419..abec657a3 100644 --- a/src/plugins/fs/generic.c +++ b/src/plugins/fs/generic.c @@ -146,10 +146,10 @@ static const BDFSFeatures fs_features[BD_FS_LAST_FS] = { .max_size = 16 TiB }, /* EXFAT */ { .resize = 0, - .mkfs = BD_FS_MKFS_LABEL, + .mkfs = BD_FS_MKFS_LABEL | BD_FS_MKFS_NOPT, .fsck = BD_FS_FSCK_CHECK | BD_FS_FSCK_REPAIR, .configure = BD_FS_SUPPORT_SET_LABEL | BD_FS_SUPPORT_SET_UUID, - .features = 0, + .features = BD_FS_FEATURE_PARTITION_TABLE, .partition_id = "0x07", .partition_type = "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7", .min_size = 3 MiB, diff --git a/tests/fs_tests/exfat_test.py b/tests/fs_tests/exfat_test.py index 48a9db481..74e174fb2 100644 --- a/tests/fs_tests/exfat_test.py +++ b/tests/fs_tests/exfat_test.py @@ -1,5 +1,9 @@ +import os +import re import tempfile +from packaging.version import Version + from .fs_test import FSTestCase, FSNoDevTestCase, mounted import overrides_hack @@ -8,6 +12,18 @@ from gi.repository import BlockDev, GLib +def _get_exfatprogs_version(): + _ret, out, _err = utils.run_command("mkfs.exfat --version") + # exfatprogs version : 1.4.1 (2026-05-28) + m = re.search(r"exfatprogs version : ([\d\.]+)", out) + if not m or len(m.groups()) != 1: + raise RuntimeError("Failed to determine exfatprogs version from: %s" % out) + return Version(m.groups()[0]) + + +EXFATPROGS_VERSION = _get_exfatprogs_version() + + class ExfatNoDevTestCase(FSNoDevTestCase): def setUp(self): super(ExfatNoDevTestCase, self).setUp() @@ -25,6 +41,11 @@ def setUp(self): self.mount_dir = tempfile.mkdtemp(prefix="libblockdev.", suffix="exfat_test") + if EXFATPROGS_VERSION < Version("1.4.0"): + self._mkfs_options = None + else: + self._mkfs_options = [BlockDev.ExtraArg.new("-P", "none")] + class ExfatTestAvailability(ExfatNoDevTestCase): @@ -80,7 +101,7 @@ def test_exfat_features(self): self.assertFalse(features.mkfs & BlockDev.FSMkfsOptionsFlags.UUID) self.assertFalse(features.mkfs & BlockDev.FSMkfsOptionsFlags.DRY_RUN) self.assertFalse(features.mkfs & BlockDev.FSMkfsOptionsFlags.NODISCARD) - self.assertFalse(features.mkfs & BlockDev.FSMkfsOptionsFlags.NOPT) + self.assertTrue(features.mkfs & BlockDev.FSMkfsOptionsFlags.NOPT) self.assertTrue(features.fsck & BlockDev.FSFsckFlags.CHECK) self.assertTrue(features.fsck & BlockDev.FSFsckFlags.REPAIR) @@ -88,7 +109,7 @@ def test_exfat_features(self): self.assertTrue(features.configure & BlockDev.FSConfigureFlags.LABEL) self.assertTrue(features.configure & BlockDev.FSConfigureFlags.UUID) - self.assertEqual(features.features, 0) + self.assertEqual(features.features, BlockDev.FSFeatureFlags.PARTITION_TABLE) self.assertEqual(features.partition_id, "0x07") self.assertEqual(features.partition_type, "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7") @@ -132,7 +153,7 @@ class ExfatTestCheck(ExfatTestCase): def test_exfat_check(self): """Verify that it is possible to check an exfat file system""" - succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0]) + succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], self._mkfs_options) self.assertTrue(succ) succ = BlockDev.fs_exfat_check(self.loop_devs[0]) @@ -143,7 +164,7 @@ class ExfatTestRepair(ExfatTestCase): def test_exfat_repair(self): """Verify that it is possible to repair an exfat file system""" - succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0]) + succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], self._mkfs_options) self.assertTrue(succ) succ = BlockDev.fs_exfat_repair(self.loop_devs[0]) @@ -154,7 +175,7 @@ class ExfatGetInfo(ExfatTestCase): def test_exfat_get_info(self): """Verify that it is possible to get info about an exfat file system""" - succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], None) + succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], self._mkfs_options) self.assertTrue(succ) fi = BlockDev.fs_exfat_get_info(self.loop_devs[0]) @@ -171,7 +192,7 @@ class ExfatSetLabel(ExfatTestCase): def test_exfat_set_label(self): """Verify that it is possible to set label of an exfat file system""" - succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], None) + succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], self._mkfs_options) self.assertTrue(succ) fi = BlockDev.fs_exfat_get_info(self.loop_devs[0]) @@ -207,7 +228,7 @@ class ExfatSetUUID(ExfatTestCase): def test_exfat_set_uuid(self): """Verify that it is possible to set UUID/volume ID of an exfat file system""" - succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0]) + succ = BlockDev.fs_exfat_mkfs(self.loop_devs[0], self._mkfs_options) self.assertTrue(succ) succ = BlockDev.fs_exfat_set_uuid(self.loop_devs[0], "0x2E24EC82")