dll: FspFileSystemOpEnter, FspFileSystemOpLeave

This commit is contained in:
Bill Zissimopoulos 2016-06-08 20:43:52 -07:00
parent 20fc185530
commit 0f63dddb32
5 changed files with 125 additions and 25 deletions

View File

@ -577,6 +577,11 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
PWSTR Pattern,
PULONG PBytesTransferred);
} 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
{
UINT16 Version;
@ -592,6 +597,8 @@ typedef struct _FSP_FILE_SYSTEM
PWSTR MountPoint;
LIST_ENTRY MountEntry;
UINT32 DebugLog;
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
SRWLOCK OpGuardLock;
} FSP_FILE_SYSTEM;
/**
* Create a file system object.
@ -716,6 +723,12 @@ VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
FileSystem->LeaveOperation = LeaveOperation;
}
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,
ULONG Index,
FSP_FILE_SYSTEM_OPERATION *Operation)
@ -748,6 +761,10 @@ VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem,
/*
* 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_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,

View File

@ -125,6 +125,11 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
FileSystem->Interface = Interface;
FileSystem->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE;
InitializeSRWLock(&FileSystem->OpGuardLock);
FileSystem->EnterOperation = FspFileSystemOpEnter;
FileSystem->LeaveOperation = FspFileSystemOpLeave;
*PFileSystem = FileSystem;
return STATUS_SUCCESS;

View File

@ -17,6 +17,92 @@
#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
NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,

View File

@ -587,12 +587,14 @@ FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env,
MemFree(f);
}
FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env,
struct fuse *f)
static int fsp_fuse_loop_internal(struct fsp_fuse_env *env,
struct fuse *f, FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy)
{
NTSTATUS Result;
ULONG ExitCode;
FspFileSystemSetOperationGuardStrategy(f->FileSystem, GuardStrategy);
Result = FspServiceLoop(f->Service);
ExitCode = FspServiceGetExitCode(f->Service);
@ -612,10 +614,18 @@ fail:
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,
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,

View File

@ -79,7 +79,6 @@ typedef struct _MEMFS
ULONG MaxFileSize;
UINT16 VolumeLabelLength;
WCHAR VolumeLabel[32];
CRITICAL_SECTION Lock;
} MEMFS;
static inline
@ -962,20 +961,6 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
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(
ULONG Flags,
ULONG FileInfoTimeout,
@ -1050,11 +1035,10 @@ NTSTATUS MemfsCreate(
Memfs->VolumeLabelLength = sizeof L"MEMFS" - sizeof(WCHAR);
memcpy(Memfs->VolumeLabel, L"MEMFS", Memfs->VolumeLabelLength);
InitializeCriticalSection(&Memfs->Lock);
FspFileSystemSetOperationGuard(Memfs->FileSystem,
MemfsEnterOperation,
MemfsLeaveOperation);
#if 0
FspFileSystemSetOperationGuardStrategy(Memfs->FileSystem,
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE);
#endif
/*
* Create root directory.
@ -1099,8 +1083,6 @@ NTSTATUS MemfsCreate(
VOID MemfsDelete(MEMFS *Memfs)
{
DeleteCriticalSection(&Memfs->Lock);
FspFileSystemDelete(Memfs->FileSystem);
MemfsFileNodeMapDelete(Memfs->FileNodeMap);