Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b9d68f3
refactoring
assorted Nov 1, 2025
a3a7243
try-fix-write
assorted Dec 25, 2025
b406f74
Initial plan
Copilot Apr 22, 2026
8f70d9d
[UDFS] Chunk free-space bitmaps to avoid large contiguous allocations
Copilot Apr 22, 2026
b77faa5
[UDFS] Optimize chunked bitmap operations in hot paths
Copilot Apr 22, 2026
0353d6e
[UDFS] Harden and refine chunked bitmap helpers
Copilot Apr 22, 2026
b7aa7fe
[UDFS] Restore fast contiguous bitmap scan path
Copilot Apr 22, 2026
e03c28a
[UDFS] Improve non-chunked bitmap fast paths
Copilot Apr 22, 2026
d9ab9a6
[UDFS] Address review nits in bitmap helpers
Copilot Apr 22, 2026
e0a3616
[UDFS] Add verbose debug output to chunked bitmap infrastructure
Copilot Apr 22, 2026
401168e
[UDFS] Convert Vcb->Vat to chunked NonPagedPool allocation
Copilot Apr 22, 2026
01b90ae
udfs: apply chunked NonPagedPool allocation to all remaining I/O bitm…
Copilot Apr 22, 2026
72d1f6e
udfs: rename Bitmap to Chunked/Chunk in chunked-buffer infrastructure
Copilot Apr 22, 2026
60b642e
udfs: clarify UDF_CHUNKED_BUF_SIGNATURE comment
Copilot Apr 22, 2026
4b555ab
udfs: move UDFPrint macro before udf_info.h include
Copilot Apr 22, 2026
b586426
udfs: add UDFAllocChunkedBitmap/UDFFreeChunkedBitmap/UDFBitmapCopyMem…
Copilot Apr 22, 2026
17aafbc
udfs: replace old bitmap aliases with renamed chunked API calls in mo…
Copilot Apr 22, 2026
ef9c1fe
udfs: fix Vcb->Vat (PCHAR) cast errors in udf_info.cpp
Copilot Apr 22, 2026
713d6fe
udf_info: make chunked bitmap allocation lazy; fix VAT direct-access …
Copilot Apr 22, 2026
1e8965f
mount: fix UDFAddXSpaceBitmap/UDFVerifyXSpaceBitmap to avoid large fl…
Copilot Apr 22, 2026
5eaab1f
mount: clean up commented-out variable declarations in XSpaceBitmap f…
Copilot Apr 22, 2026
8f247c3
udfs: use PagedPool for chunked bitmap chunks; optimize AddXSpaceBitm…
Copilot Apr 22, 2026
b58ae57
udfs: add UDFSetFreeBitOwner loop in AddXSpaceBitmap byte fast-path
Copilot Apr 22, 2026
936d62e
UDFS: invert FSBM_Bitmap bit semantics (bit=1=USED) to avoid OOM on m…
Copilot Apr 23, 2026
9f36cf6
UDFS: remove Unicode checkmark from comment in alloc.cpp
Copilot Apr 23, 2026
22f50bc
udfs: use UDFReadExtentIntoChunked and UDFWriteExtentFromChunked for …
Copilot Apr 23, 2026
7cddfc6
udfs: extract BitmapHdrBitOffset constant per code review
Copilot Apr 23, 2026
18c40e6
udfs: simplify two redundant branches in new branch code
Copilot Apr 23, 2026
1b2fe64
udfs: increase chunk I/O size from 4 KB to 128 KB (UDF_CHUNK_SHIFT 12…
Copilot Apr 23, 2026
ae5f104
Merge branch 'udf-dev' into copilot/udfs-make-all-bitmaps-chunked
Copilot Apr 27, 2026
ff4a156
udfs: revert UDF_CHUNK_SHIFT back to 12 (4 KB chunks)
Copilot Apr 28, 2026
51ffa49
udfs: fix chunked bitmap performance – bulk range ops and fast UDFGet…
Copilot Apr 28, 2026
ea5bf81
udfs: fix undeclared 'BS' in UDFPrepareXSpaceBitmap
Copilot Apr 30, 2026
baac20c
udfs: fix (uint32*) → (PCHAR) cast for Vcb->Vat in udf_info.cpp after…
Copilot Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/filesystems/udfs/Include/udf_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef __DWUDF_REGISTRY__H__
#define __DWUDF_REGISTRY__H__


#define UDF_BM_FLUSH_PERIOD_NAME L"BitmapFlushPeriod"
#define UDF_TREE_FLUSH_PERIOD_NAME L"DirTreeFlushPeriod"
#define UDF_NO_UPDATE_PERIOD_NAME L"MaxNoUpdatePeriod"
Expand Down
1 change: 1 addition & 0 deletions drivers/filesystems/udfs/close.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ UDFCommonClose(
try_return(RC = STATUS_SUCCESS);
}


if ((Vcb->VcbCleanup == 0) &&
(Vcb->VcbCondition != VcbMounted)) {

Expand Down
36 changes: 36 additions & 0 deletions drivers/filesystems/udfs/create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ try_exit: NOTHING;
} // end UDFSupersedeOrOverwriteFile()



/*************************************************************************
*
* Function: UDFOpenExistingFcb()
Expand Down Expand Up @@ -997,6 +998,7 @@ try_exit: NOTHING;
*
*************************************************************************/
static

VOID
UDFNormalizeStreamSuffix(
IN PIRP_CONTEXT IrpContext,
Expand All @@ -1020,6 +1022,7 @@ UDFNormalizeStreamSuffix(
return;
}


// Check if there's a second ':' at all — if so, it's an unknown stream type
PWCHAR buf = Name->Buffer;
USHORT len = Name->Length / sizeof(WCHAR);
Expand All @@ -1030,6 +1033,7 @@ UDFNormalizeStreamSuffix(
}
}


/*************************************************************************
*
* Function: UDFCommonCreate()
Expand Down Expand Up @@ -1289,6 +1293,8 @@ UDFCommonCreate(

_SEH2_TRY {



// Verify that the Vcb is not in an unusable condition. This routine
// will raise if not usable.

Expand Down Expand Up @@ -1360,15 +1366,19 @@ UDFCommonCreate(
CreateDisposition == FILE_OVERWRITE_IF ||
CreateDisposition == FILE_CREATE) {


try_return(Status = STATUS_ACCESS_DENIED);

}

CurrentFcb = Vcb->VolumeDasdFcb;

// Acquire the Fcb exclusively before completing the open


UDFAcquireFcbExclusive(IrpContext, CurrentFcb, FALSE);


Status = UDFCompleteFcbOpen(IrpContext,
IrpSp,
Vcb,
Expand All @@ -1379,7 +1389,9 @@ UDFCommonCreate(
FALSE, // VcbLocked
FILE_OPENED); // DesiredInformation


try_return(Status);

}

if (UDFIllegalFcbAccess(Vcb, DesiredAccess)) {
Expand All @@ -1406,10 +1418,12 @@ UDFCommonCreate(
try_return(Status = STATUS_ACCESS_DENIED);
}


try_return(Status = UDFOpenObjectByFileId(IrpContext,
IrpSp,
Vcb,
&CurrentFcb));

}

//
Expand Down Expand Up @@ -1504,7 +1518,9 @@ UDFCommonCreate(
try_return(Status = STATUS_OBJECT_NAME_INVALID);
}
if (StreamOpen && !UDFIsStreamsSupported(Vcb)) {

try_return(Status = STATUS_OBJECT_NAME_INVALID);

}

// RemainingName was set by UDFNormalizeFileNames to point to the relative path
Expand Down Expand Up @@ -1846,6 +1862,7 @@ UDFCommonCreate(
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
}

if (NT_SUCCESS(Status)) {
// Re-inject stream name: next iteration will search
// for FinalName within the stream directory.
Expand All @@ -1864,6 +1881,7 @@ UDFCommonCreate(
&NewFileInfo, &PtrNewFcb);
if (NT_SUCCESS(Status)) {
LastGoodFileInfo = NewFileInfo;

} else {
// FCB setup failed — close stream dir and exit
UDFCloseFile__(IrpContext, Vcb, StreamDirInfo);
Expand Down Expand Up @@ -2027,9 +2045,11 @@ UDFCommonCreate(
// ... and exit with error
try_return(Status);
}

// Note: With LCB model, FcbReference is not incremented during path traversal,
// so no decrement is needed here (removed the old InterlockedDecrement).
Status = STATUS_SUCCESS;

ASSERT(!OpenTargetDirectory);
// Restore PtrNewFcb/NewFileInfo from last good state.
// The stream dir branch didn't open anything in this iteration,
Expand Down Expand Up @@ -2079,8 +2099,10 @@ UDFCommonCreate(
// FILE_CREATED, allocation size, attributes, and notification are
// all handled inside UDFOpenExistingFcb via CreateDisposition == FILE_CREATE.


LastGoodFileInfo = NewFileInfo;
try_return(Status);

}

// ****************
Expand Down Expand Up @@ -2159,10 +2181,12 @@ UDFCommonCreate(
// thread can have the file stream open at this time.
RelatedFileInfo = OldRelatedFileInfo;


Status = UDFCreateFile__(IrpContext, Vcb, IgnoreCase, &FinalName, 0, 0,
UdfIsExtendedFESupported(Vcb),
(CreateDisposition == FILE_CREATE), RelatedFileInfo, &NewFileInfo);
if (!NT_SUCCESS(Status)) {

AdPrint((" Creation error\n"));
try_return(Status);
}
Expand Down Expand Up @@ -2211,6 +2235,8 @@ UDFCommonCreate(
}
LastGoodFileInfo = NewFileInfo;



UDFNotifyReportChange(IrpContext, Vcb, NewFileInfo->Fcb,
UDFIsADirectory(NewFileInfo) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
FILE_ACTION_ADDED,
Expand Down Expand Up @@ -2243,11 +2269,15 @@ UDFCommonCreate(
}
LastGoodFileInfo = NewFileInfo;



// PHASE 2: Create stream file in the stream directory
RelatedFileInfo = NewFileInfo;

StreamName.Buffer++;
StreamName.Length -= sizeof(WCHAR);
Status = UDFCreateFile__(IrpContext, Vcb, IgnoreCase, &StreamName, 0, 0,

UdfIsExtendedFESupported(Vcb), (CreateDisposition == FILE_CREATE),
RelatedFileInfo, &NewFileInfo);
if (!NT_SUCCESS(Status)) {
Expand Down Expand Up @@ -2372,8 +2402,10 @@ try_exit: NOTHING;

if (NT_SUCCESS(Status) && PtrNewFcb) {


if (DeleteOnClose) {
ASSERT(!(PtrNewFcb->FcbState & UDF_FCB_ROOT_DIRECTORY));

}

if (StreamOpen) {
Expand Down Expand Up @@ -2832,13 +2864,15 @@ UDFCompleteFcbOpen(

if (!(Ccb = UDFCreateCcb())) {


return STATUS_INSUFFICIENT_RESOURCES;
}

DeleteCcbOnUnwind = TRUE;

_SEH2_TRY {


if (AddedAccess) {

ClearFlag(DesiredAccess, AddedAccess);
Expand Down Expand Up @@ -3018,6 +3052,7 @@ UDFCompleteFcbOpen(

Fcb->FcbState &= ~UDF_FCB_DELAY_CLOSE;


// Increment all reference counts here when CCB is successfully created.
// If VcbLocked is TRUE, caller already holds VcbMutex - use simple ++.
// If VcbLocked is FALSE, acquire VcbMutex for atomicity.
Expand All @@ -3026,6 +3061,7 @@ UDFCompleteFcbOpen(
UDFLockVcb(IrpContext, Fcb->Vcb);
}


// Cleanup counts:
Fcb->FcbCleanup++;
Fcb->Vcb->VcbCleanup++;
Expand Down
1 change: 1 addition & 0 deletions drivers/filesystems/udfs/env_spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,5 +556,6 @@ UDFNotifyReportChange(
if (PathAllocated && FullPath.Buffer) {
ExFreePool(FullPath.Buffer);
}

}

8 changes: 8 additions & 0 deletions drivers/filesystems/udfs/fileinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1840,7 +1840,9 @@ UDFPrepareForRenameMoveLink(
// There is a pair of objects among input dirs &
// one of them is a parent of another. Sequential resource
// acquisition may lead to deadlock due to concurrent

// cleanup operations or UDFTeardownStructures()

InterlockedIncrement((PLONG)&Vcb->VcbReference);


Expand All @@ -1852,12 +1854,14 @@ UDFPrepareForRenameMoveLink(
} else {
InterlockedDecrement((PLONG)&Vcb->VcbReference);


// Child-first lock ordering
// File1 (child) first, Dir1 (parent) second
UDF_CHECK_PAGING_IO_RESOURCE(File1->Fcb);
UDFAcquireFcbExclusive(IrpContext, File1->Fcb, TRUE);
(*AcquiredFcb1) = TRUE;


UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb);
UDFAcquireFcbExclusive(IrpContext, Dir1->Fcb, TRUE);
(*AcquiredDir1) = TRUE;
Expand Down Expand Up @@ -2284,6 +2288,7 @@ UDFSetRenameInfo(
? FILE_NOTIFY_CHANGE_DIR_NAME
: FILE_NOTIFY_CHANGE_FILE_NAME;


// Step 1: Notify OLD location (LCB still points to old parent)
// Use FileObject->FileName — stable path independent of LCB chain
if (SingleDir && !ReplaceIfExists) {
Expand All @@ -2292,8 +2297,10 @@ UDFSetRenameInfo(
} else {
UDFNotifyReportChange(IrpContext, Vcb, Fcb, Filter, FILE_ACTION_REMOVED,
Ccb->Lcb, FileObject);

}


// Step 2: Move LCB to new parent and update name
if (Ccb->Lcb) {
RC = UDFRenameMovePrefix(IrpContext, Ccb->Lcb, &NewName,
Expand All @@ -2306,6 +2313,7 @@ UDFSetRenameInfo(
// Step 3: Update FCB parent pointer for cross-directory rename
if (!SingleDir) {
Fcb->ParentFcb = TargetDirInfo->Fcb;

}

// Step 4: Notify NEW location (LCB now points to new parent)
Expand Down
1 change: 1 addition & 0 deletions drivers/filesystems/udfs/flush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ UDFCommonFlush(
// action we take.
if ((Fcb == Fcb->Vcb->VolumeDasdFcb) || (Fcb->FcbState & UDF_FCB_ROOT_DIRECTORY)) {


UDFFspClose(Vcb);

UDFAcquireVcbExclusive(IrpContext, Vcb, FALSE);
Expand Down
11 changes: 7 additions & 4 deletions drivers/filesystems/udfs/fscntrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,16 +669,19 @@ UDFCleanupVCB(

MyFreeMemoryAndPointer(Vcb->Partitions);
MyFreeMemoryAndPointer(Vcb->LVid);
MyFreeMemoryAndPointer(Vcb->Vat);
if (Vcb->Vat) {
UDFFreeChunked(Vcb->Vat);
Vcb->Vat = NULL;
}
MyFreeMemoryAndPointer(Vcb->SparingTable);

if (Vcb->FSBM_Bitmap) {
DbgFreePool(Vcb->FSBM_Bitmap);
UDFFreeChunked(Vcb->FSBM_Bitmap);
Vcb->FSBM_Bitmap = NULL;
}

if (Vcb->BSBM_Bitmap) {
DbgFreePool(Vcb->BSBM_Bitmap);
UDFFreeChunked(Vcb->BSBM_Bitmap);
Vcb->BSBM_Bitmap = NULL;
}
#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
Expand All @@ -688,7 +691,7 @@ UDFCleanupVCB(
}
#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
if (Vcb->FSBM_OldBitmap) {
DbgFreePool(Vcb->FSBM_OldBitmap);
UDFFreeChunked(Vcb->FSBM_OldBitmap);
Vcb->FSBM_OldBitmap = NULL;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/filesystems/udfs/protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,8 @@ UDFFastUnlockAllByKey(
* Prototypes for the file misc.cpp
*************************************************************************/



_IRQL_requires_max_(APC_LEVEL)
__drv_dispatchType(DRIVER_DISPATCH)
__drv_dispatchType(IRP_MJ_CREATE)
Expand Down Expand Up @@ -868,6 +870,8 @@ UDFInsertFcbIntoTable(
_In_ PFCB Fcb
);



_Ret_valid_ PIRP_CONTEXT
UDFCreateIrpContext(
_In_ PIRP Irp,
Expand Down
1 change: 1 addition & 0 deletions drivers/filesystems/udfs/read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ UDFCommonRead(
Status = UDFReadFile__(IrpContext, Vcb, Fcb->FileInfo, StartingOffset, ByteCount,
FALSE, (PCHAR)SystemBuffer, &NumberBytesRead);


/* // AFAIU, CacheManager wants this:
if (!NT_SUCCESS(RC)) {
NumberBytesRead = 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/filesystems/udfs/shutdown.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ UDFCommonShutdown(
UdfData.UDFDeviceObject_HDD = NULL;
}


UDFCompleteRequest(IrpContext, Irp, STATUS_SUCCESS);

} _SEH2_END; // end of "__finally" processing
Expand Down
Loading
Loading