From c8e182e1d4f1e02999f35a6c3d80002a39b34d55 Mon Sep 17 00:00:00 2001 From: ethan Date: Fri, 20 Jun 2025 14:56:01 +0800 Subject: [PATCH] sys & dll: Added FlushOnCleanup volume param --- inc/winfsp/fsctl.h | 3 ++- inc/winfsp/winfsp.hpp | 8 ++++++++ src/dll/fuse/fuse.c | 4 ++++ src/dll/fuse/fuse_intf.c | 11 ++++++++++- src/dll/fuse/library.h | 1 + src/sys/cleanup.c | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 94ade4a9..e27f31c6 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -250,7 +250,8 @@ enum UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\ UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\ UINT32 FsextControlCode;\ - UINT32 Reserved32[1];\ + UINT32 FlushOnCleanup:1;\ + UINT32 Reserved32:31;\ UINT64 Reserved64[2]; typedef struct { diff --git a/inc/winfsp/winfsp.hpp b/inc/winfsp/winfsp.hpp index 33bb494b..742dfee2 100644 --- a/inc/winfsp/winfsp.hpp +++ b/inc/winfsp/winfsp.hpp @@ -620,6 +620,14 @@ public: { _VolumeParams.FlushAndPurgeOnCleanup = !!FlushAndPurgeOnCleanup; } + BOOLEAN FlushOnCleanup() + { + return _VolumeParams.FlushOnCleanup; + } + VOID SetFlushOnCleanup(BOOLEAN FlushOnCleanup) + { + _VolumeParams.FlushOnCleanup = !!FlushOnCleanup; + } PWSTR Prefix() { return _VolumeParams.Prefix; diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index dae28a0f..743018c7 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -98,6 +98,7 @@ static struct fuse_opt fsp_fuse_core_opts[] = FSP_FUSE_CORE_OPT("VolumeInfoTimeout=", set_VolumeInfoTimeout, 1), FSP_FUSE_CORE_OPT("VolumeInfoTimeout=%d", VolumeParams.VolumeInfoTimeout, 0), FSP_FUSE_CORE_OPT("KeepFileCache=", set_KeepFileCache, 1), + FSP_FUSE_CORE_OPT("FlushOnCleanup=", set_FlushOnCleanup, 1), FSP_FUSE_CORE_OPT("LegacyUnlinkRename=", set_LegacyUnlinkRename, 1), FSP_FUSE_CORE_OPT("ThreadCount=%u", ThreadCount, 0), FUSE_OPT_KEY("UNC=", 'U'), @@ -802,6 +803,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, opt_data.VolumeParams.FileInfoTimeout = 1000; opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE; opt_data.VolumeParams.SupportsPosixUnlinkRename = TRUE; + opt_data.VolumeParams.FlushOnCleanup = FALSE; if (-1 == fsp_fuse_core_opt_parse(env, args, &opt_data, /*help=*/1)) { @@ -871,6 +873,8 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, opt_data.VolumeParams.VolumeInfoTimeoutValid = 1; if (opt_data.set_KeepFileCache) opt_data.VolumeParams.FlushAndPurgeOnCleanup = FALSE; + if (opt_data.set_FlushOnCleanup) + opt_data.VolumeParams.FlushOnCleanup = TRUE; if (opt_data.set_LegacyUnlinkRename) opt_data.VolumeParams.SupportsPosixUnlinkRename = FALSE; opt_data.VolumeParams.CaseSensitiveSearch = TRUE; diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 37acd0fa..7150af73 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -1305,6 +1305,7 @@ static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem, { struct fuse *f = FileSystem->UserContext; struct fsp_fuse_file_desc *filedesc = FileDesc; + struct fuse_file_info fi; /* * In Windows a DeleteFile/RemoveDirectory is the sequence of the following: @@ -1331,6 +1332,14 @@ static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem, * LegacyUnlinkRename option to opt out of the POSIX unlink semantics. */ + if (f->VolumeParams.FlushOnCleanup && !filedesc->IsDirectory && !filedesc->IsReparsePoint) { + memset(&fi, 0, sizeof fi); + fi.flags = filedesc->OpenFlags; + fi.fh = filedesc->FileHandle; + if (0 != f->ops.flush) + f->ops.flush(filedesc->PosixPath, &fi); + } + if (Flags & FspCleanupDelete) if (filedesc->IsDirectory && !filedesc->IsReparsePoint) { @@ -1366,7 +1375,7 @@ static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem, } else { - if (0 != f->ops.flush) + if (0 != f->ops.flush && !f->VolumeParams.FlushOnCleanup) f->ops.flush(filedesc->PosixPath, &fi); if (0 != f->ops.release) f->ops.release(filedesc->PosixPath, &fi); diff --git a/src/dll/fuse/library.h b/src/dll/fuse/library.h index dc981225..08c7f640 100644 --- a/src/dll/fuse/library.h +++ b/src/dll/fuse/library.h @@ -156,6 +156,7 @@ struct fsp_fuse_core_opt_data set_EaTimeout, set_VolumeInfoTimeout, set_KeepFileCache, + set_FlushOnCleanup, set_LegacyUnlinkRename; unsigned ThreadCount; FSP_FSCTL_VOLUME_PARAMS VolumeParams; diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index 5ac3ffa0..2cac1459 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -134,6 +134,7 @@ static NTSTATUS FspFsvolCleanup( Request->Req.Cleanup.SetArchiveBit || Request->Req.Cleanup.SetLastWriteTime || Request->Req.Cleanup.SetChangeTime || + FsvolDeviceExtension->VolumeParams.FlushOnCleanup || !FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly) /* * Note that it is still possible for this request to not be delivered,