diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index dae28a0f..b9774abc 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'), @@ -880,7 +881,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE; opt_data.VolumeParams.NamedStreams = FALSE; opt_data.VolumeParams.ReadOnlyVolume = FALSE; - opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE; + opt_data.VolumeParams.PostCleanupWhenModifiedOnly = !opt_data.set_FlushOnCleanup; opt_data.VolumeParams.PassQueryDirectoryFileName = TRUE; opt_data.VolumeParams.DeviceControl = TRUE; #if defined(FSP_CFG_REJECT_EARLY_IRP) @@ -905,6 +906,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, f->rellinks = opt_data.rellinks; f->dothidden = opt_data.dothidden; f->ThreadCount = opt_data.ThreadCount; + f->FlushOnCleanup = !!opt_data.set_FlushOnCleanup; memcpy(&f->ops, ops, opsize); f->data = data; f->DebugLog = opt_data.debug ? -1 : 0; diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 37acd0fa..227281f7 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->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 (!f->FlushOnCleanup && 0 != f->ops.flush) 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..6cec0e8e 100644 --- a/src/dll/fuse/library.h +++ b/src/dll/fuse/library.h @@ -63,6 +63,7 @@ struct fuse unsigned conn_want; BOOLEAN fsinit; BOOLEAN has_symlinks, has_slashdot; + BOOLEAN FlushOnCleanup; UINT32 DebugLog; FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy; FSP_FSCTL_VOLUME_PARAMS VolumeParams; @@ -156,6 +157,7 @@ struct fsp_fuse_core_opt_data set_EaTimeout, set_VolumeInfoTimeout, set_KeepFileCache, + set_FlushOnCleanup, set_LegacyUnlinkRename; unsigned ThreadCount; FSP_FSCTL_VOLUME_PARAMS VolumeParams;