Re[2]: How to flush memory mapped files?

In addition to these comments, check out the FAT source code to see how
it attempts to maintain data sync for the various write pathways. It
performs, or attempts to perform a flush, for example in the non-cached
(non-paging) path prior to allowing the IO through if there is a backing
section to the file.

Pete


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

------ Original Message ------
From: xxxxx@hotmail.com
To: “Windows File Systems Devs Interest List”
Sent: 3/20/2017 1:08:55 PM
Subject: RE:[ntfsd] How to flush memory mapped files?

>If your driver maintains( i.e. initializes ) file objects then
>CcFlushCache is your friend as it calls MmFlushSection even for
>non-cached files ( i.e. mapped but not cached ), if the file is mapped
>and cached then the cache is supported by the same pages as the mapped
>virtual address range. Do not forget about proper synchronization
>before calling CcFlushCache.
>
>If your driver doesn’t maintain file objects and uses file objects
>initialized by FSD(file system driver) it is attached to then there is
>no common way to do this. You can play with IRP_MJ_FLUSH_BUFFERS or you
>can use CcFlushCache, in the latter with a risk of going into conflict
>with FSD and MM( Memory Manager ) as you will be unable to properly
>synchronize with FSD before calling CcFlushCache.
>
>—
>NTFSD is sponsored by OSR
>
>
>MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>software drivers!
>Details at http:
>
>To unsubscribe, visit the List Server section of OSR Online at
>http:</http:></http:>

Yes, my filter maintains( i.e. initializes ) file objects, so in this situation CcFlushCache could flush memory mapped content into the file? Are you sure about that?

Yes I am sure. I can’t point you to the source code. It is shame that Microsoft still thinks that preventing access to the source code does any good for Windows development and OS future.

The sequence of calls will be
CcFlushCache ->MmFlushSection->IoAsynchronousPageWrite->IoCallDriver( paging IRP_MJ_WRITE )

IoCallDriver recursively calls your filter with paging write request so you have dirty pages in hand. Here you need to decide how you are going to synchronize with a file on a disk/storage. Actually in most cases you need synchronize file caches/memory mapped data but not write data directly to the disk as changing data on the disk without changing the cached/mapped data will not provide you with a desired effect as user applications fetch data from the cache/mapped file. This might result in data inconsistencies when the system will synchronize the cache/mapped data with the data on storage/disk.

I do not know your architecture. If you need to synchronize with files opened by user applications then you can copy data in a buffer ( I do not recommend to play with MDL here ), complete the paging write request as successful and issue a cached write to a file with which you want to synchronize data from a special worker thread used for data synchronization. In that case you know that when you are in this thread context you need either pass through the request to a lower FSD( if you are synchronizing with file objects initialized by a lower FSD ) or just call CcCopyWrite for file object your filter initialized ( if you are synchronizing with file objects initialized by your filter ). This will synchronize the cache and memory mapped file data and the data on the disk when the system will flush dirty pages.

You can take a more risky approach and issue requests directly on paging write path. This is prone to deadlocks in the Memory Manager and FSD.

As Done told you can’t say with certainty that you flushed data for a file object on a lower FSD. Actually you don’t need this as you need to synchronize cached/mapped data and let the system to do the rest.