Best FLUSH method?

In my FS filter driver, I want to cause a cache flush for a file before its
CLEANUP processing proceeds. Right now, I intercept the IRP_MJ_CLEANUP IRP
before it gets to the filesystem, and I use the IRP to send an
IRP_MJ_FLUSH_BUFFERS command further down the stack, and wait for its
completion. Then I proceed to pass the IRP_MJ_CLEANUP request on to the
next layer of the stack.

Sometimes, during heavy file create activity, I see a deadlock which seems
to be somewhere in NTFS, with one thread owning a lock shared, one or more
exclusive waiters on the same lock, and several other threads waiting for
shared access to the lock (must have come in after the exclusive waiter).

A clue is that many of the shared waiters threads’ stacks show a call to
NtfsAcquireSharedVcb(), and the exclusive waiters’ stacks show a call to
NtfsAcquireExclusiveVcb().

I’ve changed the flush code to call CcFlushCache() directly instead of
submitting the IRP to do it. So far, I have not seen the same deadlock.
That’s strange, since NTFS calls CcFlushCache() itself in the course of
processing the IRP_MJ_FLUSH_BUFFERS. Does anyone have a clue what might be
the difference in the two methods of flushing?

Carl Appellof


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

We use CcFlushCache. However there is a locking problem we had a lot of problem with. There are two locks, pFsContext->Resource and FsContext->PagingIoResource. NTFS gets on first, and then the other; FAT gets the other first, and then the one (I don’t recal which order) but we want them both before the flush. So what I’ve done is try to get one without waiting. If this works, I try to get the other without waiting. If I have them both, I carry on. If I didn’t, I free everything I did get, wait 20mS and then try again.

I then have a try block in which I call IoSetTopLevelIrp if the current one is NULL, check if the flush is OK through MmCanFileBeTruncated (this will fa il if anyone has a memory map on the file) then call CcFlushCache and CcPurgeCacheSection.

The finally block frees the locks and restores the top-level IRP to its previous state if it was changed.

This whole shebang was carried out inside a critical section.

And I bet Molly is screaming to herself about this POLLING for locks by now… I’ll admit it’s dirty, but it seems to work!

Andy.

-----Original Message-----
From: xxxxx@veritas.com [mailto:xxxxx@veritas.com]
Sent: 24 October 2001 16:55
To: File Systems Developers
Subject: [ntfsd] Best FLUSH method?

In my FS filter driver, I want to cause a cache flush for a file before its
CLEANUP processing proceeds. Right now, I intercept the IRP_MJ_CLEANUP IRP
before it gets to the filesystem, and I use the IRP to send an
IRP_MJ_FLUSH_BUFFERS command further down the stack, and wait for its
completion. Then I proceed to pass the IRP_MJ_CLEANUP request on to the
next layer of the stack.

Sometimes, during heavy file create activity, I see a deadlock which seems
to be somewhere in NTFS, with one thread owning a lock shared, one or more
exclusive waiters on the same lock, and several other threads waiting for
shared access to the lock (must have come in after the exclusive waiter).

A clue is that many of the shared waiters threads’ stacks show a call to
NtfsAcquireSharedVcb(), and the exclusive waiters’ stacks show a call to
NtfsAcquireExclusiveVcb().

I’ve changed the flush code to call CcFlushCache() directly instead of
submitting the IRP to do it. So far, I have not seen the same deadlock.
That’s strange, since NTFS calls CcFlushCache() itself in the course of
processing the IRP_MJ_FLUSH_BUFFERS. Does anyone have a clue what might be
the difference in the two methods of flushing?

Carl Appellof



FREE Personalized E-mail at Mail.com

http://www.mail.com/?sr=signup

Talk More, Pay Less with Net2Phone Direct(R), up to 1500 minutes free!

http://www.net2phone.com/cgi-bin/link.cgi?143


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com