mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
dll: FspFileSystemOpEnter, FspFileSystemOpLeave
This commit is contained in:
parent
20fc185530
commit
0f63dddb32
@ -577,6 +577,11 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
PWSTR Pattern,
|
PWSTR Pattern,
|
||||||
PULONG PBytesTransferred);
|
PULONG PBytesTransferred);
|
||||||
} FSP_FILE_SYSTEM_INTERFACE;
|
} FSP_FILE_SYSTEM_INTERFACE;
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE = 0,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE,
|
||||||
|
} FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY;
|
||||||
typedef struct _FSP_FILE_SYSTEM
|
typedef struct _FSP_FILE_SYSTEM
|
||||||
{
|
{
|
||||||
UINT16 Version;
|
UINT16 Version;
|
||||||
@ -592,6 +597,8 @@ typedef struct _FSP_FILE_SYSTEM
|
|||||||
PWSTR MountPoint;
|
PWSTR MountPoint;
|
||||||
LIST_ENTRY MountEntry;
|
LIST_ENTRY MountEntry;
|
||||||
UINT32 DebugLog;
|
UINT32 DebugLog;
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
|
||||||
|
SRWLOCK OpGuardLock;
|
||||||
} FSP_FILE_SYSTEM;
|
} FSP_FILE_SYSTEM;
|
||||||
/**
|
/**
|
||||||
* Create a file system object.
|
* Create a file system object.
|
||||||
@ -716,6 +723,12 @@ VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FileSystem->LeaveOperation = LeaveOperation;
|
FileSystem->LeaveOperation = LeaveOperation;
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
|
VOID FspFileSystemSetOperationGuardStrategy(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy)
|
||||||
|
{
|
||||||
|
FileSystem->OpGuardStrategy = GuardStrategy;
|
||||||
|
}
|
||||||
|
static inline
|
||||||
VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
ULONG Index,
|
ULONG Index,
|
||||||
FSP_FILE_SYSTEM_OPERATION *Operation)
|
FSP_FILE_SYSTEM_OPERATION *Operation)
|
||||||
@ -748,6 +761,10 @@ VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
/*
|
/*
|
||||||
* Operations
|
* Operations
|
||||||
*/
|
*/
|
||||||
|
FSP_API VOID FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
FSP_API VOID FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
@ -125,6 +125,11 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
|||||||
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
|
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
|
||||||
FileSystem->Interface = Interface;
|
FileSystem->Interface = Interface;
|
||||||
|
|
||||||
|
FileSystem->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE;
|
||||||
|
InitializeSRWLock(&FileSystem->OpGuardLock);
|
||||||
|
FileSystem->EnterOperation = FspFileSystemOpEnter;
|
||||||
|
FileSystem->LeaveOperation = FspFileSystemOpLeave;
|
||||||
|
|
||||||
*PFileSystem = FileSystem;
|
*PFileSystem = FileSystem;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -17,6 +17,92 @@
|
|||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The FspFileSystemOpEnter/FspFileSystemOpLeave functions guard against
|
||||||
|
* concurrent accesses. Two concurrency models are provided:
|
||||||
|
*
|
||||||
|
* 1. A fine-grained concurrency model where file system NAMESPACE accesses
|
||||||
|
* are guarded using an exclusive-shared (read-write) lock. File I/O is not
|
||||||
|
* guarded and concurrent reads/writes/etc. are possible. [Note that the FSD
|
||||||
|
* will still apply an exclusive-shared lock PER INDIVIDUAL FILE, but it will
|
||||||
|
* not limit I/O operations for different files.]
|
||||||
|
*
|
||||||
|
* The fine-grained concurrency model applies the exclusive-shared lock as
|
||||||
|
* follows:
|
||||||
|
* - EXCL: SetVolumeLabel, Create, Cleanup(Delete), SetInformation(Rename)
|
||||||
|
* - SHRD: GetVolumeInfo, Open, SetInformation(Disposition), ReadDirectory
|
||||||
|
* - NONE: all other operations
|
||||||
|
*
|
||||||
|
* 2. A coarse-grained concurrency model where all file system accesses are
|
||||||
|
* guarded by a mutually exclusive lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FSP_API VOID FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
|
{
|
||||||
|
switch (FileSystem->OpGuardStrategy)
|
||||||
|
{
|
||||||
|
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
|
||||||
|
if ((FspFsctlTransactCreateKind == Request->Kind &&
|
||||||
|
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
|
||||||
|
(FspFsctlTransactCleanupKind == Request->Kind &&
|
||||||
|
Request->Req.Cleanup.Delete) ||
|
||||||
|
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||||
|
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) ||
|
||||||
|
FspFsctlTransactSetVolumeInformationKind == Request->Kind)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&FileSystem->OpGuardLock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (FspFsctlTransactCreateKind == Request->Kind ||
|
||||||
|
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||||
|
13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass) ||
|
||||||
|
FspFsctlTransactQueryDirectoryKind == Request->Kind ||
|
||||||
|
FspFsctlTransactQueryVolumeInformationKind == Request->Kind)
|
||||||
|
{
|
||||||
|
AcquireSRWLockShared(&FileSystem->OpGuardLock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE:
|
||||||
|
AcquireSRWLockExclusive(&FileSystem->OpGuardLock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
|
{
|
||||||
|
switch (FileSystem->OpGuardStrategy)
|
||||||
|
{
|
||||||
|
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
|
||||||
|
if ((FspFsctlTransactCreateKind == Request->Kind &&
|
||||||
|
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
|
||||||
|
(FspFsctlTransactCleanupKind == Request->Kind &&
|
||||||
|
Request->Req.Cleanup.Delete) ||
|
||||||
|
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||||
|
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) ||
|
||||||
|
FspFsctlTransactSetVolumeInformationKind == Request->Kind)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(&FileSystem->OpGuardLock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (FspFsctlTransactCreateKind == Request->Kind ||
|
||||||
|
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||||
|
13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass) ||
|
||||||
|
FspFsctlTransactQueryDirectoryKind == Request->Kind ||
|
||||||
|
FspFsctlTransactQueryVolumeInformationKind == Request->Kind)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockShared(&FileSystem->OpGuardLock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE:
|
||||||
|
ReleaseSRWLockExclusive(&FileSystem->OpGuardLock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
@ -587,12 +587,14 @@ FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env,
|
|||||||
MemFree(f);
|
MemFree(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env,
|
static int fsp_fuse_loop_internal(struct fsp_fuse_env *env,
|
||||||
struct fuse *f)
|
struct fuse *f, FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
ULONG ExitCode;
|
ULONG ExitCode;
|
||||||
|
|
||||||
|
FspFileSystemSetOperationGuardStrategy(f->FileSystem, GuardStrategy);
|
||||||
|
|
||||||
Result = FspServiceLoop(f->Service);
|
Result = FspServiceLoop(f->Service);
|
||||||
ExitCode = FspServiceGetExitCode(f->Service);
|
ExitCode = FspServiceGetExitCode(f->Service);
|
||||||
|
|
||||||
@ -612,10 +614,18 @@ fail:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env,
|
||||||
|
struct fuse *f)
|
||||||
|
{
|
||||||
|
return fsp_fuse_loop_internal(env, f,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE);
|
||||||
|
}
|
||||||
|
|
||||||
FSP_FUSE_API int fsp_fuse_loop_mt(struct fsp_fuse_env *env,
|
FSP_FUSE_API int fsp_fuse_loop_mt(struct fsp_fuse_env *env,
|
||||||
struct fuse *f)
|
struct fuse *f)
|
||||||
{
|
{
|
||||||
return fsp_fuse_loop(env, f);
|
return fsp_fuse_loop_internal(env, f,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env,
|
FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env,
|
||||||
|
@ -79,7 +79,6 @@ typedef struct _MEMFS
|
|||||||
ULONG MaxFileSize;
|
ULONG MaxFileSize;
|
||||||
UINT16 VolumeLabelLength;
|
UINT16 VolumeLabelLength;
|
||||||
WCHAR VolumeLabel[32];
|
WCHAR VolumeLabel[32];
|
||||||
CRITICAL_SECTION Lock;
|
|
||||||
} MEMFS;
|
} MEMFS;
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
@ -962,20 +961,6 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
|||||||
ReadDirectory,
|
ReadDirectory,
|
||||||
};
|
};
|
||||||
|
|
||||||
static VOID MemfsEnterOperation(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
|
||||||
{
|
|
||||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
|
||||||
EnterCriticalSection(&Memfs->Lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID MemfsLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
|
||||||
{
|
|
||||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
|
||||||
LeaveCriticalSection(&Memfs->Lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS MemfsCreate(
|
NTSTATUS MemfsCreate(
|
||||||
ULONG Flags,
|
ULONG Flags,
|
||||||
ULONG FileInfoTimeout,
|
ULONG FileInfoTimeout,
|
||||||
@ -1050,11 +1035,10 @@ NTSTATUS MemfsCreate(
|
|||||||
Memfs->VolumeLabelLength = sizeof L"MEMFS" - sizeof(WCHAR);
|
Memfs->VolumeLabelLength = sizeof L"MEMFS" - sizeof(WCHAR);
|
||||||
memcpy(Memfs->VolumeLabel, L"MEMFS", Memfs->VolumeLabelLength);
|
memcpy(Memfs->VolumeLabel, L"MEMFS", Memfs->VolumeLabelLength);
|
||||||
|
|
||||||
InitializeCriticalSection(&Memfs->Lock);
|
#if 0
|
||||||
|
FspFileSystemSetOperationGuardStrategy(Memfs->FileSystem,
|
||||||
FspFileSystemSetOperationGuard(Memfs->FileSystem,
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE);
|
||||||
MemfsEnterOperation,
|
#endif
|
||||||
MemfsLeaveOperation);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create root directory.
|
* Create root directory.
|
||||||
@ -1099,8 +1083,6 @@ NTSTATUS MemfsCreate(
|
|||||||
|
|
||||||
VOID MemfsDelete(MEMFS *Memfs)
|
VOID MemfsDelete(MEMFS *Memfs)
|
||||||
{
|
{
|
||||||
DeleteCriticalSection(&Memfs->Lock);
|
|
||||||
|
|
||||||
FspFileSystemDelete(Memfs->FileSystem);
|
FspFileSystemDelete(Memfs->FileSystem);
|
||||||
|
|
||||||
MemfsFileNodeMapDelete(Memfs->FileNodeMap);
|
MemfsFileNodeMapDelete(Memfs->FileNodeMap);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user