confused_ddk
驱动牛犊
驱动牛犊
  • 注册日期2009-04-16
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望221点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4890回复:4

这大概就是double fcbs吧

楼主#
更多 发布于:2009-07-13 19:36
copy from OSR list, copyrights belong to author.

Once again, we've come across one of those complex situations where
trying to use file objects within a filter (or layered file system - the
difference is pretty much semantic) is creating problems.  In thinking
about this issue, I've concluded that I can do at least one thing to
identify this class of problem and suggest how filters can ensure they
"play nice" in such situations.

We've used the term "shadow file object" for at least the past dozen
years (ever since the first time we used it to build a filter that
allowed dismounting an NTFS file system while it was still active.  By
the way, that's one way to ensure you can flush the NTFS cache because
the on-disk state has changed.  I don't recommend it for the faint of
heart, but for that specific customer it provided the functionality they
required so they could share NTFS disks between multiple machines
simultaneously.)  I'll use that terminology now, and I hear folks in
Redmond using it as well.

In a "shadow file object" model the filter/layered-FSD obtains the
original I/O Manager created file object in its IRP_MJ_CREATE dispatch
handler.  It creates a second file object and sends that second file
object down to the underlying FSD.  The first file object then points to
the filter/layered-FSD device.  This gives the filter the ability to do
several things:

- Control the FsContext/FsContext2 fields.  After all, the file object
now belongs to the filter/layered-FSD.
- Control the cache.  We can set up the SOP structures to point to
things we (in the filter/layered-FSD) control.  Indeed, it is this "we
can control the cache" that leads to the very idea of thinking of this
as more a layered FSD than a filter.  The mechanics are mostly the same.
- Point to our control device.  This is actually where a filter splits
from a layered FSD.  When we first started doing this, we did it in a
filter model.  We ran into interesting issues with the DeviceObject and
Vpb fields of the file object.  These point to the FSD, not to the
filter.   There is no OS supported way to change these in a safe
fashion, and changing these pointers around to point to the "right
place" requires adjusting reference counts (and not adjusting reference
counts leads to other nasty problems.)  That's why we now use
STATUS_REPARSE - it's the only documented way to get the I/O Manager to
point to the right device (although it means filters above us see
STATUS_REPARSE all the time and some don't like that, although it's
really no different than what one can see on a server with SIS
installed.)

The # 1 problem we've had over the years is that, try as we might,
people will send our file objects (the one that points to our
filter/layered-FSD) to NTFS.  NTFS will blow up in a function called
NtfsDecodeFileObject.  The usual proof here is that when I look at the
device object in the IRP, it's NTFS and when I look at the device object
in the file object, it's our filter/layered-FSD.  Naturally, it MUST be
our fault (although we didn't write the code to send the file object to
the wrong file system - and there's not much we can DO to "fix that."
At least not much I'm willing to put in a commercial product.)

Of course, if you use just our filter/layered-FSD it works fine.  If you
use just the other filter, it works fine. Only when you combine the two
does it not work properly.

The issue here is "how do I obtain the right target for my request in a
file system filter driver".  The correct function to use is
IoGetRelatedDeviceObject - it takes the file object in question.  If the
filter/layered-FSD has done its job right, the file object is set up
properly.  It might not have a Vpb (ah, but SR will dereference the Vpb
anyway, as we found out on XP.)  Some OS components insist that it point
to the media volume (e.g., Win32k.sys in Vista will do this for the
keyboard DLL.  Nothing like having a system crash during boot all
because someone decided that what they got back MUST point to exactly
the device they started with in the first place.)
IoGetRelatedDeviceObject does this translation right.  It's not horribly
expensive (it's just following pointers.)

So, my admonishment to filter driver writers: don't traverse the FO
pointers directly.   In the case I looked at this morning, it appears
they followed FO->DeviceObject->Vpb->DeviceObject.  That won't work if
the volume has been formatted and/or dismounted, since FO->Vpb won't be
FO->DeviceObject->Vpb.  It's a lurking bug in that filter anyway, but
one they probably won't see very often.  Of course, since we cause this
situation to arise "all the time" the system blows up.

Use IoGetRelatedDeviceObject.

My second suggestion is to those writing file system drivers - rather
than blindly assume the components above you are "doing the right
thing", when you decode a file object, make sure it points to the right
device object.  If it doesn't, you can return an error.

This isn't so hard - we get two arguments in the create entry point and
all of us go through some variation of "NtfsDecodeFileObject".  Just add
a check to make sure it points to the device object we were passed.
ONLY file systems can do this.  Filters cannot, since this check will
only work for the "owner" of the file object.  But if FO->DeviceObject
!= DeviceObject (from the passed in parameter) something's broken.  You
can bug check (but could make it obvious) or you can return an error
(I'm a proponent of the error path, but that's because when I bug check,
I field the support call.)  Maybe this can be turned into a verifier
check, or perhaps it belongs in the checked build or something, but I
stumble across this frequently enough I know that it's still a common
issue.

Shadow file objects are very powerful, particularly when you want to
control the presentation of data in a layered approach.  However, using
them turns out to be much more complicated than anyone first approaching
the field would believe.  While I'm a proponent of the STATUS_REPARSE
technique of adjusting reference counts, I know there are some who would
prefer if we did it a different way (although I've yet to see one that
works robustly - although it's often easy to make them work in isolation
and with limited testing.)

Oh, and just wait until you learn how much fun shadow file objects are
when you combine them with transactions.

I'll get down off the soapbox now.

Tony
OSR

最新喜欢:

tc891122tc8911...
confused_ddk
驱动牛犊
驱动牛犊
  • 注册日期2009-04-16
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望221点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-07-13 19:51
I prefer the layered file system approach.  I've done this four times
now.  The first time was a filter that used shadow file objects and it
turned out to be amazingly complicated because no matter what we did, we
found other components would pass our file objects to the native file
system - which then died.   The second time we did this, we tried to do
it by "taking over" the symbolic link for the drive, pointing to our
separate file system and then talking to the native file system.  That
solved the "but my file object goes to the wrong place" issue but made a
number of things MUCH more complicated (like files we didn't want to
track.)  The third time, we did it JUST for NTFS with ADS; that approach
worked very well.  The fourth time is our toolkit - it uses a filter to
redirect to a separate stack (so we have a layered file system) the
files of interest.  We use shadow file objects and we implement in the
file structure a log-structure so that we can add the ADS abstraction
independent of what the underlying FSD actually supports.
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
板凳#
发布于:2009-07-13 22:14
Tony was actually talking about a real layered file system, OSR's DMK.
confused_ddk
驱动牛犊
驱动牛犊
  • 注册日期2009-04-16
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望221点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-07-15 10:13
I see, I see the price also.....
fazwh
驱动牛犊
驱动牛犊
  • 注册日期2005-09-11
  • 最后登录2020-11-18
  • 粉丝0
  • 关注0
  • 积分32分
  • 威望303点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2009-07-16 11:13
学习学习。顶起。。。
游客

返回顶部