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

@ -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,