I’m working on minifilter driver. I’m interested in IOs to/from HDD with IRP_NOCACHE flag set on (I use this flag, because I’m not interested in IOs to/from cache manager).
Few days ago I noticed strange behaviour on one of my setups with Windows 2012R2, about which I want to ask you guys.
The scenario is:
Create empty file in cached directory with name file1.txt
xcopy file0.txt file1.txt /E /J /Y
Important is that /J parameter force xcopy to work in unbuffered mode.
File0.txt is existing file.
I observe requests which comes to file1.txt in step 2 of the scenario which I wrote and something weird happen:
Post IRP_MJ_CREATE callback comes with Data->Iopb-Parameters.Create.Options flag FILE_NO_INTERMEDIATE_BUFFERING (which looks correct, because we write in unbuffered mode to this file)
Pre IRP_MJ_WRITE callback comes with offset X and length Y with IRP_NOCACHE flag and buffer full of “valid” data (which also looks correct)
Post IRP_MJ_WRITE callback comes with Data->IoStatus.Status == STATUS_SUCCESS and Data->IoStatus.Information == Y (so it looks like this data was correctly written into HDD)
Pre IRP_MJ_WRITE callback comes with offset X and length Y/2 with IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO flags and buffer full of zeroes (for me this data doesn’t look correct)
Post IRP_MJ_WRITE callback comes with Data->IoStatus.Status == STATUS_SUCCESS and Data->IoStatus.Information == Y/2 (so it looks like this data was correctly written into HDD)
In next steps there?s no more writes (with IRP_NOCACHE flag) to area between offset X and length Y/2, but when I check file on HDD I have valid data in this area (so there?s no zeroes).
Buffer which I wrote about comes from Data->Iopb->Parameters.Write.Writebuffer or when it’s NULL from MmGetSystemAddressForMdlSafe(Data->Iopb->Parameters.Write.MdlAddress).
It looks for me like a strange behavior. I?m not sure if I understand correctly, but I thought that IRP_SYNCHRONOUS_PAGING_IO comes when OS flush data from Windows Cache, but here we use unbuffered mode, so there shouldn?t be any data in Windows Cache, if I understand correctly.
I also try to do similar operations but without /J parameter in xcopy. It that case during Post IRP_MJ_CREATE callback flag FILE_NO_INTERMEDIATE_BUFFERING is not set and pre IRP_MJ_WRITE callback with IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO contains “valid” data.
So it looks like this issue only happen when we use unbuffered mode in userspace.
So I want to ask you, if this is something normal or this case is more complicated (maybe I should check also more flags to be sure, etc.).
I also want to know how should I handle data like that, should I treat them as “valid” or not.
Do you still see the same thing (namely step 4) if you restart the machine
between creating the file and xcopy-ing it (so to make sure there is no
cached view of the file around) ? I’m wondering if the tool you’re using to
create the file initializes the cache for it so then what you’re seeing in
step 4 is some sort of coherency flush ?
Thanks,
Alex.
On Mon, Jul 14, 2014 at 6:39 AM, wrote:
> Hello. > > I’m working on minifilter driver. I’m interested in IOs to/from HDD with > IRP_NOCACHE flag set on (I use this flag, because I’m not interested in IOs > to/from cache manager). > > Few days ago I noticed strange behaviour on one of my setups with Windows > 2012R2, about which I want to ask you guys. > > The scenario is: > 1. Create empty file in cached directory with name file1.txt > 2. xcopy file0.txt file1.txt /E /J /Y > Important is that /J parameter force xcopy to work in unbuffered mode. > File0.txt is existing file. > > I observe requests which comes to file1.txt in step 2 of the scenario > which I wrote and something weird happen: > 1. Post IRP_MJ_CREATE callback comes with > Data->Iopb-Parameters.Create.Options flag FILE_NO_INTERMEDIATE_BUFFERING > (which looks correct, because we write in unbuffered mode to this file) > 2. Pre IRP_MJ_WRITE callback comes with offset X and length Y with > IRP_NOCACHE flag and buffer full of “valid” data (which also looks correct) > 3. Post IRP_MJ_WRITE callback comes with Data->IoStatus.Status == > STATUS_SUCCESS and Data->IoStatus.Information == Y (so it looks like this > data was correctly written into HDD) > 4. Pre IRP_MJ_WRITE callback comes with offset X and length Y/2 with > IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO flags and buffer full > of zeroes (for me this data doesn’t look correct) > 5. Post IRP_MJ_WRITE callback comes with Data->IoStatus.Status == > STATUS_SUCCESS and Data->IoStatus.Information == Y/2 (so it looks like this > data was correctly written into HDD) > In next steps there?s no more writes (with IRP_NOCACHE flag) to area > between offset X and length Y/2, but when I check file on HDD I have valid > data in this area (so there?s no zeroes). > > Buffer which I wrote about comes from > Data->Iopb->Parameters.Write.Writebuffer or when it’s NULL from > MmGetSystemAddressForMdlSafe(Data->Iopb->Parameters.Write.MdlAddress). > > It looks for me like a strange behavior. I?m not sure if I understand > correctly, but I thought that IRP_SYNCHRONOUS_PAGING_IO comes when OS flush > data from Windows Cache, but here we use unbuffered mode, so there > shouldn?t be any data in Windows Cache, if I understand correctly. > > I also try to do similar operations but without /J parameter in xcopy. It > that case during Post IRP_MJ_CREATE callback flag > FILE_NO_INTERMEDIATE_BUFFERING is not set and pre IRP_MJ_WRITE callback > with IRP_NOCACHE, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO contains “valid” > data. > So it looks like this issue only happen when we use unbuffered mode in > userspace. > > So I want to ask you, if this is something normal or this case is more > complicated (maybe I should check also more flags to be sure, etc.). > I also want to know how should I handle data like that, should I treat > them as “valid” or not. > > — > NTFSD is sponsored by OSR > > OSR is hiring!! Info at http://www.osr.com/careers > > 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 >
I didn’t try to restart machine between creating file and xcopy into this file. I tried to made some pause between this two steps.
When I made short pause (5 or 20 seconds) the issue was the same.
When I made longer pause (50 seconds) it looks like that issue was gone (there was no more writes with IRP_SYNCHRONOUS_PAGING_IO after create with FILE_NO_INTERMEDIATE_BUFFERING flag).