Hey , im filtering all kind of writes in my filter , taking two different code paths for noncached paging I/O and any other I/O
with the noncached paging I/O path , I call FltReadFile with FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET | FLTFL_IO_OPERATION_NON_CACHED
for some reason it causes my test program (that performs a noncached paging write) to hang , I know it's down to this FltReadFile call because commenting it out and the program runs flawlessly
I came across a few threads that suggest you can't just read in the paging io path , discussing some methods (queuing a work item for reading , reissuing irps etc )
why is that ? no way to just read and avoid the complexity ?
It’s going to be entirely file system implementation dependant but thats a pretty good guarantee of a deadlock and the non paging read queues for a lock that the thread doing the paging read already has.
You only chance is a paging read or post and dont wait for the read.
It tells the file system that this is a paging read, which has different behaviors than regular non-cached reads. Understanding why it hangs with this flag and not without is a fundamental part of understanding the way the file systems interact with the Io, Cc, and Mm subsystems. You can't just arbitrarily change from non-cached to paging and expect things to work.
Why is a long answer (I spend almost an entire day on it in my minifilter seminar). I suggest starting by reading the Windows NT File Systems Internals book:
Anything about how to write a file system filter is out of date of course, but it does a good job describing the role of the file system and the different types of I/Os.
I also recommend building your own version of the FAT source code, installing it, and stepping through the I/O paths. Right away you'll see that paging and non-cached I/Os are not treated the same:
//
// If this is a noncached transfer and is not a paging I/O, and
// the file has a data section, then we will do a flush here
// to avoid stale data problems. Note that we must flush before
// acquiring the Fcb shared since the write may try to acquire
// it exclusive.
//
if (!PagingIo && NonCachedIo
&&
(FileObject->SectionObjectPointer->DataSectionObject != NULL)) {