Repository: archlinux/archinstall

Issue:
Format EXT4 with case-insensitivity attribute
An EXT4 partition formatted with the casefold attribute allows users to make chosen directories case-insensitive.
This can be useful for software that was made with case-insensitive filesystems in mind. For instance, Civilization 6, a native Linux game, suffers from an issue where some mods break due to referring to certain game files in PascalCase, while on Linux those files have lowercase names.
Additionally, this can speed up applications running through Wine, as native support for case-insensitivity is supposedly faster than whatever conversion Wine is doing on its own.
Seeing how a filesystem with this flag functions no differently from a filesystem without this flag if you don't actually make use of the feature, I see no harm in formatting partitions with the casefold attribute by default.
See https://www.collabora.com/news-and-blog/blog/2020/08/27/using-the-linux-kernel-case-insensitive-feature-in-ext4/ for more information



Discussion:
This sounds like something you can already do and use the /mnt as-is while prompted by the installer. I don't know if it makes enough sense to have a whole choice for case insensitive during partition creation if you use the built-in formatter.
I think the guided installer should follow the Installation Guide, which in it's simplest form [doesn't specify anything but default flags](https://wiki.archlinux.org/index.php/Installation_guide#Format_the_partitions). I agree that allowing more flexible configurations and mount-options is desireable. But as dylan mentions, this is hopefully already supported in one of two ways:
 * Use `/mnt` as is, and format your layout with options as you choose and mount them to `/mnt` and archinstall will autodetect and use the setup you've chosen
 * Create your own .dotfile-like installation script and create the [file system via the API](https://github.com/archlinux/archinstall/blob/master/archinstall/lib/disk.py#L299). However, this does need to allow for custom flags in that case, which is something we could easily add through `**kwargs` to the function across all functions some how :)
It's nice to know you can set up a casefold ext4 FS manually and still take advantage of archinstall, but I feel like this functionality is the sort of stuff you discover after you've already installed and set up your Arch Linux installation, so if you decide to try it out, you're going to need to reformat everything, which can be quite troublesome.
Seeing how the attribute doesn't change ext4 behavior if you don't actually make use of case-insensitivity flag, I think it would be nice to use it by default, without a choice. At worst, you get an FS with a feature you never make use of, and in the best case, it saves the user a lot of time and effort. And AFAIK development releases of SteamOS do just that.
> It's nice to know you can set up a casefold ext4 FS manually and still take advantage of archinstall, but I feel like this functionality is the sort of stuff you discover after you've already installed and set up your Arch Linux installation, so if you decide to try it out, you're going to need to reformat everything, which can be quite troublesome.
> Seeing how the attribute doesn't change ext4 behavior if you don't actually make use of case-insensitivity flag, I think it would be nice to use it by default, without a choice. At worst, you get an FS with a feature you never make use of, and in the best case, it saves the user a lot of time and effort. And AFAIK development releases of SteamOS do just that.

I disagree with this because case sensitivity has been the default on Unix like systems for a very long time. Switching it may cause weird issues and incompatibility with other systems. Arch recommends it as the default, and we generally do not want to deviate from the defaults.
But with the flag, case sensitivity is still the default. The attribute only allows setting a special flag for a directory to make it and only it case-insensitive. So if you never actually go out of your way and make a directory case-insensitive, ext4 will function the same as without the attribute.
> But with the flag, case sensitivity is still the default. The attribute only allows setting a special flag for a directory to make it and only it case-insensitive. So if you never actually go out of your way and make a directory case-insensitive, ext4 will function the same as without the attribute.

That is better actually, but we are implementing the installer not sending policy for Arch Linux, and the installations that are resultant from running the installer should respect the same defaults that the Arch project decides on. If we deviate from a default we should have a really good reason to do so, and this does enable a feature for an entire file system. It may have impacts with performance or stability, and due to it being a newer feature it may also not be bug-free. 

Resolving patch:
diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py
--- a/archinstall/lib/disk/filesystem.py
+++ b/archinstall/lib/disk/filesystem.py
@@ -117,9 +117,9 @@ def load_layout(self, layout :dict):
 											continue
 										break
 
-						unlocked_device.format(partition['filesystem']['format'])
+						unlocked_device.format(partition['filesystem']['format'], options=partition.get('options', []))
 				elif partition.get('format', False):
-					partition['device_instance'].format(partition['filesystem']['format'])
+					partition['device_instance'].format(partition['filesystem']['format'], options=partition.get('options', []))
 
 			if partition.get('boot', False):
 				self.set(self.partuuid_to_index(partition['device_instance'].uuid), 'boot on')
diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py
--- a/archinstall/lib/disk/partition.py
+++ b/archinstall/lib/disk/partition.py
@@ -208,7 +208,7 @@ def encrypt(self, *args, **kwargs):
 		handle = luks2(self, None, None)
 		return handle.encrypt(self, *args, **kwargs)
 
-	def format(self, filesystem=None, path=None, log_formatting=True):
+	def format(self, filesystem=None, path=None, log_formatting=True, options=[]):
 		"""
 		Format can be given an overriding path, for instance /dev/null to test
 		the formatting functionality and in essence the support for the given filesystem.
@@ -228,33 +228,45 @@ def format(self, filesystem=None, path=None, log_formatting=True):
 			log(f'Formatting {path} -> {filesystem}', level=logging.INFO)
 
 		if filesystem == 'btrfs':
-			if 'UUID:' not in (mkfs := SysCommand(f'/usr/bin/mkfs.btrfs -f {path}').decode('UTF-8')):
+			options = ['-f'] + options
+
+			if 'UUID:' not in (mkfs := SysCommand(f"/usr/bin/mkfs.btrfs {' '.join(options)} {path}").decode('UTF-8')):
 				raise DiskError(f'Could not format {path} with {filesystem} because: {mkfs}')
 			self.filesystem = filesystem
 
 		elif filesystem == 'fat32':
-			mkfs = SysCommand(f'/usr/bin/mkfs.vfat -F32 {path}').decode('UTF-8')
+			options = ['-F32'] + options
+
+			mkfs = SysCommand(f"/usr/bin/mkfs.vfat {' '.join(options)} {path}").decode('UTF-8')
 			if ('mkfs.fat' not in mkfs and 'mkfs.vfat' not in mkfs) or 'command not found' in mkfs:
 				raise DiskError(f"Could not format {path} with {filesystem} because: {mkfs}")
 			self.filesystem = filesystem
 
 		elif filesystem == 'ext4':
-			if (handle := SysCommand(f'/usr/bin/mkfs.ext4 -F {path}')).exit_code != 0:
+			options = ['-F'] + options
+
+			if (handle := SysCommand(f"/usr/bin/mkfs.ext4 {' '.join(options)} {path}")).exit_code != 0:
 				raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}")
 			self.filesystem = filesystem
 
 		elif filesystem == 'ext2':
-			if (handle := SysCommand(f'/usr/bin/mkfs.ext2 -F {path}')).exit_code != 0:
+			options = ['-F'] + options
+
+			if (handle := SysCommand(f"/usr/bin/mkfs.ext2 {' '.join(options)} {path}")).exit_code != 0:
 				raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
 			self.filesystem = 'ext2'
 
 		elif filesystem == 'xfs':
-			if (handle := SysCommand(f'/usr/bin/mkfs.xfs -f {path}')).exit_code != 0:
+			options = ['-f'] + options
+
+			if (handle := SysCommand(f"/usr/bin/mkfs.xfs {' '.join(options)} {path}")).exit_code != 0:
 				raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}")
 			self.filesystem = filesystem
 
 		elif filesystem == 'f2fs':
-			if (handle := SysCommand(f'/usr/bin/mkfs.f2fs -f {path}')).exit_code != 0:
+			options = ['-f'] + options
+			
+			if (handle := SysCommand(f"/usr/bin/mkfs.f2fs {' '.join(options)} {path}")).exit_code != 0:
 				raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}")
 			self.filesystem = filesystem
 


Test patch: