From 388e44c8095c04eac53ca6500363ebfb0d8f14bb Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 5 Aug 2020 02:05:18 +0200 Subject: Linux: Add support for Btrfs filesystem when creating volumes --- src/Core/VolumeCreator.h | 55 ++++++++++++++++++++++++ src/Main/CommandLineInterface.cpp | 4 ++ src/Main/Forms/VolumeCreationWizard.cpp | 23 ++-------- src/Main/Forms/VolumeFormatOptionsWizardPage.cpp | 17 ++++++-- src/Main/TextUserInterface.cpp | 32 ++++++-------- 5 files changed, 90 insertions(+), 41 deletions(-) diff --git a/src/Core/VolumeCreator.h b/src/Core/VolumeCreator.h index 6b8f1436..22956451 100644 --- a/src/Core/VolumeCreator.h +++ b/src/Core/VolumeCreator.h @@ -16,6 +16,11 @@ #include "Platform/Platform.h" #include "Volume/Volume.h" #include "RandomNumberGenerator.h" +#if defined (TC_LINUX) +#include "Platform/Unix/Process.h" +#endif + +#define VC_MIN_BTRFS_VOLUME_SIZE 114294784ULL namespace VeraCrypt { @@ -44,6 +49,7 @@ namespace VeraCrypt Ext2, Ext3, Ext4, + Btrfs, MacOsExt, APFS, UFS @@ -63,6 +69,55 @@ namespace VeraCrypt return VolumeCreationOptions::FilesystemType::FAT; #endif } + + static const char* GetFsFormatter (VolumeCreationOptions::FilesystemType::Enum fsType) + { + switch (fsType) + { + #if defined (TC_LINUX) + case VolumeCreationOptions::FilesystemType::Ext2: return "mkfs.ext2"; + case VolumeCreationOptions::FilesystemType::Ext3: return "mkfs.ext3"; + case VolumeCreationOptions::FilesystemType::Ext4: return "mkfs.ext4"; + case VolumeCreationOptions::FilesystemType::NTFS: return "mkfs.ntfs"; + case VolumeCreationOptions::FilesystemType::exFAT: return "mkfs.exfat"; + case VolumeCreationOptions::FilesystemType::Btrfs: return "mkfs.btrfs"; + #elif defined (TC_MACOSX) + case VolumeCreationOptions::FilesystemType::MacOsExt: return "newfs_hfs"; + case VolumeCreationOptions::FilesystemType::exFAT: return "newfs_exfat"; + case VolumeCreationOptions::FilesystemType::APFS: return "newfs_apfs"; + #elif defined (TC_FREEBSD) || defined (TC_SOLARIS) + case VolumeCreationOptions::FilesystemType::UFS: return "newfs" ; + #endif + default: return NULL; + } + } + + static bool IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::Enum fsType) + { + bool bRet = false; + const char* fsFormatter = GetFsFormatter (fsType); + if (fsFormatter) + { +#if defined (TC_LINUX) + try + { + list args; + + args.push_back ("-V"); + Process::Execute (fsFormatter, args); + + bRet = true; + } + catch (exception &e) + { + } +#else + bRet = true; +#endif + } + + return bRet; + } }; FilesystemType::Enum Filesystem; diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp index dd284734..0ae246c6 100644 --- a/src/Main/CommandLineInterface.cpp +++ b/src/Main/CommandLineInterface.cpp @@ -318,6 +318,8 @@ namespace VeraCrypt ArgFilesystem = VolumeCreationOptions::FilesystemType::NTFS; else if (str.IsSameAs (L"exFAT", false)) ArgFilesystem = VolumeCreationOptions::FilesystemType::exFAT; + else if (str.IsSameAs (L"Btrfs", false)) + ArgFilesystem = VolumeCreationOptions::FilesystemType::Btrfs; #elif defined (TC_MACOSX) else if ( str.IsSameAs (L"HFS", false) || str.IsSameAs (L"HFS+", false) @@ -328,6 +330,8 @@ namespace VeraCrypt } else if (str.IsSameAs (L"exFAT", false)) ArgFilesystem = VolumeCreationOptions::FilesystemType::exFAT; + else if (str.IsSameAs (L"Btrfs", false)) + ArgFilesystem = VolumeCreationOptions::FilesystemType::Btrfs; else if (str.IsSameAs (L"APFS", false)) ArgFilesystem = VolumeCreationOptions::FilesystemType::APFS; #elif defined (TC_FREEBSD) || defined (TC_SOLARIS) diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index 37af6361..4df20301 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -466,25 +466,7 @@ namespace VeraCrypt #ifdef TC_UNIX // Format non-FAT filesystem - const char *fsFormatter = nullptr; - - switch (SelectedFilesystemType) - { -#if defined (TC_LINUX) - case VolumeCreationOptions::FilesystemType::Ext2: fsFormatter = "mkfs.ext2"; break; - case VolumeCreationOptions::FilesystemType::Ext3: fsFormatter = "mkfs.ext3"; break; - case VolumeCreationOptions::FilesystemType::Ext4: fsFormatter = "mkfs.ext4"; break; - case VolumeCreationOptions::FilesystemType::NTFS: fsFormatter = "mkfs.ntfs"; break; - case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "mkfs.exfat"; break; -#elif defined (TC_MACOSX) - case VolumeCreationOptions::FilesystemType::MacOsExt: fsFormatter = "newfs_hfs"; break; - case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "newfs_exfat"; break; - case VolumeCreationOptions::FilesystemType::APFS: fsFormatter = "newfs_apfs"; break; -#elif defined (TC_FREEBSD) || defined (TC_SOLARIS) - case VolumeCreationOptions::FilesystemType::UFS: fsFormatter = "newfs" ; break; -#endif - default: break; - } + const char *fsFormatter = VolumeCreationOptions::FilesystemType::GetFsFormatter (SelectedFilesystemType); if (fsFormatter) { @@ -544,6 +526,9 @@ namespace VeraCrypt if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::NTFS) args.push_back ("-f"); + if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::Btrfs) + args.push_back ("-f"); + args.push_back (string (virtualDevice)); Process::Execute (fsFormatter, args); diff --git a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp index 38657059..30f8c6ba 100644 --- a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp +++ b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp @@ -35,9 +35,19 @@ namespace VeraCrypt #elif defined (TC_LINUX) FilesystemTypeChoice->Append (L"Linux Ext2", (void *) VolumeCreationOptions::FilesystemType::Ext2); FilesystemTypeChoice->Append (L"Linux Ext3", (void *) VolumeCreationOptions::FilesystemType::Ext3); - FilesystemTypeChoice->Append (L"Linux Ext4", (void *) VolumeCreationOptions::FilesystemType::Ext4); - FilesystemTypeChoice->Append (L"NTFS", (void *) VolumeCreationOptions::FilesystemType::NTFS); - FilesystemTypeChoice->Append (L"exFAT", (void *) VolumeCreationOptions::FilesystemType::exFAT); + if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::Ext4)) + FilesystemTypeChoice->Append (L"Linux Ext4", (void *) VolumeCreationOptions::FilesystemType::Ext4); + if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::NTFS)) + FilesystemTypeChoice->Append (L"NTFS", (void *) VolumeCreationOptions::FilesystemType::NTFS); + if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::exFAT)) + FilesystemTypeChoice->Append (L"exFAT", (void *) VolumeCreationOptions::FilesystemType::exFAT); + if (VolumeCreationOptions::FilesystemType::IsFsFormatterPresent (VolumeCreationOptions::FilesystemType::Btrfs)) + { + uint64 minVolumeSizeForBtrfs = VC_MIN_BTRFS_VOLUME_SIZE + (uint64) (VC_MAX (TC_TOTAL_VOLUME_HEADERS_SIZE, TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH)); + // minimum size to be able to format as Btrfs is 114294784 bytes + if (volumeSize >= minVolumeSizeForBtrfs) + FilesystemTypeChoice->Append (L"Btrfs", (void *) VolumeCreationOptions::FilesystemType::Btrfs); + } #elif defined (TC_MACOSX) FilesystemTypeChoice->Append (L"Mac OS Extended", (void *) VolumeCreationOptions::FilesystemType::MacOsExt); FilesystemTypeChoice->Append (L"exFAT", (void *) VolumeCreationOptions::FilesystemType::exFAT); @@ -83,6 +93,7 @@ namespace VeraCrypt case VolumeCreationOptions::FilesystemType::Ext2: FilesystemTypeChoice->SetStringSelection (L"Linux Ext2"); break; case VolumeCreationOptions::FilesystemType::Ext3: FilesystemTypeChoice->SetStringSelection (L"Linux Ext3"); break; case VolumeCreationOptions::FilesystemType::Ext4: FilesystemTypeChoice->SetStringSelection (L"Linux Ext4"); break; + case VolumeCreationOptions::FilesystemType::Btrfs: FilesystemTypeChoice->SetStringSelection (L"Btrfs"); break; case VolumeCreationOptions::FilesystemType::MacOsExt: FilesystemTypeChoice->SetStringSelection (L"Mac OS Extended"); break; case VolumeCreationOptions::FilesystemType::APFS: FilesystemTypeChoice->SetStringSelection (L"APFS"); break; case VolumeCreationOptions::FilesystemType::UFS: FilesystemTypeChoice->SetStringSelection (L"UFS"); break; diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index e946d6fc..95becfdf 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -785,6 +785,7 @@ namespace VeraCrypt ShowInfo (L" 5) Linux Ext4"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Ext4); ShowInfo (L" 6) NTFS"); filesystems.push_back (VolumeCreationOptions::FilesystemType::NTFS); ShowInfo (L" 7) exFAT"); filesystems.push_back (VolumeCreationOptions::FilesystemType::exFAT); + ShowInfo (L" 8) Btrfs"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Btrfs); #elif defined (TC_MACOSX) ShowInfo (L" 3) Mac OS Extended"); filesystems.push_back (VolumeCreationOptions::FilesystemType::MacOsExt); ShowInfo (L" 4) exFAT"); filesystems.push_back (VolumeCreationOptions::FilesystemType::exFAT); @@ -808,6 +809,12 @@ namespace VeraCrypt throw_err (_("Specified volume size cannot be used with FAT filesystem.")); } + if (options->Filesystem == VolumeCreationOptions::FilesystemType::Btrfs + && (filesystemSize < VC_MIN_BTRFS_VOLUME_SIZE)) + { + throw_err (_("Specified volume size is too small to be used with Btrfs filesystem.")); + } + // Password if (!options->Password && !Preferences.NonInteractive) { @@ -875,25 +882,9 @@ namespace VeraCrypt if (options->Filesystem != VolumeCreationOptions::FilesystemType::None && options->Filesystem != VolumeCreationOptions::FilesystemType::FAT) { - const char *fsFormatter = nullptr; - - switch (options->Filesystem) - { -#if defined (TC_LINUX) - case VolumeCreationOptions::FilesystemType::Ext2: fsFormatter = "mkfs.ext2"; break; - case VolumeCreationOptions::FilesystemType::Ext3: fsFormatter = "mkfs.ext3"; break; - case VolumeCreationOptions::FilesystemType::Ext4: fsFormatter = "mkfs.ext4"; break; - case VolumeCreationOptions::FilesystemType::NTFS: fsFormatter = "mkfs.ntfs"; break; - case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "mkfs.exfat"; break; -#elif defined (TC_MACOSX) - case VolumeCreationOptions::FilesystemType::MacOsExt: fsFormatter = "newfs_hfs"; break; - case VolumeCreationOptions::FilesystemType::exFAT: fsFormatter = "newfs_exfat"; break; - case VolumeCreationOptions::FilesystemType::APFS: fsFormatter = "newfs_apfs"; break; -#elif defined (TC_FREEBSD) || defined (TC_SOLARIS) - case VolumeCreationOptions::FilesystemType::UFS: fsFormatter = "newfs" ; break; -#endif - default: throw ParameterIncorrect (SRC_POS); - } + const char *fsFormatter = VolumeCreationOptions::FilesystemType::GetFsFormatter (options->Filesystem); + if (!fsFormatter) + throw ParameterIncorrect (SRC_POS); MountOptions mountOptions (GetPreferences().DefaultMountOptions); mountOptions.Path = make_shared (options->Path); @@ -947,6 +938,9 @@ namespace VeraCrypt if (options->Filesystem == VolumeCreationOptions::FilesystemType::NTFS) args.push_back ("-f"); + if (options->Filesystem == VolumeCreationOptions::FilesystemType::Btrfs) + args.push_back ("-f"); + args.push_back (string (virtualDevice)); Process::Execute (fsFormatter, args); -- cgit v1.2.3