mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
sys: FspAcquireCcFlush: improve/fix top level IRP handling
This commit is contained in:
parent
9fc1123cdb
commit
03522c5296
@ -131,12 +131,23 @@ NTSTATUS FspAcquireForCcFlush(
|
||||
|
||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||
PIRP TopLevelIrp = IoGetTopLevelIrp();
|
||||
ULONG TopFlags;
|
||||
|
||||
ASSERT(0 == TopLevelIrp ||
|
||||
(PIRP)FSRTL_MAX_TOP_LEVEL_IRP_FLAG < TopLevelIrp);
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
if (0 == TopLevelIrp)
|
||||
{
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
}
|
||||
else
|
||||
{
|
||||
TopFlags = FspIrpTopFlags(TopLevelIrp);
|
||||
FspIrpSetTopFlags(TopLevelIrp, FspIrpFlags(TopLevelIrp));
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
ASSERT(0 == FileNode->Tls.TopFlags);
|
||||
FileNode->Tls.TopFlags = TopFlags;
|
||||
}
|
||||
|
||||
FSP_LEAVE("FileObject=%p", FileObject);
|
||||
}
|
||||
@ -149,12 +160,22 @@ NTSTATUS FspReleaseForCcFlush(
|
||||
|
||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||
PIRP TopLevelIrp = IoGetTopLevelIrp();
|
||||
ULONG TopFlags;
|
||||
|
||||
ASSERT((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP == TopLevelIrp ||
|
||||
(PIRP)FSRTL_MAX_TOP_LEVEL_IRP_FLAG < TopLevelIrp);
|
||||
if ((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP == TopLevelIrp)
|
||||
{
|
||||
IoSetTopLevelIrp(0);
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
}
|
||||
else
|
||||
{
|
||||
TopFlags = FileNode->Tls.TopFlags;
|
||||
FileNode->Tls.TopFlags = 0;
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
FspIrpSetTopFlags(TopLevelIrp, TopFlags);
|
||||
}
|
||||
|
||||
FSP_LEAVE("FileObject=%p", FileObject);
|
||||
}
|
||||
@ -175,7 +196,8 @@ BOOLEAN FspAcquireForLazyWrite(
|
||||
Result = FspFileNodeTryAcquireExclusiveF(FileNode, FspFileNodeAcquireFull, Wait);
|
||||
if (Result)
|
||||
{
|
||||
FileNode->LazyWriteThread = PsGetCurrentThread();
|
||||
ASSERT(0 == FileNode->Tls.LazyWriteThread);
|
||||
FileNode->Tls.LazyWriteThread = PsGetCurrentThread();
|
||||
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
}
|
||||
|
||||
@ -194,8 +216,9 @@ VOID FspReleaseFromLazyWrite(
|
||||
FSP_FILE_NODE *FileNode = Context;
|
||||
|
||||
ASSERT((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP == IoGetTopLevelIrp());
|
||||
ASSERT(PsGetCurrentThread() == FileNode->Tls.LazyWriteThread);
|
||||
IoSetTopLevelIrp(0);
|
||||
FileNode->LazyWriteThread = 0;
|
||||
FileNode->Tls.LazyWriteThread = 0;
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
|
||||
FSP_LEAVE_VOID("Context=%p", Context);
|
||||
|
@ -793,7 +793,11 @@ typedef struct
|
||||
UINT64 Security;
|
||||
ULONG SecurityChangeNumber;
|
||||
BOOLEAN TruncateOnClose;
|
||||
PVOID LazyWriteThread;
|
||||
union
|
||||
{
|
||||
PVOID LazyWriteThread;
|
||||
UINT32 TopFlags;
|
||||
} Tls;
|
||||
/* read-only after creation (and insertion in the ContextTable) */
|
||||
PDEVICE_OBJECT FsvolDeviceObject;
|
||||
UINT64 UserContext;
|
||||
|
@ -64,15 +64,19 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
||||
#define FSP_FILE_NODE_GET_FLAGS() \
|
||||
PIRP Irp = IoGetTopLevelIrp(); \
|
||||
BOOLEAN IrpValid = (PIRP)FSRTL_MAX_TOP_LEVEL_IRP_FLAG < Irp &&\
|
||||
IO_TYPE_IRP == Irp->Type;\
|
||||
IO_TYPE_IRP == Irp->Type; \
|
||||
if (IrpValid) \
|
||||
Flags &= ~FspIrpTopFlags(Irp);
|
||||
Flags &= ~FspIrpTopFlags(Irp)
|
||||
#define FSP_FILE_NODE_ASSERT_FLAGS_CLR()\
|
||||
ASSERT(IrpValid ? (0 == (FspIrpFlags(Irp) & Flags)) : TRUE)
|
||||
#define FSP_FILE_NODE_ASSERT_FLAGS_SET()\
|
||||
ASSERT(IrpValid ? (Flags == (FspIrpFlags(Irp) & Flags)) : TRUE)
|
||||
#define FSP_FILE_NODE_SET_FLAGS() \
|
||||
if (IrpValid) \
|
||||
FspIrpSetFlags(Irp, FspIrpFlags(Irp) | Flags);
|
||||
FspIrpSetFlags(Irp, FspIrpFlags(Irp) | Flags)
|
||||
#define FSP_FILE_NODE_CLR_FLAGS() \
|
||||
if (IrpValid) \
|
||||
FspIrpSetFlags(Irp, FspIrpFlags(Irp) & (~Flags & 3));
|
||||
FspIrpSetFlags(Irp, FspIrpFlags(Irp) & (~Flags & 3))
|
||||
|
||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||
ULONG ExtraSize, FSP_FILE_NODE **PFileNode)
|
||||
@ -145,6 +149,7 @@ VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags)
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE_GET_FLAGS();
|
||||
FSP_FILE_NODE_ASSERT_FLAGS_CLR();
|
||||
|
||||
if (Flags & FspFileNodeAcquireMain)
|
||||
ExAcquireResourceSharedLite(FileNode->Header.Resource, TRUE);
|
||||
@ -160,6 +165,7 @@ BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLE
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE_GET_FLAGS();
|
||||
FSP_FILE_NODE_ASSERT_FLAGS_CLR();
|
||||
|
||||
BOOLEAN Result = TRUE;
|
||||
|
||||
@ -192,6 +198,7 @@ VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags)
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE_GET_FLAGS();
|
||||
FSP_FILE_NODE_ASSERT_FLAGS_CLR();
|
||||
|
||||
if (Flags & FspFileNodeAcquireMain)
|
||||
ExAcquireResourceExclusiveLite(FileNode->Header.Resource, TRUE);
|
||||
@ -207,6 +214,7 @@ BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BO
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE_GET_FLAGS();
|
||||
FSP_FILE_NODE_ASSERT_FLAGS_CLR();
|
||||
|
||||
BOOLEAN Result = TRUE;
|
||||
|
||||
@ -254,6 +262,7 @@ VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags)
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE_GET_FLAGS();
|
||||
FSP_FILE_NODE_ASSERT_FLAGS_SET();
|
||||
|
||||
if (Flags & FspFileNodeAcquirePgio)
|
||||
ExReleaseResourceLite(FileNode->Header.PagingIoResource);
|
||||
@ -269,6 +278,7 @@ VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner)
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_FILE_NODE_GET_FLAGS();
|
||||
FSP_FILE_NODE_ASSERT_FLAGS_SET();
|
||||
|
||||
Owner = (PVOID)((UINT_PTR)Owner | 3);
|
||||
|
||||
|
@ -285,7 +285,7 @@ static NTSTATUS FspFsvolWriteNonCached(
|
||||
|
||||
/* if we are called by the lazy writer we must constrain writes */
|
||||
if (FlagOn(FspIrpTopFlags(Irp), FspFileNodeAcquireMain) && /* if TopLevelIrp has acquired Main */
|
||||
FileNode->LazyWriteThread == PsGetCurrentThread()) /* and this is a lazy writer thread */
|
||||
FileNode->Tls.LazyWriteThread == PsGetCurrentThread()) /* and this is a lazy writer thread */
|
||||
{
|
||||
ASSERT(PagingIo);
|
||||
ASSERT(FspTimeoutInfinity32 ==
|
||||
|
Loading…
x
Reference in New Issue
Block a user