diff --git a/src/sys/callbacks.c b/src/sys/callbacks.c index 9f486f56..1ad363a4 100644 --- a/src/sys/callbacks.c +++ b/src/sys/callbacks.c @@ -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); diff --git a/src/sys/driver.h b/src/sys/driver.h index 171da557..37aae1e1 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -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; diff --git a/src/sys/file.c b/src/sys/file.c index 77b3e0e0..5709c5a6 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -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); diff --git a/src/sys/write.c b/src/sys/write.c index aa88e6bb..1a7eb7f2 100644 --- a/src/sys/write.c +++ b/src/sys/write.c @@ -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 ==