From aed134080c60d6c4b823bd8de2296742197e481a Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 21 Sep 2016 14:22:08 -0700 Subject: [PATCH] inc: fsctl: PostCleanupOnDeleteOnly --- inc/winfsp/fsctl.h | 4 +++- inc/winfsp/winfsp.h | 4 ++++ src/dll/fuse/fuse.c | 1 + src/sys/cleanup.c | 26 ++++++++++++++++---------- tst/memfs/memfs.cpp | 2 ++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 05d3c2d2..4bf3c357 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -146,7 +146,9 @@ typedef struct UINT32 HardLinks:1; /* unimplemented; set to 0 */ UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */ UINT32 ReadOnlyVolume:1; - UINT32 KmReservedFlags:6; + /* kernel-mode flags */ + UINT32 PostCleanupOnDeleteOnly:1; /* post Cleanup when deleting a file only */ + UINT32 KmReservedFlags:5; /* user-mode flags */ UINT32 UmFileNodeIsUserContext2:1; /* user mode: FileNode parameter is UserContext2 */ UINT32 UmReservedFlags:15; diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index db48565d..4f96282b 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -318,6 +318,10 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE * tested to see if the delete can proceed and if the answer is positive the file is then * deleted during Cleanup. * + * As an optimization a file system may specify the FSP_FSCTL_VOLUME_PARAMS :: + * PostCleanupOnDeleteOnly flag. In this case the FSD will only post Cleanup requests when a + * file is being deleted. + * * @param FileSystem * The file system on which this request is posted. * @param Request diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index 7f278cef..76c53b11 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -525,6 +525,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE; opt_data.VolumeParams.NamedStreams = !!opt_data.NamedStreams; opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume; + opt_data.VolumeParams.PostCleanupOnDeleteOnly = TRUE; opt_data.VolumeParams.UmFileNodeIsUserContext2 = TRUE; if (L'\0' == opt_data.VolumeParams.FileSystemName[0]) memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR)); diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index dac23a1c..83e621d6 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -72,6 +72,7 @@ static NTSTATUS FspFsvolCleanup( if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext)) return STATUS_SUCCESS; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); PFILE_OBJECT FileObject = IrpSp->FileObject; FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_DESC *FileDesc = FileObject->FsContext2; @@ -87,9 +88,6 @@ static NTSTATUS FspFsvolCleanup( /* if this is a directory inform the FSRTL Notify mechanism */ if (FileNode->IsDirectory) { - FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = - FspFsvolDeviceExtension(FsvolDeviceObject); - if (DeletePending) FspNotifyDeletePending( FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList, FileNode); @@ -114,14 +112,22 @@ static NTSTATUS FspFsvolCleanup( FspFileNodeSetOwner(FileNode, Full, Request); FspIopRequestContext(Request, RequestIrp) = Irp; - return FSP_STATUS_IOQ_POST_BEST_EFFORT; + if (DeletePending || !FsvolDeviceExtension->VolumeParams.PostCleanupOnDeleteOnly) + /* + * Note that it is still possible for this request to not be delivered, + * if the volume device Ioq is stopped. But such failures are benign + * from our perspective, because they mean that the file system is going + * away and should correctly tear things down. + */ + return FSP_STATUS_IOQ_POST_BEST_EFFORT; + else + { + /* if the file is being resized invalidate the volume info */ + if (FileNode->TruncateOnClose) + FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject); - /* - * Note that it is still possible for this request to not be delivered, - * if the volume device Ioq is stopped. But such failures are benign - * from our perspective, because they mean that the file system is going - * away and should correctly tear things down. - */ + return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */ + } } NTSTATUS FspFsvolCleanupComplete( diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index d574d822..87696169 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -502,6 +502,7 @@ static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem, MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; assert(0 == FileName || 0 == wcscmp(FileNode->FileName, FileName)); + assert(Delete); /* the new FSP_FSCTL_VOLUME_PARAMS::PostCleanupOnDeleteOnly ensures this */ if (Delete && !MemfsFileNodeMapHasChild(Memfs->FileNodeMap, FileNode)) MemfsFileNodeMapRemove(Memfs->FileNodeMap, FileNode); @@ -1151,6 +1152,7 @@ NTSTATUS MemfsCreate( VolumeParams.PersistentAcls = 1; VolumeParams.ReparsePoints = 1; VolumeParams.ReparsePointsAccessCheck = 0; + VolumeParams.PostCleanupOnDeleteOnly = 1; if (0 != VolumePrefix) wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix); wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR), L"MEMFS");