BSOD with CcDeferWrite on Win11

I am experiencing a BSOD with CcDeferWrite on Win11 24H2. Earlier versions of Win10 do not exhibit this problem (confirmed by automated testing which exercises this code path).

The BSOD is as follows (relevant parts only shown):

0: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 0000000000000450, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000000, bitfield :
	bit 0 : value 0 = read operation, 1 = write operation
	bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: fffff806e829deae, address which referenced memory

Debugging Details:
------------------

...

BUGCHECK_CODE:  a

BUGCHECK_P1: 450

BUGCHECK_P2: 2

BUGCHECK_P3: 0

BUGCHECK_P4: fffff806e829deae

FAULTING_THREAD:  ffffde85e398c080

READ_ADDRESS:  0000000000000450

PROCESS_NAME:  winfsp-tests-x64.exe

TRAP_FRAME:  fffff48d52ace9a0 -- (.trap 0xfffff48d52ace9a0)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=ffffde85da855ce0
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff806e829deae rsp=fffff48d52aceb30 rbp=ffffde85da855820
 r8=0000000000000000  r9=0000000000200000 r10=0000000000000001
r11=0000000000001001 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz na pe nc
nt!CcPostDeferredWrites+0x4a:
fffff806`e829deae 498b3e          mov     rdi,qword ptr [r14] ds:00000000`00000000=????????????????
Resetting default scope

