sys: FspFileNodeFlushAndPurgeCache

This commit is contained in:
Bill Zissimopoulos 2016-03-17 10:13:52 -07:00
parent df85107c42
commit b734e6968d
6 changed files with 157 additions and 22 deletions

View File

@ -7,10 +7,12 @@
#include <sys/driver.h> #include <sys/driver.h>
DRIVER_INITIALIZE DriverEntry; DRIVER_INITIALIZE DriverEntry;
static VOID FspDriverMultiVersionInitialize(VOID);
DRIVER_UNLOAD FspUnload; DRIVER_UNLOAD FspUnload;
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(INIT, FspDriverMultiVersionInitialize)
#pragma alloc_text(PAGE, FspUnload) #pragma alloc_text(PAGE, FspUnload)
#endif #endif
@ -19,6 +21,8 @@ NTSTATUS DriverEntry(
{ {
FSP_ENTER(); FSP_ENTER();
FspDriverMultiVersionInitialize();
FspDriverObject = DriverObject; FspDriverObject = DriverObject;
/* create the file system control device objects */ /* create the file system control device objects */
@ -143,6 +147,18 @@ NTSTATUS DriverEntry(
&DriverObject->DriverName, RegistryPath); &DriverObject->DriverName, RegistryPath);
} }
static VOID FspDriverMultiVersionInitialize(VOID)
{
UNICODE_STRING Name;
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7))
{
RtlInitUnicodeString(&Name, L"CcCoherencyFlushAndPurgeCache");
FspMvCcCoherencyFlushAndPurgeCache =
(FSP_MV_CcCoherencyFlushAndPurgeCache *)(UINT_PTR)MmGetSystemRoutineAddress(&Name);
}
}
VOID FspUnload( VOID FspUnload(
PDRIVER_OBJECT DriverObject) PDRIVER_OBJECT DriverObject)
{ {
@ -164,3 +180,5 @@ PDEVICE_OBJECT FspFsctlDiskDeviceObject;
PDEVICE_OBJECT FspFsctlNetDeviceObject; PDEVICE_OBJECT FspFsctlNetDeviceObject;
FAST_IO_DISPATCH FspFastIoDispatch; FAST_IO_DISPATCH FspFastIoDispatch;
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks; CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;

View File

@ -835,6 +835,7 @@ VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait);
VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags);
BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait);
VOID FspFileNodeConvertExclusiveToSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags);
VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
@ -844,6 +845,8 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending); PBOOLEAN PDeletePending);
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject, BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING FileName, BOOLEAN SubpathOnly); PUNICODE_STRING FileName, BOOLEAN SubpathOnly);
@ -863,6 +866,7 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
#define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F, FALSE) #define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F, FALSE)
#define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F) #define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F)
#define FspFileNodeTryAcquireExclusive(N,F) FspFileNodeTryAcquireExclusiveF(N, FspFileNodeAcquire ## F, FALSE) #define FspFileNodeTryAcquireExclusive(N,F) FspFileNodeTryAcquireExclusiveF(N, FspFileNodeAcquire ## F, FALSE)
#define FspFileNodeConvertExclusiveToShared(N,F) FspFileNodeConvertExclusiveToSharedF(N, FspFileNodeAcquire ## F)
#define FspFileNodeSetOwner(N,F,P) FspFileNodeSetOwnerF(N, FspFileNodeAcquire ## F, P) #define FspFileNodeSetOwner(N,F,P) FspFileNodeSetOwnerF(N, FspFileNodeAcquire ## F, P)
#define FspFileNodeRelease(N,F) FspFileNodeReleaseF(N, FspFileNodeAcquire ## F) #define FspFileNodeRelease(N,F) FspFileNodeReleaseF(N, FspFileNodeAcquire ## F)
#define FspFileNodeReleaseOwner(N,F,P) FspFileNodeReleaseOwnerF(N, FspFileNodeAcquire ## F, P) #define FspFileNodeReleaseOwner(N,F,P) FspFileNodeReleaseOwnerF(N, FspFileNodeAcquire ## F, P)
@ -904,4 +908,17 @@ extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
/* multiversion support */
typedef
NTKERNELAPI
VOID
FSP_MV_CcCoherencyFlushAndPurgeCache(
_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer,
_In_opt_ PLARGE_INTEGER FileOffset,
_In_ ULONG Length,
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_opt_ ULONG Flags
);
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
#endif #endif

