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