File Context for Paging IO

I’m fairly new to FSD and I’m writing a file system driver to track writes. I’m using a StreamHandleContext (allocated PostCreate) to track filenames. During the PreWrite callback, I’m calling the following code.

status = FltGetStreamHandleContext(pFltObjects->Instance, pFltObjects->FileObject, &pFileContext);

if(NT_SUCCESS(status))
{
if (FlagOn(pCallbackData->Iopb->IrpFlags, IRP_PAGING_IO))
{
DBG_PRINT(DBG_TRACE_WRITE, (“Writing To: PAGEFILE [%wZ]\n”, &pFileContext->fileName));
gpCacheDriverContext->writeCP++;
}
}

In my traces I’m seeing a bunch of different filenames for the file context. Could someone explain to me why the file name is not always set to the pagefile - considering I’m predicated on the IRP_PAGING_IO flag?

Thanks,

Ben.

Memory mapped files are also paging writes and IIRC also for cache
writes.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@hotmail.com” wrote in message
news:xxxxx@ntfsd:

> I’m fairly new to FSD and I’m writing a file system driver to track writes. I’m using a StreamHandleContext (allocated PostCreate) to track filenames. During the PreWrite callback, I’m calling the following code.
>
> status = FltGetStreamHandleContext(pFltObjects->Instance, pFltObjects->FileObject, &pFileContext);
>
> if(NT_SUCCESS(status))
> {
> if (FlagOn(pCallbackData->Iopb->IrpFlags, IRP_PAGING_IO))
> {
> DBG_PRINT(DBG_TRACE_WRITE, (“Writing To: PAGEFILE [%wZ]\n”, &pFileContext->fileName));
> gpCacheDriverContext->writeCP++;
> }
> }
>
> In my traces I’m seeing a bunch of different filenames for the file context. Could someone explain to me why the file name is not always set to the pagefile - considering I’m predicated on the IRP_PAGING_IO flag?
>
> Thanks,
>
> Ben.

Paging I/O is not the same as Paging I/O to the paging file.

See FsRtlIsPagingFile, which can be used to determine if a specific file object is a paging file.

Tony
OSR

Thanks for the very fast responses. They’re very helpful.

I’d like to be able to determine which paging I/O writes actually make it to the filesystem (as opposed to the cache). Are you aware of any flags that might enable me to do this?

Ben.

Paging I/O is not cached, so all of them make it to the storage for the
file system.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@hotmail.com” wrote in message
news:xxxxx@ntfsd:

> Thanks for the very fast responses. They’re very helpful.
>
> I’d like to be able to determine which paging I/O writes actually make it to the filesystem (as opposed to the cache). Are you aware of any flags that might enable me to do this?
>
> Ben.

There isn’t any way to guarantee that a paging I/O isn’t going to be converted by some lower layer. In the simplest case, paging I/O IS treated as non-cached (e.g., your filter on top of a physical media file system.) In more complex cases, the underlying file system might play tricks you don’t really understand.

For example, imagine you have paging I/O to a compressed file on NTFS - the “uncompressed” data is written out via the paging I/O, but it is then compressed and written to the cache for the compressed version of the file. A second paging I/O will then cause that to be written out to disk.

We do something comparable in our own layered file systems - our paging I/O (in the layered FSD) is converted to normal cached I/O to the underlying FSD.

Further, if you wish to consider lower layers, disk controllers and disk drives also cache the information. We’ve found that the cost of forcing things to disk can be horribly expensive, particularly on “cheaper” hard drive devices.

On the flip side of this, network file systems can (and do) change caching policy based upon their own internal state. SMB, for example, will cache (or not) based upon oplock state. This becomes even more complicated when you begin to consider memory mapped files into the network file system mix as well (since there is no way to say “no caching” on a memory mapped file.)

But if you’re satisfied with merely addressing the “common case” you can treat paging I/O as non-cached. That’s good enough for an academic project or prototype project, for example. It only becomes more complicated if you are working on commercial products.

Tony
OSR

One thing, which is slightly orthogonal.

If you are on top of NTFS you will see paging IO for files on file objects
for which you have never see the create. So if (as most people do) you are
attaching the StreamHandle context during post create and then you look only
at paging writes you will be missing a bunch,

wrote in message news:xxxxx@ntfsd…
> I’m fairly new to FSD and I’m writing a file system driver to track
> writes. I’m using a StreamHandleContext (allocated PostCreate) to track
> filenames. During the PreWrite callback, I’m calling the following code.
>
> status = FltGetStreamHandleContext(pFltObjects->Instance,
> pFltObjects->FileObject, &pFileContext);
>
> if(NT_SUCCESS(status))
> {
> if (FlagOn(pCallbackData->Iopb->IrpFlags, IRP_PAGING_IO))
> {
> DBG_PRINT(DBG_TRACE_WRITE, (“Writing To: PAGEFILE [%wZ]\n”,
> &pFileContext->fileName));
> gpCacheDriverContext->writeCP++;
> }
> }
>
> In my traces I’m seeing a bunch of different filenames for the file
> context. Could someone explain to me why the file name is not always set
> to the pagefile - considering I’m predicated on the IRP_PAGING_IO flag?
>
> Thanks,
>
> Ben.
>
>

Thanks Rod. That’s exactly what’s happenniing. Any idea how to pick up the missing contexts/filenames and connect them with their corresponding file objects in the PreWrite?

Ben.

You can look into using stream context in addition to (or perhaps as opposed
to) stream handle contexts. Take a look at the Ctx sample in the WDK.

wrote in message news:xxxxx@ntfsd…
> Thanks Rod. That’s exactly what’s happenniing. Any idea how to pick up
> the missing contexts/filenames and connect them with their corresponding
> file objects in the PreWrite?
>
> Ben.
>
>