mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
sys: FspFileNodeFlushAndPurgeCache
This commit is contained in:
parent
df85107c42
commit
b734e6968d
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user