diff --git a/drivers/filesystems/udfs/Include/mem_tools.cpp b/drivers/filesystems/udfs/Include/mem_tools.cpp index 7b9a8bf8ea499..82defc5b8c4ea 100644 --- a/drivers/filesystems/udfs/Include/mem_tools.cpp +++ b/drivers/filesystems/udfs/Include/mem_tools.cpp @@ -39,7 +39,7 @@ InitLockMemoryManager() { KeInitializeSpinLock(&FrameLock); return STATUS_SUCCESS; } -#define DeinitLockMemoryManager() {NOTHING;} +#define DeinitLockMemoryManager() ((void)0) #else //MEM_LOCK_BY_SPINLOCK ERESOURCE FrameLock; #define LockMemoryManager() ExAcquireResourceExclusiveLite(&FrameLock, TRUE) @@ -184,9 +184,9 @@ MyAllocCheck( //#endif //CHECK_ALLOC_FRAMES #else -#define MyAllocDumpFrame(a) {} -#define MyAllocCheck(a) {} -#define MyAllocDumpFrames() {} +#define MyAllocDumpFrame(a) ((void)0) +#define MyAllocCheck(a) ((void)0) +#define MyAllocDumpFrames() ((void)0) #endif // UDF_DBG diff --git a/drivers/filesystems/udfs/udf_dbg.h b/drivers/filesystems/udfs/udf_dbg.h index 63fc430bc3c83..c4c543c2acbe5 100644 --- a/drivers/filesystems/udfs/udf_dbg.h +++ b/drivers/filesystems/udfs/udf_dbg.h @@ -61,13 +61,13 @@ #ifdef USE_KD_PRINT #define KdPrint(_x_) DbgPrint _x_ #else - #define KdPrint(a) {NOTHING;} + #define KdPrint(a) ((void)0) #endif //USE_KD_PRINT #ifdef USE_MM_PRINT #define MmPrint(_x_) DbgPrint _x_ #else - #define MmPrint(_x_) {NOTHING;} + #define MmPrint(_x_) ((void)0) #endif //USE_MM_PRINT #ifdef USE_TIME_PRINT @@ -80,29 +80,29 @@ #ifdef USE_AD_PRINT #define AdPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;} #else - #define AdPrint(_x_) {NOTHING;} + #define AdPrint(_x_) ((void)0) #endif #ifdef USE_TH_PRINT #define ThPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;} #else - #define ThPrint(_x_) {NOTHING;} + #define ThPrint(_x_) ((void)0) #endif #ifdef UDF_DUMP_EXTENT #define ExtPrint(_x_) KdPrint(_x_) #else - #define ExtPrint(_x_) {NOTHING;} + #define ExtPrint(_x_) ((void)0) #endif #else // defined UDF_DBG || defined PRINT_ALWAYS - #define MmPrint(_x_) {NOTHING;} - #define TmPrint(_x_) {NOTHING;} - #define PerfPrint(_x_) {NOTHING;} - #define AdPrint(_x_) {NOTHING;} - #define ThPrint(_x_) {NOTHING;} - #define ExtPrint(_x_) {NOTHING;} + #define MmPrint(_x_) ((void)0) + #define TmPrint(_x_) ((void)0) + #define PerfPrint(_x_) ((void)0) + #define AdPrint(_x_) ((void)0) + #define ThPrint(_x_) ((void)0) + #define ExtPrint(_x_) ((void)0) #endif // defined UDF_DBG || defined PRINT_ALWAYS @@ -120,24 +120,16 @@ DbgWaitForSingleObject_( #ifdef UDF_DBG -#ifdef _X86_ -// This is an illegal use of INT3 -#define UDFBreakPoint() { __asm int 3 } -#else // _X86_ - -#define UDFBreakPoint() DbgBreakPoint() -#endif // _X86_ - #ifdef BRUTE #define BrutePoint() UDFBreakPoint() #else -#define BrutePoint() {} +#define BrutePoint() ((void)0) #endif // BRUTE #ifdef CHECK_REF_COUNTS #define ASSERT_REF(_a_) ASSERT(_a_) #else -#define ASSERT_REF(_a_) {NOTHING;} +#define ASSERT_REF(_a_) ((void)0) #endif //CHECK_REF_COUNTS #ifdef TRACK_SYS_ALLOCS @@ -186,7 +178,7 @@ VOID DebugFreePool(PVOID addr); } #else -#define ValidateFileInfo(fi) {} +#define ValidateFileInfo(fi) ((void)0) #endif #if defined (_X86_) && defined (_MSC_VER) @@ -219,13 +211,13 @@ __inline VOID UDFTouch(IN PVOID addr) #define DbgCopyMemory(d, s, l) RtlCopyMemory(d, s, l) #define DbgCompareMemory(d, s, l) RtlCompareMemory(d, s, l) -#define ASSERT_REF(_a_) {NOTHING;} +#define ASSERT_REF(_a_) ((void)0) -#define UDFBreakPoint() {} -#define BrutePoint() {} -#define ValidateFileInfo(fi) {} +#define UDFBreakPoint() ((void)0) +#define BrutePoint() ((void)0) +#define ValidateFileInfo(fi) ((void)0) -#define UDFTouch(addr) {} +#define UDFTouch(addr) ((void)0) #endif // UDF_DBG @@ -245,7 +237,7 @@ if ((a)!=NULL) { \ #else -#define KdDump(a,b) {} +#define KdDump(a,b) ((void)0) #endif // UDF_DBG diff --git a/drivers/filesystems/udfs/udf_info/alloc.cpp b/drivers/filesystems/udfs/udf_info/alloc.cpp index 530d6b168767e..d881e10592a40 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.cpp +++ b/drivers/filesystems/udfs/udf_info/alloc.cpp @@ -408,6 +408,7 @@ UDFCheckSpaceAllocation_( uint32 i=0; uint32 lba, j, len, BS, BSh; BOOLEAN asUsed = (asXXX == AS_USED); + uint32* BitmapPtr = (uint32*)(Vcb->FSBM_Bitmap); if (!Map) return; @@ -468,39 +469,56 @@ UDFCheckSpaceAllocation_( len = Vcb->LastPossibleLBA - lba; } - // mark frag as XXX (see asUsed parameter) - if (asUsed) { + // --- SPEED OPTIMIZATION: Word-at-a-time verification --- + // Instead of bit-by-bit, we check 32 blocks per CPU instruction. + j = 0; + while (j < len) { + // Fast Path: Check 32 blocks if aligned on a 32-bit boundary + if (((lba + j) & 31) == 0 && (len - j) >= 32) { + uint32 CurrentWord = BitmapPtr[(lba + j) >> 5]; + + if (asUsed) { + // In UDF, 0 = Used. We expect the whole word to be 0x00000000. + if (CurrentWord == 0) { + j += 32; + continue; + } + } else { + // In UDF, 1 = Free. We expect the whole word to be 0xFFFFFFFF. + if (CurrentWord == 0xFFFFFFFF) { + j += 32; + continue; + } + } + // If the word check fails, we fall through to the bit-checker below + // to identify exactly which block is inconsistent. + } - ASSERT(len); - for(j=0;j Vcb->LastPossibleLBA) { + // Fallback: Individual bit check (for tails or if an inconsistency is found) + if (asUsed) { + if (lba + j > Vcb->LastPossibleLBA) { BrutePoint(); - AdPrint(("USED Mapping covers block(s) beyond media @%x\n",lba+j)); break; } - if (!UDFGetUsedBit(Vcb->FSBM_Bitmap, lba+j)) { + if (!UDFGetUsedBit(Vcb->FSBM_Bitmap, lba + j)) { BrutePoint(); - AdPrint(("USED Mapping covers FREE block(s) @%x\n",lba+j)); + AdPrint(("USED Mapping covers FREE block @ %x\n", lba + j)); break; } - } - - } else { - - ASSERT(len); - for(j=0;j Vcb->LastPossibleLBA) { + } else { + if (lba + j > Vcb->LastPossibleLBA) { BrutePoint(); - AdPrint(("USED Mapping covers block(s) beyond media @%x\n",lba+j)); break; } - if (!UDFGetFreeBit(Vcb->FSBM_Bitmap, lba+j)) { + if (!UDFGetFreeBit(Vcb->FSBM_Bitmap, lba + j)) { BrutePoint(); - AdPrint(("FREE Mapping covers USED block(s) @%x\n",lba+j)); + AdPrint(("FREE Mapping covers USED block @ %x\n", lba + j)); break; } } + j++; } + // --- END OPTIMIZATION --- i++; } @@ -516,11 +534,28 @@ UDFMarkBadSpaceAsUsed( ) { uint32 j; + uint32 start_word, end_word; + + // BIT_C is the number of bits per array element (usually 8 or 32) #define BIT_C (sizeof(Vcb->BSBM_Bitmap[0])*8) - len = (lba+len+BIT_C-1)/BIT_C; - if (Vcb->BSBM_Bitmap) { - for(j=lba/BIT_C; jFSBM_Bitmap[j] &= ~Vcb->BSBM_Bitmap[j]; + + if (Vcb->BSBM_Bitmap && Vcb->FSBM_Bitmap) { + + start_word = lba / BIT_C; + end_word = (lba + len + BIT_C - 1) / BIT_C; + + // Ensure we don't go out of bounds of the allocated bitmap + uint32 max_words = (Vcb->FSBM_BitCount + BIT_C - 1) / BIT_C; + if (end_word > max_words) end_word = max_words; + + // FAST PATH: If the range is large, the CPU can process + // these words very quickly. + for(j = start_word; j < end_word; j++) { + // Only perform the write if there is actually a bad bit to clear + // This saves a memory write cycle (bus traffic) + if (Vcb->BSBM_Bitmap[j] != 0) { + Vcb->FSBM_Bitmap[j] &= ~Vcb->BSBM_Bitmap[j]; + } } } #undef BIT_C @@ -603,40 +638,29 @@ UDFMarkSpaceAsXXXNoProtect_( bit_after = UDFGetBit(Vcb->FSBM_Bitmap, lba+len); #endif //UDF_TRACK_ONDISK_ALLOCATION - // mark frag as XXX (see asUsed parameter) + // --- SPEED OPTIMIZATION START --- + // Instead of bit-loops, we use the optimized SetBits/FreeBits + // which should ideally be mapped to RtlFillMemory for large spans. if (asUsed) { -/* for(j=0;jFSBM_Bitmap, lba+j); - }*/ ASSERT(len); + // Fast Path: If we are marking a large span as used (bits = 1) + // UDFSetUsedBits handles the bit-shifting logic. UDFSetUsedBits(Vcb->FSBM_Bitmap, lba, len); -#ifdef UDF_TRACK_ONDISK_ALLOCATION - for(j=0;jFSBM_Bitmap, lba+j)); - } -#endif //UDF_TRACK_ONDISK_ALLOCATION - + + // VAT handling (This loop is slow but only runs for UDF 1.50/Vat-based media) if (Vcb->Vat) { - // mark logical blocks in VAT as used for(j=0;jVat[lba-root+j] == UDF_VAT_FREE_ENTRY) && - (lba > Vcb->LastLBA)) { + if ((Vcb->Vat[lba-root+j] == UDF_VAT_FREE_ENTRY) && (lba > Vcb->LastLBA)) { Vcb->Vat[lba-root+j] = 0x7fffffff; } } } } else { -/* for(j=0;jFSBM_Bitmap, lba+j); - }*/ ASSERT(len); + // Fast Path: Mark space as free (bits = 0) UDFSetFreeBits(Vcb->FSBM_Bitmap, lba, len); -#ifdef UDF_TRACK_ONDISK_ALLOCATION - for(j=0;jFSBM_Bitmap, lba+j)); - } -#endif //UDF_TRACK_ONDISK_ALLOCATION + if (asXXX & AS_BAD) { UDFSetBits(Vcb->BSBM_Bitmap, lba, len); } @@ -645,25 +669,19 @@ UDFMarkSpaceAsXXXNoProtect_( if (asXXX & AS_DISCARDED) { UDFUnmapRange(Vcb, lba, len); } + if (Vcb->Vat) { - // mark logical blocks in VAT as free - // this operation can decrease resulting VAT size for(j=0;jVat[lba-root+j] = UDF_VAT_FREE_ENTRY; } } - // mark discarded extent as Not-Alloc-Not-Rec to - // prevent writes there + + // Optimization for the Map itself Map[i].extLength = (len << BSh) | (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30); Map[i].extLocation = 0; } - -#ifdef UDF_TRACK_ONDISK_ALLOCATION - if (lba) - ASSERT(bit_before == UDFGetBit(Vcb->FSBM_Bitmap, lba-1)); - ASSERT(bit_after == UDFGetBit(Vcb->FSBM_Bitmap, lba+len)); -#endif //UDF_TRACK_ONDISK_ALLOCATION + // --- SPEED OPTIMIZATION END --- i++; } @@ -755,6 +773,9 @@ UDFAllocFreeExtent_( // probably we have the opportunity to do it Ext.extLength = len<>5]) |= (((uint32)1) << ((bit)&31)) ) #define UDFClrBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) &= (~(((uint32)1) << ((bit)&31))) ) -#define UDFSetBits(arr, bit, bc) \ -{uint32 j; \ - for(j=0;j 0) { \ + /* 1. Tail: bit-by-bit until byte aligned */ \ + while (_c > 0 && (_b & 7) != 0) { \ + UDFSetBit(arr, _b); \ + _b++; _c--; \ + } \ + /* 2. Fast Path: High-speed byte fill */ \ + if (_c >= 8) { \ + uint32 _bytes = _c >> 3; \ + RtlFillMemory(((uint8*)(arr)) + (_b >> 3), _bytes, 0xFF); \ + _b += (_bytes << 3); \ + _c -= (_bytes << 3); \ + } \ + /* 3. Tail: remaining bits */ \ + while (_c > 0) { \ + UDFSetBit(arr, _b); \ + _b++; _c--; \ + } \ + } \ +} while (0) + +#define UDFClrBits(arr, bit, bc) \ +do { \ + uint32 _b = (uint32)(bit); \ + uint32 _c = (uint32)(bc); \ + if (_c > 0) { \ + while (_c > 0 && (_b & 7) != 0) { \ + UDFClrBit(arr, _b); \ + _b++; _c--; \ + } \ + if (_c >= 8) { \ + uint32 _bytes = _c >> 3; \ + RtlZeroMemory(((uint8*)(arr)) + (_b >> 3), _bytes); \ + _b += (_bytes << 3); \ + _c -= (_bytes << 3); \ + } \ + while (_c > 0) { \ + UDFClrBit(arr, _b); \ + _b++; _c--; \ + } \ + } \ +} while (0) + #define UDFGetUsedBit(arr,bit) (!UDFGetBit(arr,bit)) #define UDFGetFreeBit(arr,bit) UDFGetBit(arr,bit) diff --git a/drivers/filesystems/udfs/udffs.h b/drivers/filesystems/udfs/udffs.h index 272046b907e62..a3d28704fb3f0 100644 --- a/drivers/filesystems/udfs/udffs.h +++ b/drivers/filesystems/udfs/udffs.h @@ -98,6 +98,8 @@ typedef FILE_ID *PFILE_ID; #define UDF_DBG #endif +//#define BRUTE + #define VALIDATE_STRUCTURES // the following include files should be in the inc sub-dir associated with this driver