View File

@ -13,6 +13,7 @@ VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait);
VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags);
BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait);
VOID FspFileNodeConvertExclusiveToSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags);
VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
@ -22,6 +23,8 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending); PBOOLEAN PDeletePending);
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject, BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
PUNICODE_STRING FileName, BOOLEAN SubpathOnly); PUNICODE_STRING FileName, BOOLEAN SubpathOnly);
@ -45,6 +48,7 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
#pragma alloc_text(PAGE, FspFileNodeTryAcquireSharedF) #pragma alloc_text(PAGE, FspFileNodeTryAcquireSharedF)
#pragma alloc_text(PAGE, FspFileNodeAcquireExclusiveF) #pragma alloc_text(PAGE, FspFileNodeAcquireExclusiveF)
#pragma alloc_text(PAGE, FspFileNodeTryAcquireExclusiveF) #pragma alloc_text(PAGE, FspFileNodeTryAcquireExclusiveF)
#pragma alloc_text(PAGE, FspFileNodeConvertExclusiveToSharedF)
#pragma alloc_text(PAGE, FspFileNodeSetOwnerF) #pragma alloc_text(PAGE, FspFileNodeSetOwnerF)
#pragma alloc_text(PAGE, FspFileNodeReleaseF) #pragma alloc_text(PAGE, FspFileNodeReleaseF)
#pragma alloc_text(PAGE, FspFileNodeReleaseOwnerF) #pragma alloc_text(PAGE, FspFileNodeReleaseOwnerF)
@ -52,6 +56,7 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
#pragma alloc_text(PAGE, FspFileNodeCleanup) #pragma alloc_text(PAGE, FspFileNodeCleanup)
#pragma alloc_text(PAGE, FspFileNodeCleanupComplete) #pragma alloc_text(PAGE, FspFileNodeCleanupComplete)
#pragma alloc_text(PAGE, FspFileNodeClose) #pragma alloc_text(PAGE, FspFileNodeClose)
#pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache)
#pragma alloc_text(PAGE, FspFileNodeRename) #pragma alloc_text(PAGE, FspFileNodeRename)
#pragma alloc_text(PAGE, FspFileNodeHasOpenHandles) #pragma alloc_text(PAGE, FspFileNodeHasOpenHandles)
#pragma alloc_text(PAGE, FspFileNodeGetFileInfo) #pragma alloc_text(PAGE, FspFileNodeGetFileInfo)
@ -246,6 +251,19 @@ BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BO
return Result; return Result;
} }
VOID FspFileNodeConvertExclusiveToSharedF(FSP_FILE_NODE *FileNode, ULONG Flags)
{
PAGED_CODE();
FSP_FILE_NODE_GET_FLAGS();
if (Flags & FspFileNodeAcquirePgio)
ExConvertExclusiveToSharedLite(FileNode->Header.PagingIoResource);
if (Flags & FspFileNodeAcquireMain)
ExConvertExclusiveToSharedLite(FileNode->Header.Resource);
}
VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner) VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner)
{ {
PAGED_CODE(); PAGED_CODE();
@ -515,6 +533,54 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
FspFileNodeDereference(FileNode); FspFileNodeDereference(FileNode);
} }
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge)
{
/*
* The FileNode must be acquired exclusive (Full) when calling this function.
*/
PAGED_CODE();
LARGE_INTEGER FlushOffset;
PLARGE_INTEGER PFlushOffset = &FlushOffset;
FSP_FSCTL_FILE_INFO FileInfo;
IO_STATUS_BLOCK IoStatus = { 0 };
FlushOffset.QuadPart = FlushOffset64;
if (FILE_WRITE_TO_END_OF_FILE == FlushOffset.LowPart && -1L == FlushOffset.HighPart)
{
if (FspFileNodeTryGetFileInfo(FileNode, &FileInfo))
FlushOffset.QuadPart = FileInfo.FileSize;
else
PFlushOffset = 0; /* we don't know how big the file is, so flush it all! */
}
if (0 != FspMvCcCoherencyFlushAndPurgeCache)
{
/* if we are on Win7+ use CcCoherencyFlushAndPurgeCache */
FspMvCcCoherencyFlushAndPurgeCache(
&FileNode->NonPaged->SectionObjectPointers, PFlushOffset, FlushLength, &IoStatus,
FlushAndPurge ? 0 : CC_FLUSH_AND_PURGE_NO_PURGE);
return STATUS_CACHE_PAGE_LOCKED == IoStatus.Status ?
STATUS_SUCCESS/* liar! */:
IoStatus.Status;
}
else
{
/* do it the old-fashioned way; non-cached and mmap'ed I/O are non-coherent */
CcFlushCache(&FileNode->NonPaged->SectionObjectPointers, PFlushOffset, FlushLength, &IoStatus);
if (!NT_SUCCESS(IoStatus.Status))
return IoStatus.Status;
if (FlushAndPurge)
CcPurgeCacheSection(&FileNode->NonPaged->SectionObjectPointers, PFlushOffset, FlushLength, FALSE);
return STATUS_SUCCESS;
}
}
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName) VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
{ {
PAGED_CODE(); PAGED_CODE();

View File

@ -252,11 +252,19 @@ NTSTATUS FspFsvolReadPrepare(
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
FSP_SAFE_MDL *SafeMdl = 0; FSP_SAFE_MDL *SafeMdl = 0;
PVOID Address; PVOID Address;
PEPROCESS Process; PEPROCESS Process;
BOOLEAN FlushCache;
BOOLEAN Success; BOOLEAN Success;
FlushCache = !PagingIo && 0 != FileObject->SectionObjectPointer->DataSectionObject;
/* !!!: DataSectionObject accessed outside a lock. Hmmm! */
if (FlushCache)
Success = DEBUGTEST(90, TRUE) && FspFileNodeTryAcquireExclusive(FileNode, Full);
else
Success = DEBUGTEST(90, TRUE) && FspFileNodeTryAcquireShared(FileNode, Full); Success = DEBUGTEST(90, TRUE) && FspFileNodeTryAcquireShared(FileNode, Full);
if (!Success) if (!Success)
{ {
@ -264,6 +272,22 @@ NTSTATUS FspFsvolReadPrepare(
return Result; return Result;
} }
/* if this is a non-cached transfer on a cached file then flush the file */
if (FlushCache)
{
Result = FspFileNodeFlushAndPurgeCache(FileNode,
IrpSp->Parameters.Read.ByteOffset.QuadPart,
IrpSp->Parameters.Read.Length,
FALSE);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Full);
return Result;
}
FspFileNodeConvertExclusiveToShared(FileNode, Full);
}
/* create a "safe" MDL if necessary */ /* create a "safe" MDL if necessary */
if (!FspSafeMdlCheck(Irp->MdlAddress)) if (!FspSafeMdlCheck(Irp->MdlAddress))
{ {

View File

@ -335,28 +335,15 @@ NTSTATUS FspFsvolWritePrepare(
/* if this is a non-cached transfer on a cached file then flush and purge the file */ /* if this is a non-cached transfer on a cached file then flush and purge the file */
if (!PagingIo && 0 != FileObject->SectionObjectPointer->DataSectionObject) if (!PagingIo && 0 != FileObject->SectionObjectPointer->DataSectionObject)
{ {
LARGE_INTEGER FlushOffset = IrpSp->Parameters.Write.ByteOffset; Result = FspFileNodeFlushAndPurgeCache(FileNode,
PLARGE_INTEGER PFlushOffset = &FlushOffset; IrpSp->Parameters.Write.ByteOffset.QuadPart,
ULONG FlushLength = IrpSp->Parameters.Write.Length; IrpSp->Parameters.Write.Length,
FSP_FSCTL_FILE_INFO FileInfo; TRUE);
IO_STATUS_BLOCK IoStatus = { 0 }; if (!NT_SUCCESS(Result))
if (FILE_WRITE_TO_END_OF_FILE == FlushOffset.LowPart && -1L == FlushOffset.HighPart)
{
if (FspFileNodeTryGetFileInfo(FileNode, &FileInfo))
FlushOffset.QuadPart = FileInfo.FileSize;
else
PFlushOffset = 0; /* we don't know how big the file is, so flush it all! */
}
CcFlushCache(FileObject->SectionObjectPointer, PFlushOffset, FlushLength, &IoStatus);
if (!NT_SUCCESS(IoStatus.Status))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
return IoStatus.Status; return Result;
} }
CcPurgeCacheSection(FileObject->SectionObjectPointer, PFlushOffset, FlushLength, FALSE);
} }
/* create a "safe" MDL if necessary */ /* create a "safe" MDL if necessary */

View File

@ -2,6 +2,7 @@
#include <tlib/testsuite.h> #include <tlib/testsuite.h>
#include <strsafe.h> #include <strsafe.h>
#include <time.h> #include <time.h>
#include <VersionHelpers.h>
#include "memfs.h" #include "memfs.h"
void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout); void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout);
@ -710,16 +711,27 @@ void rdwr_mmap_test(void)
{ {
/* /*
* WinFsp does not currently provide coherency between mmap'ed I/O and ReadFile/WriteFile * WinFsp does not currently provide coherency between mmap'ed I/O and ReadFile/WriteFile
* in the following circumstances: * before Windows 7 in the following cases:
* - FileInfoTimeout != INFINITE * - FileInfoTimeout != INFINITE
* - CreateFlags & FILE_FLAG_NO_BUFFERING * - CreateFlags & FILE_FLAG_NO_BUFFERING
*
* In Windows 7 and above the new DDI CcCoherencyFlushAndPurgeCache allows us to provide
* coherency in those cases.
*/ */
if (IsWindows7OrGreater())
{
rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, 0, FALSE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, FILE_FLAG_NO_BUFFERING, FALSE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, FILE_FLAG_WRITE_THROUGH, FALSE);
}
rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, 0, TRUE); rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, 0, TRUE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, FILE_FLAG_NO_BUFFERING, TRUE); rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, FILE_FLAG_NO_BUFFERING, TRUE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, FILE_FLAG_WRITE_THROUGH, TRUE); rdwr_mmap_dotest(MemfsDisk, 0, 0, 1000, FILE_FLAG_WRITE_THROUGH, TRUE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, 0, FALSE); rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, 0, FALSE);
if (IsWindows7OrGreater())
rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, FILE_FLAG_NO_BUFFERING, FALSE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, FILE_FLAG_WRITE_THROUGH, FALSE); rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, FILE_FLAG_WRITE_THROUGH, FALSE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, 0, TRUE); rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, 0, TRUE);
rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, FILE_FLAG_NO_BUFFERING, TRUE); rdwr_mmap_dotest(MemfsDisk, 0, 0, INFINITE, FILE_FLAG_NO_BUFFERING, TRUE);
@ -729,16 +741,27 @@ void rdwr_mmap_test(void)
{ {
/* /*
* WinFsp does not currently provide coherency between mmap'ed I/O and ReadFile/WriteFile * WinFsp does not currently provide coherency between mmap'ed I/O and ReadFile/WriteFile
* in the following circumstances: * before Windows 7 in the following cases:
* - FileInfoTimeout != INFINITE * - FileInfoTimeout != INFINITE
* - CreateFlags & FILE_FLAG_NO_BUFFERING * - CreateFlags & FILE_FLAG_NO_BUFFERING
*
* In Windows 7 and above the new DDI CcCoherencyFlushAndPurgeCache allows us to provide
* coherency in those cases.
*/ */
if (IsWindows7OrGreater())
{
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, 0, FALSE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, FILE_FLAG_NO_BUFFERING, FALSE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, FILE_FLAG_WRITE_THROUGH, FALSE);
}
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, 0, TRUE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, 0, TRUE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, FILE_FLAG_NO_BUFFERING, TRUE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, FILE_FLAG_NO_BUFFERING, TRUE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, FILE_FLAG_WRITE_THROUGH, TRUE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", 1000, FILE_FLAG_WRITE_THROUGH, TRUE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, 0, FALSE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, 0, FALSE);
if (IsWindows7OrGreater())
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, FILE_FLAG_NO_BUFFERING, FALSE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, FILE_FLAG_WRITE_THROUGH, FALSE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, FILE_FLAG_WRITE_THROUGH, FALSE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, 0, TRUE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, 0, TRUE);
rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, FILE_FLAG_NO_BUFFERING, TRUE); rdwr_mmap_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share", INFINITE, FILE_FLAG_NO_BUFFERING, TRUE);