I am creating a file system driver which is similar to fastfat in WDK smaples.
And I got problem when I doing following test, and data is corrupted.
I did some search in this forum, but I cannot find a explanation why following issue happens.
Have anyone seen similar problem or has any idea how it happened?
Really appreciate it!!!
#########################
Test Description
- Create new file map.txt
- Write 512 bytes (Memory is filled with ‘A’, cache write)
- Write Another 512 bytes (Memory is filled with ‘A’) (file size should be 1024, cache write)
- Close file
- Open the file again
- Map the file (CreateFileMapping) with size 2048
CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 2048, NULL); - Set memory with ‘B’ from 1024 to 2048.
- Unmap
- Close file
PROBLEMS:
In step 6, a IRP_MJ_SET_INFORMATION request is sent to extend EOF from 1024 to 2048.
In this request, our FSD call CcSetFileSize to update file size in cache (I notice there is a CcPurgeCacheSection after FSD call CcSetFileSize), and this cause a page fault, and a paging read is issued.
The problem is that there is no paging write before this — ValidDataLength is 1024 because of previous cache write, but ValidDataToDisk is 0 because there is no paging write yet, so the first 1024 bytes (two 512 bytes write) data get lost because fsd cannot read it from disk.
At last, the paging write comes, but FSD already lost the first 1024 bytes, and data corruption happens.
(If test on normal file system, e.g. ntfs, there is no such paging read)
#########################
ProcMon Info
Test on normal file (Without our FSD) - C:\TestData\map.txt
FASTIO_NETWORK_QUERY_OPEN - FAST IO DISALLOWED
IRP_MJ_CREATE - NAME NOT FOUND
Desired Access: Read Attributes
Disposition: Open
Options: Open Reparse Point
Attributes: n/a
ShareMode: Read, Write, Delete
AllocationSize: n/a
IRP_MJ_CREATE ? SUCCESS
Desired Access: Generic Write, Read Attributes
Disposition: OverwriteIf
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: None
AllocationSize: 0
OpenResult: Created
IRP_MJ_WRITE ? SUCCESS
Offset: 0, Length: 512, Priority: Normal
FASTIO_WRITE ? FAST IO DISALLOWED
Offset: 512, Length: 512
IRP_MJ_WRITE ? SUCCESS
Offset: 512, Length: 512, Priority: Normal
FASTIO_MDL_WRITE_COMPLETE ? SUCCESS
Offset: 0, MDL: 0xfffffa8002ff7f40
FASTIO_MDL_READ_COMPLETE ? SUCCESS
MDL: 0xfffffa8003154e90
IRP_MJ_CLEANUP ? SUCCESS
IRP_MJ_CLOSE ? SUCCESS
IRP_MJ_CREATE ? SUCCESS
Desired Access: Generic Read/Write
Disposition: OpenIf
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: None
AllocationSize: 0
OpenResult: Opened
FASTIO_ACQUIRE_FOR_SECTION_SYNCHRONIZATION ? FILE LOCKED WITH WRITERS
SyncType: SyncTypeCreateSection, PageProtection:
FASTIO_QUERY_INFORMATION ? SUCCESS
Type: QueryStandardInformationFile
AllocationSize: 4,096
EndOfFile: 1,024
NumberOfLinks: 1
DeletePending: False
Directory: False
FASTIO_RELEASE_FOR_SECTION_SYNCHRONIZATION ? SUCCESS
FASTIO_QUERY_INFORMATION ? SUCCESS
Type: QueryStandardInformationFile
AllocationSize: 4,096
EndOfFile: 1,024
NumberOfLinks: 1
DeletePending: False
Directory: False
IRP_MJ_SET_INFORMATION ? SUCCESS
Type: SetEndOfFileInformationFile, EndOfFile: 2,048
FASTIO_ACQUIRE_FOR_SECTION_SYNCHRONIZATION ? SUCCESS
SyncType: SyncTypeOther
FASTIO_RELEASE_FOR_SECTION_SYNCHRONIZATION - SUCCESS
FASTIO_ACQUIRE_FOR_CC_FLUSH SUCCESS
IRP_MJ_WRITE ? SUCCESS
Offset: 0
Length: 4,096
I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O
Priority: Normal
FASTIO_RELEASE_FOR_CC_FLUSH SUCCESS
IRP_MJ_CLEANUP ? SUCCESS
IRP_MJ_CLOSE ? SUCCESS
#########################
ProcMon Info
Test file on shadow volume (with our FSD) - \Device\HarddiskShadowVolume2\TestData\map.txt
FASTIO_NETWORK_QUERY_OPEN - FAST IO DISALLOWED
IRP_MJ_CREATE - NAME NOT FOUND
Desired Access: Read Attributes
Disposition: Open
Options: Open Reparse Point
Attributes: n/a
ShareMode: Read, Write, Delete
AllocationSize: n/a
IRP_MJ_CREATE ? SUCCESS
Desired Access: Generic Write, Read Attributes
Disposition: OverwriteIf
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: None
AllocationSize: 0
OpenResult: Created
IRP_MJ_WRITE ? SUCCESS
Offset: 0, Length: 512, Priority: Normal
FASTIO_WRITE ? SUCCESS
Offset: 512, Length: 512
IRP_MJ_CLEANUP? SUCCESS
IRP_MJ_CREATE ? SUCCESS
Desired Access: Generic Read/Write
Disposition: OpenIf
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: None
AllocationSize: 0
OpenResult: Opened
FASTIO_ACQUIRE_FOR_SECTION_SYNCHRONIZATION ? SUCCESS
SyncType: SyncTypeCreateSection, PageProtection:
FASTIO_QUERY_INFORMATION ? SUCCESS
Type: QueryStandardInformationFile
AllocationSize: 4,096
EndOfFile: 1,024
NumberOfLinks: 1
DeletePending: False, Directory: False
FASTIO_RELEASE_FOR_SECTION_SYNCHRONIZATION ? SUCCESS
FASTIO_QUERY_INFORMATION ? SUCCESS
Type: QueryStandardInformationFile
AllocationSize: 4,096
EndOfFile: 1,024
NumberOfLinks: 1
DeletePending: False
Directory: False
IRP_MJ_SET_INFORMATION ? SUCCESS
Type: SetEndOfFileInformationFile, EndOfFile: 2,048
FASTIO_ACQUIRE_FOR_SECTION_SYNCHRONIZATION ? SUCCESS
SyncType: SyncTypeOther
FASTIO_RELEASE_FOR_SECTION_SYNCHRONIZATION ? SUCCESS
IRP_MJ_READ ? SUCCESS
Offset: 0
Length: 2,048
I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O
Priority: Normal
FASTIO_ACQUIRE_FOR_CC_FLUSH ? SUCCESS
IRP_MJ_WRITE ? SUCCESS
Offset: 0
Length: 4,096
I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O
Priority: Normal
FASTIO_RELEASE_FOR_CC_FLUSH ? SUCCESS
IRP_MJ_CLEANUP ? SUCCESS
IRP_MJ_CLOSE ? SUCCESS