mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-25 18:02:24 -05:00
sys: FspFileNodeCleanupFlush:
- CcFlushCache now happens during initial Cleanup call - avoids recursive call into file system during Cleanup completion
This commit is contained in:
parent
157c4bc09a
commit
c2f87029d7
@ -123,6 +123,8 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
|
||||||
|
FspFileNodeCleanupFlush(FileNode, FileObject);
|
||||||
|
|
||||||
if (Request->Req.Cleanup.Delete ||
|
if (Request->Req.Cleanup.Delete ||
|
||||||
Request->Req.Cleanup.SetAllocationSize ||
|
Request->Req.Cleanup.SetAllocationSize ||
|
||||||
Request->Req.Cleanup.SetArchiveBit ||
|
Request->Req.Cleanup.SetArchiveBit ||
|
||||||
@ -228,10 +230,9 @@ static VOID FspFsvolCleanupRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Co
|
|||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
FspFileNodeCleanupComplete(FileNode, FileObject);
|
|
||||||
|
|
||||||
FspFileNodeReleaseOwner(FileNode, Pgio, Request);
|
FspFileNodeReleaseOwner(FileNode, Pgio, Request);
|
||||||
|
|
||||||
|
FspFileNodeCleanupComplete(FileNode, FileObject);
|
||||||
if (!FileNode->IsDirectory)
|
if (!FileNode->IsDirectory)
|
||||||
FspFileNodeOplockCheck(FileNode, Irp);
|
FspFileNodeOplockCheck(FileNode, Irp);
|
||||||
SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
|
SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
|
||||||
|
@ -1358,6 +1358,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
UINT32 GrantedAccess, UINT32 ShareAccess,
|
UINT32 GrantedAccess, UINT32 ShareAccess,
|
||||||
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
|
||||||
|
VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
||||||
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
||||||
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
||||||
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
||||||
|
@ -37,6 +37,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
UINT32 GrantedAccess, UINT32 ShareAccess,
|
UINT32 GrantedAccess, UINT32 ShareAccess,
|
||||||
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
|
||||||
|
VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
||||||
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
||||||
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
||||||
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
||||||
@ -121,6 +122,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
|||||||
#pragma alloc_text(PAGE, FspFileNodeReleaseOwnerF)
|
#pragma alloc_text(PAGE, FspFileNodeReleaseOwnerF)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeOpen)
|
#pragma alloc_text(PAGE, FspFileNodeOpen)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeCleanup)
|
#pragma alloc_text(PAGE, FspFileNodeCleanup)
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeCleanupFlush)
|
||||||
#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, FspFileNodeFlushAndPurgeCache)
|
||||||
@ -772,6 +774,59 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG
|
|||||||
*PCleanupFlags = SingleHandle ? DeletePending | (SetAllocationSize << 1) : 0;
|
*PCleanupFlags = SingleHandle ? DeletePending | (SetAllocationSize << 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Optionally flush the FileNode during Cleanup.
|
||||||
|
*
|
||||||
|
* The FileNode must be acquired exclusive (Full) when calling this function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
|
||||||
|
if (!FsvolDeviceExtension->VolumeParams.FlushAndPurgeOnCleanup)
|
||||||
|
return; /* nothing to do! */
|
||||||
|
|
||||||
|
BOOLEAN DeletePending, SingleHandle;
|
||||||
|
LARGE_INTEGER TruncateSize, *PTruncateSize = 0;
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
DeletePending = 0 != FileNode->DeletePending;
|
||||||
|
MemoryBarrier();
|
||||||
|
|
||||||
|
SingleHandle = 1 == FileNode->HandleCount;
|
||||||
|
|
||||||
|
if (SingleHandle && FileNode->TruncateOnClose)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Even when the FileInfo is expired, this is the best guess for a file size
|
||||||
|
* without asking the user-mode file system.
|
||||||
|
*/
|
||||||
|
TruncateSize = FileNode->Header.FileSize;
|
||||||
|
PTruncateSize = &TruncateSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
/* Flush and purge on last Cleanup. Keeps files off the "standby" list. (GitHub issue #104) */
|
||||||
|
if (SingleHandle && !DeletePending)
|
||||||
|
{
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
LARGE_INTEGER ZeroOffset = { 0 };
|
||||||
|
|
||||||
|
if (0 != PTruncateSize && 0 == PTruncateSize->HighPart)
|
||||||
|
FspCcFlushCache(FileObject->SectionObjectPointer, &ZeroOffset, PTruncateSize->LowPart,
|
||||||
|
&IoStatus);
|
||||||
|
else
|
||||||
|
FspCcFlushCache(FileObject->SectionObjectPointer, 0, 0,
|
||||||
|
&IoStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
|
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -791,7 +846,7 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
|
|||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
LARGE_INTEGER TruncateSize, *PTruncateSize = 0;
|
LARGE_INTEGER TruncateSize, *PTruncateSize = 0;
|
||||||
BOOLEAN DeletePending = FALSE, DeletedFromContextTable = FALSE, SingleHandle = FALSE;
|
BOOLEAN DeletePending, DeletedFromContextTable = FALSE, SingleHandle = FALSE;
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
@ -915,22 +970,8 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
|
|||||||
* So we deem this difference in behavior ok and desirable.
|
* So we deem this difference in behavior ok and desirable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!DeletePending)
|
TruncateSize.QuadPart = 0;
|
||||||
{
|
PTruncateSize = &TruncateSize;
|
||||||
/* NOTE: Do not use FspFileNodeFlushAndPurgeCache. It does not work well in CLEANUP! */
|
|
||||||
|
|
||||||
IO_STATUS_BLOCK IoStatus;
|
|
||||||
LARGE_INTEGER ZeroOffset = { 0 };
|
|
||||||
|
|
||||||
if (0 != PTruncateSize && 0 == PTruncateSize->HighPart)
|
|
||||||
FspCcFlushCache(FileObject->SectionObjectPointer, &ZeroOffset, PTruncateSize->LowPart,
|
|
||||||
&IoStatus);
|
|
||||||
else
|
|
||||||
FspCcFlushCache(FileObject->SectionObjectPointer, 0, 0,
|
|
||||||
&IoStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
CcPurgeCacheSection(FileObject->SectionObjectPointer, 0, 0, TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CcUninitializeCacheMap(FileObject, PTruncateSize, 0);
|
CcUninitializeCacheMap(FileObject, PTruncateSize, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user