diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 62a15091..cdda8831 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -709,38 +709,38 @@ __int32 __iso_volatile_load32(const volatile __int32 *); void __iso_volatile_store32(volatile __int32 *, __int32); __int64 __iso_volatile_load64(const volatile __int64 *); void __iso_volatile_store64(volatile __int64 *, __int64); -#define FSP_ATOMIC_VOLATILE_LOAD32(p) __iso_volatile_load32(p) -#define FSP_ATOMIC_VOLATILE_STORE32(p,v)__iso_volatile_store32(p,v) -#define FSP_ATOMIC_VOLATILE_LOAD64(p) __iso_volatile_load64(p) -#define FSP_ATOMIC_VOLATILE_STORE64(p,v)__iso_volatile_store64(p,v) +#define FSP_INTERLOCKED__LOAD32(p) __iso_volatile_load32(p) +#define FSP_INTERLOCKED__STORE32(p,v) __iso_volatile_store32(p,v) +#define FSP_INTERLOCKED__LOAD64(p) __iso_volatile_load64(p) +#define FSP_INTERLOCKED__STORE64(p,v) __iso_volatile_store64(p,v) #else -#define FSP_ATOMIC_VOLATILE_LOAD32(p) (*(p)) -#define FSP_ATOMIC_VOLATILE_STORE32(p,v)(*(p) = (v)) -#define FSP_ATOMIC_VOLATILE_LOAD64(p) (*(p)) -#define FSP_ATOMIC_VOLATILE_STORE64(p,v)(*(p) = (v)) +#define FSP_INTERLOCKED__LOAD32(p) (*(p)) +#define FSP_INTERLOCKED__STORE32(p,v) (*(p) = (v)) +#define FSP_INTERLOCKED__LOAD64(p) (*(p)) +#define FSP_INTERLOCKED__STORE64(p,v) (*(p) = (v)) #endif -static inline INT32 FspAtomicLoad32(INT32 volatile *p) +static inline INT32 FspInterlockedLoad32(INT32 volatile *p) { #if defined(_M_ARM64) void __dmb(unsigned int); - INT32 v = FSP_ATOMIC_VOLATILE_LOAD32(p); + INT32 v = FSP_INTERLOCKED__LOAD32(p); __dmb(0xb); return v; #elif defined(_M_X64) || defined(_M_IX86) void _ReadWriteBarrier(void); - INT32 v = FSP_ATOMIC_VOLATILE_LOAD32(p); + INT32 v = FSP_INTERLOCKED__LOAD32(p); _ReadWriteBarrier(); return v; #endif } -static inline VOID FspAtomicStore32(INT32 volatile *p, INT32 v) +static inline VOID FspInterlockedStore32(INT32 volatile *p, INT32 v) { #if defined(_M_ARM64) void __dmb(unsigned int); __dmb(0xb); - FSP_ATOMIC_VOLATILE_STORE32(p, v); + FSP_INTERLOCKED__STORE32(p, v); __dmb(0xb); #elif defined(_M_X64) || defined(_M_IX86) @@ -749,34 +749,34 @@ static inline VOID FspAtomicStore32(INT32 volatile *p, INT32 v) #endif } -static inline VOID *FspAtomicLoadPointer(VOID *volatile *p) +static inline VOID *FspInterlockedLoadPointer(VOID *volatile *p) { #if defined(_M_ARM64) void __dmb(unsigned int); - VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD64((__int64 volatile *)(p)); + VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p)); __dmb(0xb); return v; #elif defined(_M_X64) void _ReadWriteBarrier(void); - VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD64((__int64 volatile *)(p)); + VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p)); _ReadWriteBarrier(); return v; #elif defined(_M_IX86) void _ReadWriteBarrier(void); - VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD32((__int32 volatile *)(p)); + VOID *v = (VOID *)FSP_INTERLOCKED__LOAD32((__int32 volatile *)(p)); _ReadWriteBarrier(); return v; #endif } -static inline VOID FspAtomicStorePointer(VOID *volatile *p, VOID *v) +static inline VOID FspInterlockedStorePointer(VOID *volatile *p, VOID *v) { #if defined(_M_ARM64) void __dmb(unsigned int); __dmb(0xb); - FSP_ATOMIC_VOLATILE_STORE64((__int64 volatile *)(p), (__int64)(v)); + FSP_INTERLOCKED__STORE64((__int64 volatile *)(p), (__int64)(v)); __dmb(0xb); #elif defined(_M_X64) || defined(_M_IX86) diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index dad249b0..ba753a6e 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1348,9 +1348,7 @@ static inline VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, NTSTATUS *PDispatcherResult) { - /* 32-bit reads are atomic */ - *PDispatcherResult = FileSystem->DispatcherResult; - MemoryBarrier(); + *PDispatcherResult = FspInterlockedLoad32((INT32 *)&FileSystem->DispatcherResult); } FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem, NTSTATUS *PDispatcherResult); diff --git a/src/dll/dirbuf.c b/src/dll/dirbuf.c index 2037ec4e..bde3b98d 100644 --- a/src/dll/dirbuf.c +++ b/src/dll/dirbuf.c @@ -227,8 +227,7 @@ static inline VOID FspFileSystemSortDirectoryBuffer(FSP_FILE_SYSTEM_DIRECTORY_BU FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer, BOOLEAN Reset, PNTSTATUS PResult) { - FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; - MemoryBarrier(); + FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer); if (0 == DirBuffer) { @@ -243,10 +242,9 @@ FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer, AcquireSRWLockExclusive(&NewDirBuffer->Lock); AcquireSRWLockExclusive(&CreateLock); - DirBuffer = *PDirBuffer; - MemoryBarrier(); + DirBuffer = FspInterlockedLoadPointer(PDirBuffer); if (0 == DirBuffer) - *PDirBuffer = DirBuffer = NewDirBuffer; + FspInterlockedStorePointer(PDirBuffer, DirBuffer = NewDirBuffer); ReleaseSRWLockExclusive(&CreateLock); if (DirBuffer == NewDirBuffer) @@ -274,7 +272,7 @@ FSP_API BOOLEAN FspFileSystemFillDirectoryBuffer(PVOID *PDirBuffer, { /* assume that FspFileSystemAcquireDirectoryBuffer has been called */ - FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; + FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer); ULONG Capacity, LoMark, HiMark; PUINT8 Buffer; @@ -333,7 +331,7 @@ FSP_API VOID FspFileSystemReleaseDirectoryBuffer(PVOID *PDirBuffer) { /* assume that FspFileSystemAcquireDirectoryBuffer has been called */ - FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; + FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer); /* eliminate invalidated entries from the index */ PULONG Index = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark); @@ -356,8 +354,7 @@ FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer, PWSTR Marker, PVOID Buffer, ULONG Length, PULONG PBytesTransferred) { - FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; - MemoryBarrier(); + FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer); if (0 != DirBuffer) { @@ -396,14 +393,13 @@ FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer, FSP_API VOID FspFileSystemDeleteDirectoryBuffer(PVOID *PDirBuffer) { - FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; - MemoryBarrier(); + FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer); if (0 != DirBuffer) { MemFree(DirBuffer->Buffer); MemFree(DirBuffer); - *PDirBuffer = 0; + FspInterlockedStorePointer(PDirBuffer, 0); } } @@ -412,7 +408,7 @@ VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer, { /* assume that FspFileSystemAcquireDirectoryBuffer has been called */ - FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; + FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer); *PBuffer = DirBuffer->Buffer; *PIndex = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark); diff --git a/src/dll/service.c b/src/dll/service.c index c779d03c..229c4424 100644 --- a/src/dll/service.c +++ b/src/dll/service.c @@ -275,8 +275,7 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service) else { ResetEvent(FspServiceConsoleModeEvent); - FspServiceConsoleCtrlHandlerDisabled = 0; - MemoryBarrier(); + FspInterlockedStore32((INT32 *)&FspServiceConsoleCtrlHandlerDisabled, 0); } #endif @@ -326,8 +325,7 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service) * * What we do instead is disable our handler by setting a variable. */ - FspServiceConsoleCtrlHandlerDisabled = 1; - MemoryBarrier(); + FspInterlockedStore32((INT32 *)&FspServiceConsoleCtrlHandlerDisabled, 1); } Result = STATUS_SUCCESS; @@ -517,8 +515,7 @@ static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context) /* expose FspServiceConsoleCtrlHandler so it can be used from fsp_fuse_signal_handler */ BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType) { - UINT32 Disabled = FspServiceConsoleCtrlHandlerDisabled; - MemoryBarrier(); + UINT32 Disabled = FspInterlockedLoad32((INT32 *)&FspServiceConsoleCtrlHandlerDisabled); if (Disabled) return FALSE; diff --git a/src/sys/dirctl.c b/src/sys/dirctl.c index cd85829e..872aac37 100644 --- a/src/sys/dirctl.c +++ b/src/sys/dirctl.c @@ -753,8 +753,7 @@ static NTSTATUS FspFsvolNotifyChangeDirectory( return STATUS_ACCESS_DENIED; /* stop now if the directory is pending deletion */ - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode); if (DeletePending) return STATUS_DELETE_PENDING; diff --git a/src/sys/driver.h b/src/sys/driver.h index 0a4b472d..0a882d72 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1521,6 +1521,16 @@ VOID FspFileNodeDereference(FSP_FILE_NODE *FileNode) if (0 == RefCount) FspFileNodeDelete(FileNode); } +static inline +BOOLEAN FspFileNodeDeletePending(FSP_FILE_NODE *FileNode) +{ + return 0 != FspInterlockedLoad32((INT32 *)&FileNode->DeletePending); +} +static inline +VOID FspFileNodeSetDeletePending(FSP_FILE_NODE *FileNode, BOOLEAN Delete) +{ + FspInterlockedStore32((INT32 *)&FileNode->DeletePending, Delete); +} VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags); BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); diff --git a/src/sys/file.c b/src/sys/file.c index 64aac3bf..23bdfda6 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -618,8 +618,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, */ if (0 != FileNode->MainFileNode) { - DeletePending = 0 != FileNode->MainFileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode->MainFileNode); if (DeletePending) { Result = STATUS_DELETE_PENDING; @@ -669,8 +668,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, ASSERT(OpenedFileNode != FileNode); ASSERT(OpenedFileNode->MainFileNode == FileNode->MainFileNode); - DeletePending = 0 != OpenedFileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(OpenedFileNode); if (DeletePending) { Result = STATUS_DELETE_PENDING; @@ -795,9 +793,8 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG FspFsvolDeviceLockContextTable(FsvolDeviceObject); if (FileDesc->DeleteOnClose) - FileNode->DeletePending = TRUE; - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + FspFileNodeSetDeletePending(FileNode, TRUE); + DeletePending = FspFileNodeDeletePending(FileNode); SetAllocationSize = !DeletePending && FileNode->TruncateOnClose; @@ -841,8 +838,7 @@ VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject) FspFsvolDeviceLockContextTable(FsvolDeviceObject); - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode); SingleHandle = 1 == FileNode->HandleCount; @@ -965,8 +961,7 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject { SingleHandle = TRUE; - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode); if (DeletePending) FileNode->Header.FileSize.QuadPart = 0; @@ -1179,7 +1174,7 @@ VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode) DescendantFileNodeIndex++) { DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex]; - DescendantFileNode->DeletePending = TRUE; + FspFileNodeSetDeletePending(DescendantFileNode, TRUE); } FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index cde12c9f..7bea7e6b 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -177,8 +177,7 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject, return FspFsvolQueryNameInformation(FileObject, PBuffer, BufferEnd); } - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode); Info->BasicInformation.CreationTime.QuadPart = FileInfo->CreationTime; Info->BasicInformation.LastAccessTime.QuadPart = FileInfo->LastAccessTime; @@ -422,8 +421,7 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject, return STATUS_SUCCESS; } - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode); Info->AllocationSize.QuadPart = FileInfo->AllocationSize; Info->EndOfFile.QuadPart = FileInfo->FileSize; @@ -1626,7 +1624,7 @@ static NTSTATUS FspFsvolSetDispositionInformationSuccess( UINT32 DispositionFlags = Request->Req.SetInformation.Info.DispositionEx.Flags; BOOLEAN Delete = BooleanFlagOn(DispositionFlags, FILE_DISPOSITION_DELETE); - FileNode->DeletePending = Delete; + FspFileNodeSetDeletePending(FileNode, Delete); FileObject->DeletePending = Delete; if (!Delete) diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 315b510d..fcef99fc 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -503,8 +503,7 @@ static NTSTATUS FspFsvolFileSystemControlOplock( { BOOLEAN DeletePending; - DeletePending = 0 != FileNode->DeletePending; - MemoryBarrier(); + DeletePending = FspFileNodeDeletePending(FileNode); if (DeletePending) { Result = STATUS_DELETE_PENDING; diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 076073ba..1f645827 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -1298,8 +1298,7 @@ static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem, MemfsFileNodeMapEnumerateFn, &Context); for (Index = 0; Context.Count > Index; Index++) { - LONG RefCount = Context.FileNodes[Index]->RefCount; - MemoryBarrier(); + LONG RefCount = FspInterlockedLoad32((INT32 *)&Context.FileNodes[Index]->RefCount); if (2 >= RefCount) MemfsFileNodeMapRemove(Memfs->FileNodeMap, Context.FileNodes[Index]); }