Close-To-Open Consistency and Mapped I/O

Hi all,

We have a layered file system driver (not filter), which stores the actual data on a different file system. As expected, we own the FCB, but we’re not using the cache manager services. All the requests are attended by reading from or writing to the underlying file system.

There’s a customer complaining about the “close-to-open” consistency on the following scenario:

  1. Application A opens a given file.
  2. Application A maps the file content in memory.
  3. Application A closes the file handle.
  4. Application A writes to the map.
  5. Application A unmap the file and ends.
  6. Application B opens the same file.
  7. Application B reads the file using regular I/O.

Application B is reading stale data because the data comes from the underlying file system, but dirty pages were not flushed to the media (underlying file system) yet.

Now I’m confused about this “close-to-open” consistency because we all know that a file system driver cannot ensure data coherency between mapped I/O and regular I/O. Should that be different in cases like the one above? And if so, how could my driver accomplish such a requirement without impacting on performance? Am I obligated to use cache manager?

Thanks in advance,

Fernando Roberto da Silva
DriverEntry Kernel Development
http://www.driverentry.com.br

> 1) Application A opens a given file.

  1. Application A maps the file content in memory.
  2. Application A closes the file handle.
  3. Application A writes to the map.
  4. Application A unmap the file and ends.
  5. Application B opens the same file.
  6. Application B reads the file using regular I/O.

If App B uses noncached IO to read the file - then sorry, on older Windows versions the coherency is not guaranteed in such a case.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

File system drives work quite hard to ensure data coherency between mapped I/O and regular I/O - and not just across opens, but while the file is opened via both paths. Indeed CcCoherencyFlushAndPurgeCache was added (Windows 7) to further improve the ability of the file system to maintain coherency between mapped and non-cached I/O (which is comparable to the problem that you’re having).

Cache Manager integration gives mapped and cached I/O coherency “for free”, but because you are maintaining your own cache (that’s what Mm is doing for the memory mapped I/O, after all), you become responsible for maintaining that coherency.

Is there a reason you aren’t doing at least a flush on that second open? Presumably you can locate your own control structures, so you should notice there is an SOP with a non-null DataSectionObject. In that case, just calling CcCoherencyFlushAndPurge might be all it takes. I can understand not wanting to do it in the close path (it might not be necessary/useful) but doing it in the second create path (where it’s there for correctness) should “do the right thing” and only pay the cost when it’s necessary.

MmDoesFileHaveUserWriteableReferences can also be used to help out with this process - you can do that (on the second open) and if it comes back as true it means someone has it memory mapped and you can return STATUS_SHARING_VIOLATION (see the FastFat code sample).

I can see other scenarios that should break in your environment. For example:

(1) Execute program foo.exe
(2) Copy bar.exe onto foo.exe
(3) Execute program foo.exe

This is going to have similar coherency issues, just using the ImageSectionObject rather than the DataSectionObject. For that you use MmFlushImageSection…

Tony
OSR

Hi Tony,

The only reason I had for not doing the flush on the second open was about getting a performance impact for no reason, assuming mixing mapped IO and regular IO would always be incoherent even through close to open.

Thanks for the clarification.
Regards,

Fernando Roberto da Silva
DriverEntry Kernel Development
http://www.driverentry.com.br