From ce551d4e0d36979f2906dcef8718fe11ab9e11b4 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 20 Nov 2016 14:08:23 -0800 Subject: [PATCH] sys: oplock: refactoring/cleanup --- src/sys/cleanup.c | 2 +- src/sys/create.c | 50 +++++++++++++++++++++--------------- src/sys/driver.h | 64 ++++++++++++++++++++++++++++++++++++++++++++-- src/sys/file.c | 46 ++++++++++++++++++++++++++------- src/sys/fileinfo.c | 18 ++++++------- src/sys/lockctl.c | 9 ++++--- src/sys/read.c | 18 ++++++++----- src/sys/util.c | 2 +- src/sys/wq.c | 28 -------------------- src/sys/write.c | 18 ++++++++----- 10 files changed, 169 insertions(+), 86 deletions(-) diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index 7aa2086f..7b8f1d24 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -176,7 +176,7 @@ static VOID FspFsvolCleanupRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Co FspFileNodeCleanupComplete(FileNode, FileObject); if (!FileNode->IsDirectory) - FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); + FspFileNodeOplockCheck(FileNode, Irp); SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE); MainFileHandle = FileDesc->MainFileHandle; diff --git a/src/sys/create.c b/src/sys/create.c index b22542f5..33a91710 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -595,7 +595,9 @@ NTSTATUS FspFsvolCreatePrepare( FspFsvolCreateOpenOrOverwriteOplock(Irp, 0, &Result); if (!Success) { - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Full); return Result; @@ -1047,7 +1049,9 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re FspFsvolCreateOpenOrOverwriteOplock(Irp, Response, &Result); if (!Success) { - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Main); return Result; @@ -1191,8 +1195,8 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV if (OplockIrp) { ASSERT(IO_TYPE_IRP == OplockIrp->Type); - FspCheckOplockEx(FspFileNodeAddrOfOplock(FileDesc->FileNode), OplockIrp, - OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK, 0, 0, 0); + FspFileNodeOplockCheckEx(FileDesc->FileNode, OplockIrp, + OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK); } FspFsvolCreatePostClose(FileDesc); @@ -1227,8 +1231,8 @@ static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, if (OplockIrp) { ASSERT(IO_TYPE_IRP == OplockIrp->Type); - FspCheckOplockEx(FspFileNodeAddrOfOplock(FileDesc->FileNode), OplockIrp, - OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK, 0, 0, 0); + FspFileNodeOplockCheckEx(FileDesc->FileNode, OplockIrp, + OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK); } FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE); @@ -1299,9 +1303,9 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock( Success = DEBUGTEST(90) && !(FspFileNodeSharingViolationMainFile == SharingViolationReason) && !(FspFileNodeSharingViolationStream == SharingViolationReason) && - !(FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(ExtraFileNode))) && + !(FspFileNodeOplockIsBatch(ExtraFileNode)) && !(!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) && - FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(ExtraFileNode))); + FspFileNodeOplockIsHandle(ExtraFileNode)); FspFileNodeRelease(ExtraFileNode, Main); @@ -1354,11 +1358,10 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock( Result = STATUS_SHARING_VIOLATION; } else - if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(ExtraFileNode))) + if (FspFileNodeOplockIsBatch(ExtraFileNode)) { /* wait for Batch oplock break to complete */ - Result = FspCheckOplock(FspFileNodeAddrOfOplock(ExtraFileNode), Irp, - 0, 0, 0); + Result = FspFileNodeOplockCheck(ExtraFileNode, Irp); if (STATUS_SUCCESS != Result) Result = STATUS_SHARING_VIOLATION; else @@ -1366,11 +1369,10 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock( } else if (!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) && - FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(ExtraFileNode))) + FspFileNodeOplockIsHandle(ExtraFileNode)) { /* wait for Handle oplock break to complete */ - Result = FspOplockBreakH(FspFileNodeAddrOfOplock(ExtraFileNode), Irp, - 0, 0, 0, 0); + Result = FspFileNodeOplockBreakHandle(ExtraFileNode, Irp, 0); ASSERT(STATUS_OPLOCK_BREAK_IN_PROGRESS != Result); if (STATUS_SUCCESS != Result) Result = STATUS_SHARING_VIOLATION; @@ -1406,16 +1408,17 @@ static BOOLEAN FspFsvolCreateOpenOrOverwriteOplock(PIRP Irp, const FSP_FSCTL_TRA PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject; PFILE_OBJECT FileObject = IrpSp->FileObject; FSP_FILE_NODE *FileNode = FileObject->FsContext; + UINT32 RequestKind = FspIrpRequest(Irp)->Kind; ULONG OplockCount = 0; NTSTATUS Result; ASSERT( - FspFsctlTransactReservedKind == FspIrpRequest(Irp)->Kind || - FspFsctlTransactOverwriteKind == FspIrpRequest(Irp)->Kind); + FspFsctlTransactReservedKind == RequestKind || + FspFsctlTransactOverwriteKind == RequestKind); /* add oplock key to the file object */ - Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, - OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY, 0, 0, 0); + Result = FspFileNodeOplockCheckEx(FileNode, Irp, + OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY); if (!NT_SUCCESS(Result)) { *PResult = Result; @@ -1430,8 +1433,11 @@ static BOOLEAN FspFsvolCreateOpenOrOverwriteOplock(PIRP Irp, const FSP_FSCTL_TRA /* if there are more than one handles, perform oplock check */ if (1 < OplockCount) { - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, + Result = FspFileNodeOplockCheckAsyncEx( + FileNode, + FspFsctlTransactReservedKind == RequestKind ? FspFileNodeAcquireMain : FspFileNodeAcquireFull, (PVOID)Response, + Irp, FspFsvolCreateOpenOrOverwriteOplockComplete, FspFsvolCreateOpenOrOverwriteOplockPrepare); if (STATUS_PENDING == Result) @@ -1462,8 +1468,10 @@ static VOID FspFsvolCreateOpenOrOverwriteOplockPrepare( { PAGED_CODE(); - if (0 != Context) - FspIopSetIrpResponse(Irp, Context); + FSP_FSCTL_TRANSACT_RSP *Response = FspFileNodeReleaseForOplock(Context); + + if (0 != Response) + FspIopSetIrpResponse(Irp, Response); } static VOID FspFsvolCreateOpenOrOverwriteOplockComplete( diff --git a/src/sys/driver.h b/src/sys/driver.h index 7291c515..90a099b1 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -799,8 +799,6 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, BOOLEAN CreateAndPost); VOID FspWqPostIrpWorkItem(PIRP Irp); -VOID FspWqOplockPrepare(PVOID Context, PIRP Irp); -VOID FspWqOplockComplete(PVOID Context, PIRP Irp); #define FspWqCreateIrpWorkItem(I, RW, RF)\ FspWqCreateAndPostIrpWorkItem(I, RW, RF, FALSE) #define FspWqRepostIrpWorkItem(I, RW, RF)\ @@ -1236,6 +1234,68 @@ BOOLEAN FspMainFileOpenCheck(PIRP Irp) #define FspFileNodeAddrOfOplock(N) (&(N)->Header.Oplock) #endif +/* oplock support */ +typedef struct +{ + FSP_FILE_NODE *FileNode; + ULONG AcquireFlags; + PVOID PrepareContext; +} FSP_FILE_NODE_OPLOCK_CONTEXT; +static inline +BOOLEAN FspFileNodeOplockIsBatch(FSP_FILE_NODE *FileNode) +{ + return FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode)); +} +static inline +BOOLEAN FspFileNodeOplockIsHandle(FSP_FILE_NODE *FileNode) +{ + return FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(FileNode)); +} +static inline +NTSTATUS FspFileNodeOplockCheck(FSP_FILE_NODE *FileNode, PIRP Irp) +{ + return FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); +} +static inline +NTSTATUS FspFileNodeOplockCheckEx(FSP_FILE_NODE *FileNode, PIRP Irp, ULONG Flags) +{ + return FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, Flags, 0, 0, 0); +} +static inline +NTSTATUS FspFileNodeOplockBreakHandle(FSP_FILE_NODE *FileNode, PIRP Irp, ULONG Flags) +{ + return FspOplockBreakH(FspFileNodeAddrOfOplock(FileNode), Irp, Flags, 0, 0, 0); +} +static inline +NTSTATUS FspFileNodeOplockCheckAsyncEx( + FSP_FILE_NODE *FileNode, ULONG AcquireFlags, PVOID PrepareContext, + PIRP Irp, + POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine, + POPLOCK_FS_PREPOST_IRP PostIrpRoutine) +{ + FSP_FILE_NODE_OPLOCK_CONTEXT OplockContext; + OplockContext.FileNode = FileNode; + OplockContext.AcquireFlags = AcquireFlags; + OplockContext.PrepareContext = PrepareContext; + return FspCheckOplock( + FspFileNodeAddrOfOplock(FileNode), + Irp, + &OplockContext, + CompletionRoutine, + PostIrpRoutine); +} +static inline +PVOID FspFileNodeReleaseForOplock(FSP_FILE_NODE_OPLOCK_CONTEXT *OplockContext) +{ + FspFileNodeReleaseF(OplockContext->FileNode, OplockContext->AcquireFlags); + return OplockContext->PrepareContext; +} +VOID FspFileNodeOplockPrepare(PVOID Context, PIRP Irp); +VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp); +#define FspFileNodeOplockCheckAsync(FileNode, AcquireFlags, PrepareContext, Irp)\ + FspFileNodeOplockCheckAsyncEx(FileNode, AcquireFlags, (PVOID)(UINT_PTR)PrepareContext, Irp,\ + FspFileNodeOplockComplete,FspFileNodeOplockPrepare) + /* multiversion support */ typedef NTKERNELAPI diff --git a/src/sys/file.c b/src/sys/file.c index 87c9b5e1..cb7b5bbe 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -952,20 +952,18 @@ NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams( { DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex]; - if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(DescendantFileNode))) + if (FspFileNodeOplockIsBatch(DescendantFileNode)) { - NTSTATUS Result0 = FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, - 0, 0, 0); + NTSTATUS Result0 = FspFileNodeOplockCheck(DescendantFileNode, OplockIrp); if (STATUS_SUCCESS != Result0) Result = STATUS_SHARING_VIOLATION; else OplockIrp->IoStatus.Information = FILE_OPBATCH_BREAK_UNDERWAY; } else - if (FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(DescendantFileNode))) + if (FspFileNodeOplockIsHandle(DescendantFileNode)) { - NTSTATUS Result0 = FspOplockBreakH(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, - 0, 0, 0, 0); + NTSTATUS Result0 = FspFileNodeOplockBreakHandle(DescendantFileNode, OplockIrp, 0); ASSERT(STATUS_OPLOCK_BREAK_IN_PROGRESS != Result0); if (STATUS_SUCCESS != Result0) Result = STATUS_SHARING_VIOLATION; @@ -1118,9 +1116,9 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp, DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~1); if (HasOpenHandles) - if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(DescendantFileNode)) || - FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(DescendantFileNode))) - FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, 0, 0, 0); + if (FspFileNodeOplockIsBatch(DescendantFileNode) || + FspFileNodeOplockIsHandle(DescendantFileNode)) + FspFileNodeOplockCheck(DescendantFileNode, OplockIrp); } FspFsvolDeviceLockContextTable(FsvolDeviceObject); @@ -1978,6 +1976,36 @@ NTSTATUS FspMainFileClose( return Result; } +VOID FspFileNodeOplockPrepare(PVOID Context, PIRP Irp) +{ + PAGED_CODE(); + + FSP_IOP_REQUEST_WORK *WorkRoutine = (FSP_IOP_REQUEST_WORK *)(UINT_PTR) + FspFileNodeReleaseForOplock(Context); + NTSTATUS Result; + + FSP_FSCTL_STATIC_ASSERT(sizeof(PVOID) == sizeof(VOID (*)(VOID)), + "Data and code pointers must have same size!"); + + Result = FspWqCreateIrpWorkItem(Irp, WorkRoutine, 0); + if (!NT_SUCCESS(Result)) + /* + * Only way to communicate failure is through ExRaiseStatus. + * We will catch it in FspCheckOplock, etc. + */ + ExRaiseStatus(Result); +} + +VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp) +{ + PAGED_CODE(); + + if (STATUS_SUCCESS == Irp->IoStatus.Status) + FspWqPostIrpWorkItem(Irp); + else + FspIopCompleteIrp(Irp, Irp->IoStatus.Status); +} + WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*"; // {904862B4-EB3F-461E-ACB2-4DF2B3FC898B} diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index eca05360..c997a975 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -1067,13 +1067,13 @@ retry: * If that is the case we release the FileNode and wait for the oplock breaks * to complete. Once they are complete we retry the whole thing. */ - Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, - OPLOCK_FLAG_COMPLETE_IF_OPLOCKED, 0, 0, 0); + Result = FspFileNodeOplockCheckEx(FileNode, Irp, + OPLOCK_FLAG_COMPLETE_IF_OPLOCKED); if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE)) { FspFileNodeRelease(FileNode, Full); - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); + Result = FspFileNodeOplockCheck(FileNode, Irp); if (!NT_SUCCESS(Result)) return Result; goto retry; @@ -1202,14 +1202,14 @@ retry: * If that is the case we release the FileNode and wait for the oplock breaks * to complete. Once they are complete we retry the whole thing. */ - Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, - OPLOCK_FLAG_COMPLETE_IF_OPLOCKED, 0, 0, 0); + Result = FspFileNodeOplockCheckEx(FileNode, Irp, + OPLOCK_FLAG_COMPLETE_IF_OPLOCKED); if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE)) { FspFileNodeRelease(FileNode, Full); FspFsvolDeviceFileRenameRelease(FsvolDeviceObject); - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); + Result = FspFileNodeOplockCheck(FileNode, Irp); if (!NT_SUCCESS(Result)) return Result; goto retry; @@ -1425,13 +1425,13 @@ retry: * If that is the case we release the FileNode and wait for the oplock breaks * to complete. Once they are complete we retry the whole thing. */ - Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, - OPLOCK_FLAG_COMPLETE_IF_OPLOCKED, 0, 0, 0); + Result = FspFileNodeOplockCheckEx(FileNode, Irp, + OPLOCK_FLAG_COMPLETE_IF_OPLOCKED); if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE)) { FspFileNodeRelease(FileNode, Full); - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); + Result = FspFileNodeOplockCheck(FileNode, Irp); if (!NT_SUCCESS(Result)) return Result; goto retry; diff --git a/src/sys/lockctl.c b/src/sys/lockctl.c index c4f2ef4e..ba466691 100644 --- a/src/sys/lockctl.c +++ b/src/sys/lockctl.c @@ -50,9 +50,12 @@ static NTSTATUS FspFsvolLockControlRetry( return FspWqRepostIrpWorkItem(Irp, FspFsvolLockControlRetry, 0); /* perform oplock check; we are only implementing Win7 behavior */ - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, - (PVOID)(UINT_PTR)FspFsvolLockControlRetry, FspWqOplockComplete, FspWqOplockPrepare); - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + Result = FspFileNodeOplockCheckAsync( + FileNode, FspFileNodeAcquireMain, FspFsvolLockControlRetry, + Irp); + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Main); return Result; diff --git a/src/sys/read.c b/src/sys/read.c index 8162c0f1..d20227a8 100644 --- a/src/sys/read.c +++ b/src/sys/read.c @@ -117,9 +117,12 @@ static NTSTATUS FspFsvolReadCached( return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0); /* perform oplock check */ - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, - (PVOID)(UINT_PTR)FspFsvolReadCached, FspWqOplockComplete, FspWqOplockPrepare); - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + Result = FspFileNodeOplockCheckAsync( + FileNode, FspFileNodeAcquireMain, FspFsvolReadCached, + Irp); + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Main); return Result; @@ -248,9 +251,12 @@ static NTSTATUS FspFsvolReadNonCached( /* perform oplock check */ if (!PagingIo) { - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, - (PVOID)(UINT_PTR)FspFsvolReadNonCached, FspWqOplockComplete, FspWqOplockPrepare); - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + Result = FspFileNodeOplockCheckAsync( + FileNode, FspFileNodeAcquireFull, FspFsvolReadNonCached, + Irp); + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Full); return Result; diff --git a/src/sys/util.c b/src/sys/util.c index ffdb25ce..d8b5b80c 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -683,7 +683,7 @@ NTSTATUS FspOplockBreakH( try { - Result = FspOplockBreakH( + Result = FsRtlOplockBreakH( Oplock, Irp, Flags, diff --git a/src/sys/wq.c b/src/sys/wq.c index b5ab7166..6064a66c 100644 --- a/src/sys/wq.c +++ b/src/sys/wq.c @@ -173,31 +173,3 @@ static VOID FspWqWorkRoutine(PVOID Context) IoSetTopLevelIrp(0); } - -VOID FspWqOplockPrepare(PVOID Context, PIRP Irp) -{ - PAGED_CODE(); - - NTSTATUS Result; - - FSP_FSCTL_STATIC_ASSERT(sizeof(PVOID) == sizeof(VOID (*)(VOID)), - "Data and code pointers must have same size!"); - - Result = FspWqCreateAndPostIrpWorkItem(Irp, (FSP_IOP_REQUEST_WORK *)(UINT_PTR)Context, 0, TRUE); - if (!NT_SUCCESS(Result)) - /* - * Only way to communicate failure is through ExRaiseStatus. - * We will catch it in FspCheckOplock, etc. - */ - ExRaiseStatus(Result); -} - -VOID FspWqOplockComplete(PVOID Context, PIRP Irp) -{ - PAGED_CODE(); - - if (STATUS_SUCCESS == Irp->IoStatus.Status) - FspWqPostIrpWorkItem(Irp); - else - FspIopCompleteIrp(Irp, Irp->IoStatus.Status); -} diff --git a/src/sys/write.c b/src/sys/write.c index 50a557ac..00314c6e 100644 --- a/src/sys/write.c +++ b/src/sys/write.c @@ -141,9 +141,12 @@ static NTSTATUS FspFsvolWriteCached( return FspWqRepostIrpWorkItem(Irp, FspFsvolWriteCached, 0); /* perform oplock check */ - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, - (PVOID)(UINT_PTR)FspFsvolWriteCached, FspWqOplockComplete, FspWqOplockPrepare); - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + Result = FspFileNodeOplockCheckAsync( + FileNode, FspFileNodeAcquireMain, FspFsvolWriteCached, + Irp); + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Main); return Result; @@ -318,9 +321,12 @@ static NTSTATUS FspFsvolWriteNonCached( /* perform oplock check */ if (!PagingIo) { - Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, - (PVOID)(UINT_PTR)FspFsvolWriteNonCached, FspWqOplockComplete, FspWqOplockPrepare); - if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) + Result = FspFileNodeOplockCheckAsync( + FileNode, FspFileNodeAcquireFull, FspFsvolWriteNonCached, + Irp); + if (STATUS_PENDING == Result) + return Result; + if (!NT_SUCCESS(Result)) { FspFileNodeRelease(FileNode, Full); return Result;