diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py index eea4efc91..353a9ef38 100644 --- a/blivet/formats/fs.py +++ b/blivet/formats/fs.py @@ -1012,10 +1012,14 @@ class FATFS(FS): _uuidfs = fsuuid.FATFSUUID() _supported = True _formattable = True + _resizable = True + _resize_support = FSResize.OFFLINE_GROW | FSResize.OFFLINE_SHRINK _max_size = Size("1 TiB") _packages = ["dosfstools"] _fsck_class = fsck.DosFSCK _info_class = fsinfo.FATFSInfo + _minsize_class = fsminsize.FATFSMinSize + _resize_class = fsresize.FATFSResize _size_info_class = fssize.FATFSSize _mkfs_class = fsmkfs.FATFSMkfs _mount_class = fsmount.FATFSMount diff --git a/blivet/tasks/availability.py b/blivet/tasks/availability.py index bde29c727..d5f3aa850 100644 --- a/blivet/tasks/availability.py +++ b/blivet/tasks/availability.py @@ -553,6 +553,7 @@ class FSOperation(): BLOCKDEV_EXT_RESIZE = blockdev_fs_plugin_operation(BlockDevFSMethod(FSOperation.RESIZE, blockdev.fs.can_resize, "ext2")) BLOCKDEV_XFS_RESIZE = blockdev_fs_plugin_operation(BlockDevFSMethod(FSOperation.RESIZE, blockdev.fs.can_resize, "xfs")) BLOCKDEV_NTFS_RESIZE = blockdev_fs_plugin_operation(BlockDevFSMethod(FSOperation.RESIZE, blockdev.fs.can_resize, "ntfs")) +BLOCKDEV_VFAT_RESIZE = blockdev_fs_plugin_operation(BlockDevFSMethod(FSOperation.RESIZE, blockdev.fs.can_resize, "vfat")) BLOCKDEV_EXT_INFO = blockdev_fs_plugin_operation(BlockDevFSMethod(FSOperation.INFO, blockdev.fs.can_get_size, "ext2")) BLOCKDEV_XFS_INFO = blockdev_fs_plugin_operation(BlockDevFSMethod(FSOperation.INFO, blockdev.fs.can_get_size, "xfs")) diff --git a/blivet/tasks/fsminsize.py b/blivet/tasks/fsminsize.py index 74e02ef84..dd8248f6a 100644 --- a/blivet/tasks/fsminsize.py +++ b/blivet/tasks/fsminsize.py @@ -80,5 +80,23 @@ def do_task(self): # pylint: disable=arguments-differ return min_size +class FATFSMinSize(FSMinSize): + ext = availability.BLOCKDEV_VFAT_INFO + + def do_task(self): # pylint: disable=arguments-differ + error_msgs = self.availability_errors + if error_msgs: + raise FSError("\n".join(error_msgs)) + + try: + info = BlockDev.fs.vfat_get_info(self.fs.device) + except BlockDev.FSError as e: + raise FSError("failed to get fs min size: %s" % e) + min_size = Size((info.free_cluster_count - info.free_cluster_count) * info.cluster_size) + # resizing below 32 MiB would require changing from VFAT/FAT32 to FAT16 which is not + # currently supported by libparted which libblockdev uses for FAT resize + return max(min_size, Size("32 MiB")) + + class UnimplementedFSMinSize(fstask.UnimplementedFSTask): pass diff --git a/blivet/tasks/fsresize.py b/blivet/tasks/fsresize.py index e420fe966..ca6ef5a35 100644 --- a/blivet/tasks/fsresize.py +++ b/blivet/tasks/fsresize.py @@ -47,6 +47,10 @@ class FSResize(task.BasicApplication, FSResizeTask): # IMPLEMENTATION methods + @property + def fs_type(self): + return self.fs.type + def do_task(self): # pylint: disable=arguments-differ """ Resize the device. @@ -57,7 +61,7 @@ def do_task(self): # pylint: disable=arguments-differ raise FSError("\n".join(error_msgs)) try: - BlockDev.fs.resize(self.fs.device, self.fs.target_size.convert_to(B), self.fs.type) + BlockDev.fs.resize(self.fs.device, self.fs.target_size.convert_to(B), self.fs_type) except BlockDev.FSError as e: raise FSError(str(e)) @@ -77,6 +81,16 @@ class XFSResize(FSResize): unit = B +class FATFSResize(FSResize): + ext = availability.BLOCKDEV_VFAT_RESIZE + unit = B + + @property + def fs_type(self): + # we don't want 'efi' to be used for EFIFS + return "vfat" + + class TmpFSResize(FSResize): ext = availability.BLOCKDEV_FS_PLUGIN unit = MiB diff --git a/tests/storage_tests/formats_test/fstesting.py b/tests/storage_tests/formats_test/fstesting.py index 16d6dba45..ee158bbae 100644 --- a/tests/storage_tests/formats_test/fstesting.py +++ b/tests/storage_tests/formats_test/fstesting.py @@ -278,7 +278,7 @@ def test_shrink(self): an_fs.target_size = TARGET_SIZE self.assertIsNone(an_fs.do_resize()) - TARGET_SIZE = TARGET_SIZE / 2 + TARGET_SIZE = TARGET_SIZE - Size("10 MiB") self.assertTrue(TARGET_SIZE > an_fs.min_size) an_fs.target_size = TARGET_SIZE self.assertEqual(an_fs.target_size, TARGET_SIZE)