STACK_TEXT:
*** WARNING: Unable to verify checksum for winfsp-tests-x64.exe
fffff48d`52ace028 fffff806`e84ec432     : fffff48d`52ace0a8 00000000`00000001 00000000`00000080 fffff806`e860cb01 : nt!DbgBreakPointWithStatus
fffff48d`52ace030 fffff806`e84eb95c     : 00000000`00000003 fffff48d`52ace190 fffff806`e860ce00 fffff48d`52ace750 : nt!KiBugCheckDebugBreak+0x12
fffff48d`52ace090 fffff806`e8438c07     : fffff806`e7f80000 fffff806`e81ada0a 00000000`00000450 fffff48d`52ace930 : nt!KeBugCheck2+0xb2c
fffff48d`52ace820 fffff806`e8606fe9     : 00000000`0000000a 00000000`00000450 00000000`00000002 00000000`00000000 : nt!KeBugCheckEx+0x107
fffff48d`52ace860 fffff806`e86022a8     : 00000000`49707346 ffffde85`00000000 ffffde85`da602000 00000000`00000028 : nt!KiBugCheckDispatch+0x69
fffff48d`52ace9a0 fffff806`e829deae     : ffffde85`da855820 ffffde85`e4d7dbf0 00000000`00000068 ffffde85`e39af060 : nt!KiPageFault+0x468
fffff48d`52aceb30 fffff806`e84b4223     : ffffde85`da855820 ffffde85`da855820 00000000`00000000 00000000`00000000 : nt!CcPostDeferredWrites+0x4a
fffff48d`52aceba0 fffff807`c0b1ff5d     : ffffde85`e378f8a0 fffff806`79a86af7 ffffde85`e39af060 00000000`00000000 : nt!CcDeferWrite+0x113
fffff48d`52acec00 fffff807`c0b1fccb     : ffffde85`e39af060 ffffde85`e378f8a0 ffffde85`e378f970 fffff807`c0b1fb01 : winfsp_x64!FspFsvolWriteCached+0x24d [C:\Users\billziss\Projects\winfsp\src\sys\write.c @ 262]
fffff48d`52aced50 fffff807`c0b21b64     : ffffde85`e39af060 ffffde85`e378f8a0 ffffde85`e378f970 00000000`00000000 : winfsp_x64!FspFsvolWrite+0x15b [C:\Users\billziss\Projects\winfsp\src\sys\write.c @ 220]
fffff48d`52aceda0 fffff806`e821658c     : ffffde85`e39af060 ffffde85`e378f8a0 ffff819e`1eb4287b 00000000`00000000 : winfsp_x64!FspWrite+0x194 [C:\Users\billziss\Projects\winfsp\src\sys\write.c @ 778]
fffff48d`52aceed0 fffff806`e8ae5ad4     : 00000000`00000004 ffffde85`e4d7dbf0 ffffde85`e378f8a0 ffffde85`e4d7dbf0 : nt!IopfCallDriver+0x8c
fffff48d`52acef10 fffff806`e821696c     : ffffde85`e325c010 ffffde85`e378f8a0 00000000`00000008 00000000`00000000 : nt!IovCallDriver+0x44
fffff48d`52acef50 fffff806`79a86af7     : ffffdcee`7e01ba20 ffffde85`e325c010 ffffdcee`773b9f80 fffff806`e8db77c0 : nt!IofCallDriver+0xac
fffff48d`52acef90 fffff806`79a85c19     : fffff48d`52acf090 00000000`00000001 00000000`00000000 ffffde85`e378f9b8 : FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x237
fffff48d`52acf030 fffff806`e821658c     : 00000000`00000001 ffffde85`e378f8a0 ffffde85`e2ca0970 ffffde85`e4d7dbf0 : FLTMGR!FltpDispatch+0x109
fffff48d`52acf0d0 fffff806`e8ae5ad4     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!IopfCallDriver+0x8c
fffff48d`52acf110 fffff806`e821696c     : ffffde85`e2ca0970 fffff48d`52acf200 00000000`00000001 00000000`00000000 : nt!IovCallDriver+0x44
fffff48d`52acf150 fffff806`e880a568     : fffff48d`52acf200 fffff48d`52acf200 ffffde85`e2ca0970 00000000`00000001 : nt!IofCallDriver+0xac
fffff48d`52acf190 fffff806`e88088c1     : fffff48d`52acf2a0 fffff48d`52acf370 00000000`00000000 00000000`00000000 : nt!IopSynchronousServiceTail+0x1c8
fffff48d`52acf240 fffff806`e880858f     : ffffde85`e4d7dbf0 ffffde85`e4d7dbc0 ffffde85`e378f8a0 00000000`00000000 : nt!IopWriteFile+0x141
fffff48d`52acf360 fffff806`e8606655     : 00000000`00100084 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtWriteFile+0x2cf
fffff48d`52acf430 00007ff9`1905ef04     : 00007ff9`168faf4d 0000003e`33b0e628 00007ff7`2f417c8d 00000149`ca1f7900 : nt!KiSystemServiceCopyEnd+0x25
0000003e`33b0e0f8 00007ff9`168faf4d     : 0000003e`33b0e628 00007ff7`2f417c8d 00000149`ca1f7900 00000000`00011007 : ntdll!NtWriteFile+0x14
0000003e`33b0e100 00007ff7`2f3847ce     : 00000149`ca1f7900 00000000`00000000 00007ff7`00000001 0000003e`33b0e594 : KERNELBASE!WriteFile+0x8d
0000003e`33b0e170 00007ff7`2f38f6cc     : 00007ff7`00000000 00000000`00000000 00000000`00000000 00000000`ffffffff : winfsp_tests_x64!rdwr_append_dotest+0x43e [C:\Users\billziss\Projects\winfsp\tst\winfsp-tests\rdwr-test.c @ 254]
0000003e`33b0e880 00007ff7`2f31a981     : 00007ff7`2f49c019 00000000`00000058 00000000`00000000 00000149`cc686ee0 : winfsp_tests_x64!rdwr_writethru_append_test+0xbc [C:\Users\billziss\Projects\winfsp\tst\winfsp-tests\rdwr-test.c @ 980]
0000003e`33b0eca0 00007ff7`2f31a63a     : 00000149`cc7de380 0000003e`33b0ee78 00000000`0000000d 00007ff7`2f43d070 : winfsp_tests_x64!run_test+0x81 [C:\Users\billziss\Projects\winfsp\ext\tlib\testsuite.c @ 84]
0000003e`33b0ee50 00007ff7`2f31b5dd     : 00000149`cc7de380 00000000`00000006 00000000`00000000 00000000`00000000 : winfsp_tests_x64!do_test_default+0x11a [C:\Users\billziss\Projects\winfsp\ext\tlib\testsuite.c @ 110]
0000003e`33b0eff0 00007ff7`2f3b509d     : 00000000`00000001 00000149`ca1f7908 0000003e`33b0f6b8 00000000`00000000 : winfsp_tests_x64!tlib_run_tests+0x4fd [C:\Users\billziss\Projects\winfsp\ext\tlib\testsuite.c @ 222]
0000003e`33b0f3d0 00007ff7`2f3b8648     : 00000000`00000002 00000149`ca1f7900 00000000`00000000 00000000`00000000 : winfsp_tests_x64!main+0x119d [C:\Users\billziss\Projects\winfsp\tst\winfsp-tests\winfsp-tests.c @ 426]
0000003e`33b0f850 00007ff9`1837dbe7     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : winfsp_tests_x64!__scrt_common_main_seh+0x10c [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
0000003e`33b0f890 00007ff9`18f85a6c     : 00000000`00000000 00000000`00000000 000004f0`fffffb30 000004d0`fffffb30 : KERNEL32!BaseThreadInitThunk+0x17
0000003e`33b0f8c0 00000000`00000000     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2c

...

The original file object has NULLs in its SectionObjectPointer:

0: kd> ?? FileObject->SectionObjectPointer
struct _SECTION_OBJECT_POINTERS * 0xffffde85`e4140fb8
   +0x000 DataSectionObject : (null)
   +0x008 SharedCacheMap   : (null)
   +0x010 ImageSectionObject : (null)

Some analysis shows that:

  • CcDeferWrite uses CcGetPrivateVolumeCacheMapFromFileObject to get a _PRIVATE_VOLUME_CACHEMAP object. This routine first attempts to get this object from the FileObject->SectionObjectPointer (via the PrivateVolumeCacheMap field of _SHARED_CACHE_MAP and if that fails it falls back to consulting CcVolumeCacheMapList.

  • CcDeferWrite calls CcPostDeferredWrites. This bugchecks when trying to access the DeferredWrites field (at offset 0x450) of _PRIVATE_VOLUME_CACHEMAP.

I am at a loss why this happens as I do not know if these new behaviors are documented anywhere. Any suggestions on how to make my File System Driver work properly with CcDeferWrite under latest versions of Win11 are welcome.

SWAG have you called CcInitializeCacheMap yet?

have you called CcInitializeCacheMap yet?

That's a good question.

In my FSD it is possible to get into the CcDeferWrite path without having called CcInitializeCacheMap on the FileObject. My understanding based on how FastFat does things is that this is legal. Is that not the case?

According to the MSDN, you should call CcInitializeCacheMap() before CcCanIWrite() or CcDeferWrite().
Also see CcInitializeCacheMap() page:

File systems must call CcInitializeCacheMap to cache a file before using any other cache manager routines on the file, unless the file was created with data caching disabled