Minifilter -> disk filter

I am trying to communicate from a file system mini-filter to a disk filter driver. I have used minispy and diskperf as my starting point. The way I am trying to do it is to set IO priority on the FILE_OBJECT from the minifilter but it does not seem to be reflected in the disk filter when I issue IoGetIoPriority on the IRP coming into the readwrite entry point. Two questions:

  1. Is the priority on a file object supposed to be reflected at the IRP level?

  2. Is there a better way to set Io priority from the minifilter level which can survive the traversal down to the disk filter level?

regards,

dan

There is no guarantee that IO on a file on the file system will translate to
IO on a disk. If the file request gets satisfied from the cache, there might
be no IO to the disk at all.

What are you trying achieve by communicating between the two filters ? Is it
just a priority thing or are you using that as a tag for IO related to some
file ?

Thanks,
Alex.

just a priority thing. i’d like to know at the disk filter level that someone at the file system level wants to prioritize IRPs.

I was thinking of maybe building in a device interface in the disk filter driver which the file system minifilter driver could call. But, i ran into a problem where it appears I am not successfully parsing the IRP list in PFLT_IO_PARAMETER_BLOCK->TargetFileObject->IrpList

Should I be able to traverse the IRP list at the pre-IRP_MJ_READ entry point? It seems like my for loop just doesn’t execute at all, as if the list is empty.

Nope, you shouldn’t be able to get to the IRP from a minifilter at all.
That’s the model…

However, you can see the irp in the debugger !fltkd.cbd on the callbackdata.
Also, there are special routines for minifilters, FltGetIoPriorityHint,
FltGetIoPriorityHintFromCallbackData and friends…

Thanks,
Alex.

Actually you can call from a minifilter to a disk filter, I’ve done it
in several products. What you have to do is as part of the
FLT_INSTANCE_SETUP_CALLBACK use FltGetDiskDeviceObject to get the disk’s
DEVICE_OBJECT from the volume then call directly to it.

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

“Alex Carp” wrote in message
news:xxxxx@ntfsd:

> Nope, you shouldn’t be able to get to the IRP from a minifilter at all.
> That’s the model…
>
> However, you can see the irp in the debugger !fltkd.cbd on the callbackdata.
> Also, there are special routines for minifilters, FltGetIoPriorityHint,
> FltGetIoPriorityHintFromCallbackData and friends…
>
> Thanks,
> Alex.

will my disk filter driver get a chance to intercept any messages i send to the DiskDeviceObject? once i have the DiskDeviceObject do i just send IOCTLS and/or IRPs to it? I see I can use IoCallDriver to send IRPs, can these be user-defined IRPs? or is it better to call IoBuildDeviceIoControlRequest to build a custom IRP and send it?

my end goal is to communicate to the disk filter driver that an important IRP is coming. i have tried setting the priority for the file object in pre-read, but when i print out IRP priority from within the disk filter driver, i rarely see the effect. i am setting the priority to IoPriorityHigh from the minifilter and most of the time i see the priority for IRPs at the disk filter level are IoPriorityNormal. i have caught a couple of IoPriorityHigh IRPs so i think that sometimes i am getting thru but i don’t see the logic of when it succeeds or fails.

how can i send along some info with an IRP from the minifilter level so that it can be retrieved at the disk filter level? or, how can i send a message to the disk filter so that it can associate the info with the yet to be seen IRP? maybe this is not possible with minifilters? do i need to fall back to a legacy filter?

> how can i send along some info with an IRP from the minifilter level so that it can be retrieved at the

disk filter level?

Impossible, because there is no 1-to-1 relation of FSD IRPs and disk IRPs.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

so, does the Fltmgr api call FltSetIoPriorityHintIntoFileObject not modify the underlying IRP(s) behind a file read/write?

No, it doesn’t modify the IRP. It is just a thin wrapper over
nt!IoSetIoPriorityHintIntoFileObject, which sets the priority somewhere in
the FILE_OBJECT.

The function that sets the priority hint in the IRP is
FltSetIoPriorityHintIntoCallbackData. The CallbackData is the FltMgr
abstraction for the IRP and so FltMgr equivalents for IO functions that deal
with IRPs will have either the same name but a different prefix (Flt instead
of Io) or have the “CallbackData” string somewhere in the name if the IO
function dealt with irps.

Thanks,
Alex.

thanks alex. so would it be better to set this hint in post-create, pre-read, or somewhere else?

As I’ve said before, not every IRP sent to a file system results in an IRP
to the disk. For example, and IRP_MJ_READ request might be satisfied from
the cache, in which case actual “read” is nothing more than a memcpy into
the buffer supplied in IRP_MJ_READ, no IRP is ever sent to the disk. Now,
even if the IRP will actually require an IRP to be sent to the volume, it
might be quite a different IRP (for example, IRP_MJ_CREATE might require
that a directory entry is read from disk, nothing to do with the actual
on-disk representation of the file you’re trying to open). Nevertheless,
even if the file system IRP actually does translate into volume level file
IO, there still will be no 1-to-1 mapping since one IRP_MJ_WRITE request at
the file system level might need to be split if the blocks being written are
not contiguous on the volume. Even for those IRPs there may be volume level
filters that process them in some fashion (like encryption or maybe they
split each IO further to send it to multiple partitions). Then you might
also have a RAID driver of some sort. And then the disk might be a virtual
thing (I hesitate to call it a virtual disk since some solutions are in fact
just volumes), like a VHD or a TrueCrypt volume, which will result in even
more IO obfuscation…

In order to track the priority hint, all these layers must properly handle
and forward the IO hint in all these cases. And again, in very many (maybe
even in most) cases you won’t even see an IRP since things will hopefully be
cached.

In my opinion trying to match IO at the file system level to IO at the disk
level in the general case is going to be somewhere between unfeasible and
impossible.

Perhaps you could try to explain what you are trying to do instead of how.
Why are you trying to mark certain IOs at file system level as high priority
? Is this for high availability ? Performance ?

However, to answer your question, you should set this hint in the preOp
callback for the operation you’re interested in. Whether those operations
are IRP_MJ_CREATEs or IRP_MJ_READs I can’t tell for the reasons I mentioned
above. However, if you want to mark all IO for a file as high priority, you
might be better off just setting the hint for the FILE_OBJECT in postCreate
and then the IO mgr should set it on subsequent IRPs (at least I think so, I
haven’t actually ever looked at this feature).

Thanks,
Alex.

answered my own question by trying both. FltSetIoPriorityHintIntoCallbackData called from pre-read seems to change IRP priority as seen in the disk device filter. thanks a ton for the help. love your file systems blog by the way.

one more question, is this behavior guaranteed? what i mean is, is it possible for FltSetIoPriorityHintIntoCallbackData to get ignored and IRP priority hint remains unchanged from whatever it was before the call?

FltSetIoPriorityHintIntoCallbackData is just a wrapper over
IoSetIoPriorityHint. The call itself can fail in IoSetIoPriorityHint. If it
succeeds, then IO manager will not ignore it, but it is nevertheless a hint
so it is possible that some component of the system might chose to ignore
it. You’ll have to experiment I guess.

Thanks,
Alex.

ok, great. i know for sure that the hint does not make it thru msahci but that’s ok. thanks again.

msahci does get to know if a request is a high priority though - IsHighPriorityIrb (). Priority reaches the msahci (or any other ataport miniport) in the IRB but not to the hardware atleast int the current msahci. you can write your own miniport (if it is your controller) and make use of it.

yep, saw that when i went into the source. thanks.