From 9edd7492db84a5f3b8cf5d71fee98cf51882043f Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Tue, 11 Feb 2020 19:22:22 +0000 Subject: [PATCH] [ext2fs] improve formatting speed * Fix use of EXT2_BLOCK_SIZE() instead of EXT2_INODE_SIZE() during inode initialization, that made us zero way many more blocks than was needed. * Also disable sparse_super feature and improve block setup. * Also explicitly use IS_POWER_OF_2 macro where required. --- src/format.c | 3 +-- src/format_ext.c | 25 +++++++++++++++---------- src/rufus.h | 3 +-- src/rufus.rc | 10 +++++----- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/format.c b/src/format.c index 78ce2577..07e042b5 100644 --- a/src/format.c +++ b/src/format.c @@ -641,8 +641,7 @@ out: static BOOL FormatPartition(DWORD DriveIndex, uint64_t PartitionOffset, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags) { if ((DriveIndex < 0x80) || (DriveIndex > 0x100) || (FSType >= FS_MAX) || - // The following validates that UnitAllocationSize is a power of 2 - ((UnitAllocationSize != 0) && (UnitAllocationSize & (UnitAllocationSize - 1)))) { + ((UnitAllocationSize != 0) && (!IS_POWER_OF_2(UnitAllocationSize)))) { ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_INVALID_PARAMETER; return FALSE; } diff --git a/src/format_ext.c b/src/format_ext.c index 4085f89c..37718de6 100644 --- a/src/format_ext.c +++ b/src/format_ext.c @@ -218,15 +218,18 @@ const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset) return (r == 0) ? label : NULL; } +#define TEST_IMG_PATH "\\??\\C:\\tmp\\disk.img" +#define TEST_IMG_SIZE 4000 // Size in MB + BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) { // Mostly taken from mke2fs.conf const float reserve_ratio = 0.05f; const ext2fs_default_t ext2fs_default[5] = { - { 3 * MB, 1024, 128, 3}, // "floppy" + { 3 * MB, 1024, 128, 3}, // "floppy" { 512 * MB, 1024, 128, 2}, // "small" - { 4 * GB, 4096, 256, 2}, // "default" - { 16 * GB, 4096, 256, 3}, // "big" + { 4 * GB, 4096, 256, 2}, // "default" + { 16 * GB, 4096, 256, 3}, // "big" { 1024 * TB, 4096, 256, 4} // "huge" }; @@ -298,15 +301,16 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP break; } assert(i < ARRAYSIZE(ext2fs_default)); - // NB: We validated that BlockSize is a power of two in FormatPartition() - if (BlockSize == 0) + if ((BlockSize == 0) || (BlockSize < EXT2_MIN_BLOCK_SIZE)) BlockSize = ext2fs_default[i].block_size; - size /= BlockSize; + assert(IS_POWER_OF_2(BlockSize)); for (features.s_log_block_size = 0; EXT2_BLOCK_SIZE_BITS(&features) <= EXT2_MAX_BLOCK_LOG_SIZE; features.s_log_block_size++) { if (EXT2_BLOCK_SIZE(&features) == BlockSize) break; } assert(EXT2_BLOCK_SIZE_BITS(&features) <= EXT2_MAX_BLOCK_LOG_SIZE); + features.s_log_cluster_size = features.s_log_block_size; + size /= BlockSize; // Set the blocks, reserved blocks and inodes ext2fs_blocks_count_set(&features, size); @@ -320,10 +324,10 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP // Set features ext2fs_set_feature_xattr(&features); - // ext2fs_set_feature_resize_inode(&features); +// ext2fs_set_feature_resize_inode(&features); ext2fs_set_feature_dir_index(&features); ext2fs_set_feature_filetype(&features); - ext2fs_set_feature_sparse_super(&features); +// ext2fs_set_feature_sparse_super(&features); ext2fs_set_feature_large_file(&features); if (FSName[3] != '2') ext2fs_set_feature_journal(&features); @@ -372,6 +376,8 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP goto out; } + // TODO: mke2fs appears to be zeroing some data at the end of the partition as well + ext2_percent_start = 0.0f; ext2_percent_share = (FSName[3] == '2') ? 1.0f : 0.5f; uprintf("Creating %d inode sets: [1 marker = %0.1f set(s)]", ext2fs->group_desc_count, @@ -381,7 +387,7 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP goto out; cur = ext2fs_inode_table_loc(ext2fs, i); count = ext2fs_div_ceil((ext2fs->super->s_inodes_per_group - ext2fs_bg_itable_unused(ext2fs, i)) - * EXT2_BLOCK_SIZE(ext2fs->super), EXT2_BLOCK_SIZE(ext2fs->super)); + * EXT2_INODE_SIZE(ext2fs->super), EXT2_BLOCK_SIZE(ext2fs->super)); r = ext2fs_zero_blocks2(ext2fs, cur, count, &cur, &count); if (r != 0) { FormatStatus = ext2_last_winerror(ERROR_WRITE_FAULT); @@ -488,4 +494,3 @@ out: free(buf); return ret; } - diff --git a/src/rufus.h b/src/rufus.h index 5571c423..722adc72 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -111,6 +111,7 @@ #define WPPRECORDER_MORE_INFO_URL "https://github.com/pbatard/rufus/wiki/FAQ#BSODs_with_Windows_To_Go_drives_created_from_Windows_10_1809_ISOs" #define SEVENZIP_URL "https://www.7-zip.org" #define FILES_DIR "rufus_files" +#define IS_POWER_OF_2(x) ((x != 0) && (((x) & ((x) - 1)) == 0)) #define IGNORE_RETVAL(expr) do { (void)(expr); } while(0) #ifndef ARRAYSIZE #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) @@ -124,8 +125,6 @@ // Bit masks used for the display of additional image options in the UI #define IMOP_WINTOGO 0x01 #define IMOP_PERSISTENCE 0x02 -#define TEST_IMG_PATH "\\??\\C:\\tmp\\disk.img" -#define TEST_IMG_SIZE 4500 // Size in MB #define safe_free(p) do {free((void*)p); p = NULL;} while(0) #define safe_mm_free(p) do {_mm_free((void*)p); p = NULL;} while(0) diff --git a/src/rufus.rc b/src/rufus.rc index e925d017..0b0d000a 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.9.1604" +CAPTION "Rufus 3.9.1605" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -394,8 +394,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,1604,0 - PRODUCTVERSION 3,9,1604,0 + FILEVERSION 3,9,1605,0 + PRODUCTVERSION 3,9,1605,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -413,13 +413,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.9.1604" + VALUE "FileVersion", "3.9.1605" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.9.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.9.1604" + VALUE "ProductVersion", "3.9.1605" END END BLOCK "VarFileInfo"