Querying last USN for the file on NTFS volume from a filter driver

Hello,

I wanted to query the last USN for the file on the NTFS volume from my file system filter driver’s PostOpCreate routine.

I figured that using FltFsControlFile with FSCTL_READ_FILE_USN_DATA iocontrol provides me the desired information. However, I was wondering about couple of points.

  1. What is the performance overhead of making FSCTL_READ_FILE_USN_DATA? I presume that the data returned as part of the call is directly coming from the MFT and hence doesn’t require reading through the change journal at all and hence I expect it to be faster/
  2. Is there any simpler call like FltQueryInformationFile which provides me this information? I only care about usn field from USN_RECORD structure.

Thanks.
-Prasad

On 01/27/2012 03:35 AM, xxxxx@vmware.com wrote:

  1. What is the performance overhead of making FSCTL_READ_FILE_USN_DATA? I presume that the data returned as part of the call is directly coming from the MFT and hence doesn’t require reading through the change journal at all and hence I expect it to be faster/
    Yes, the data is coming from the MFT. If the file has been accessed
    recently this should be cached and the call should be fast. Note that
    the USN provided is the USN of the most recent close record, not the
    most recent record.
  2. Is there any simpler call like FltQueryInformationFile which provides me this information? I only care about usn field from USN_RECORD structure.
    No.
  • M

Hello,

I had a follow-up question on this one.

I was able to query the USN record using FltFsControlFile with FSCTL_READ_FILE_USN_DATA. However, I noticed, that, if the USN journal is not active (which is default on NTFS), the API call still succeeds and USN_RECORD.Usn is zero in this case.

Based on some other reading, it seems that USN is just an offset into an internal journal file maintained by NTFS and hence USN_RECORD.Usn=0 can potentially be a genuine USN record.

Hence, there is needs to be a way to distinguish between USN=0 vs. journal not active case. I came across FSCTL_QUERY_USN_JOURNAL which is supposed to return me STATUS_JOURNAL_NOT_ACTIVE when journal is not active. However, I find that many times this API returns STATUS_ACCESS_DENIED instead of STATUS_JOURNAL_NOT_ACTIVE. Any thoughts on this? I am calling the API as follows

USN_JOURNAL_DATA usnJournalData;

ns = FltFsControlFile(fltObjects->Instance,
fltObjects->FileObject,
FSCTL_QUERY_USN_JOURNAL,
NULL,
0,
&usnJournalData,
sizeof(usnJournalData),
&bytesRet);

Thanks.
-Prasad

I don’t know, I use IoGetRelatedDeviceObject+IoBuildDeviceIoControlRequest
on volume’s FO (instead of FltFs- API). Maybe you should stop when you get
STATUS_ACCESS_DENIED and examine why it failed. Instead of those two status
code, you can also get STATUS_JOURNAL_DELETE_IN_PROGRESS error code. In this
case, call FSCTL_DELETE_USN_JOURNAL with USN_DELETE_FLAG_NOTIFY and query
USN again.

Petr

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@vmware.com
Sent: Monday, February 13, 2012 9:23 AM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] Querying last USN for the file on NTFS volume from a
filter driver

Hello,

I had a follow-up question on this one.

I was able to query the USN record using FltFsControlFile with
FSCTL_READ_FILE_USN_DATA. However, I noticed, that, if the USN journal is
not active (which is default on NTFS), the API call still succeeds and
USN_RECORD.Usn is zero in this case.

Based on some other reading, it seems that USN is just an offset into an
internal journal file maintained by NTFS and hence USN_RECORD.Usn=0 can
potentially be a genuine USN record.

Hence, there is needs to be a way to distinguish between USN=0 vs. journal
not active case. I came across FSCTL_QUERY_USN_JOURNAL which is supposed to
return me STATUS_JOURNAL_NOT_ACTIVE when journal is not active. However, I
find that many times this API returns STATUS_ACCESS_DENIED instead of
STATUS_JOURNAL_NOT_ACTIVE. Any thoughts on this? I am calling the API as
follows

USN_JOURNAL_DATA usnJournalData;

ns = FltFsControlFile(fltObjects->Instance,
fltObjects->FileObject,
FSCTL_QUERY_USN_JOURNAL,
NULL,
0,
&usnJournalData,
sizeof(usnJournalData),
&bytesRet);

Thanks.
-Prasad


NTFSD is sponsored by OSR

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thanks Petr for your quick response.

By “examine why it failed”, you mean tracing throgh the io control request end-to-end? I am getting back the error code ns=STATUS_ACCESS_DENIED. I have seen that for the same file, sometimes I get STATUS_ACCESS_DENIED and sometimes STATUS_JOURNAL_NOT_ACTIVE which is wierd.

I will try using IoGetRelatedDeviceObject+IoBuildDeviceIoControlRequest with FSCTL_QUERY_USN_JOURNAL and see if it helps.

For querying the USN, I can continue to use FltFsControlFile with FSCTL_READ_FILE_USN_DATA right?

Thanks.
-Prasad

When are you making this FltFsControlFile call ? In what context ? Also, how do you open the handle on which you issue the request ?

Thanks,
Alex.

I am calling this from PreOpCleanup and PostOpCreate using fltObjects->Instance and fltObjects->FileObject as first two parameters to FltFsControlFile.

fltObjects is PCFLT_RELATED_OBJECTS that is passed to PreOpCleanup and PostOpCreate.

Thanks.
-Prasad

Well, as far as I know FSCTL_QUERY_USN_JOURNAL requires a volume handle, so calling in on the FILE_OBJECT that happens to be in FltObjects->FileObject will occasionally work (when the FILE_OBJECT is a volume handle) but it will mostly fail (when it’s not a volume handle).

My advice would be to do the FSCTL_QUERY_USN_JOURNAL query early on (instance setup or immediately after that) and cache the result (in an instance context for example) instead of checking in preCleanup.

If you intend to use IoGetRelatedDeviceObject+IoBuildDeviceIoControlRequest make sure you do so on a FILE_OBJECT that you have opened yourself via FltCreateFile otherwise the layering will be broken.

Thanks,
Alex.

You might also look at FSCTL_WRITE_USN_CLOSE_RECORD. This forces a usn to be generated if the journal is active. It does not require a volume handle. In general, you should only be doing this with your files so it depends on the application.

Eventhough not kernel mode, this is the best article i have seen about USN
Journal related problems (with sample code included)

http://technet.microsoft.com/en-us/library/bb742450.aspx

Hope it helps,

-Emre TINAZTEPE

On Tue, Feb 21, 2012 at 12:09 AM, wrote:

> You might also look at FSCTL_WRITE_USN_CLOSE_RECORD. This forces a usn to
> be generated if the journal is active. It does not require a volume
> handle. In general, you should only be doing this with your files so it
> depends on the application.
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>