sys: oplock: refactoring/cleanup

This commit is contained in:
Bill Zissimopoulos 2016-11-20 14:08:23 -08:00
parent 53f60a698a
commit ce551d4e0d
10 changed files with 169 additions and 86 deletions

View File

@ -176,7 +176,7 @@ static VOID FspFsvolCleanupRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Co
FspFileNodeCleanupComplete(FileNode, FileObject); FspFileNodeCleanupComplete(FileNode, FileObject);
if (!FileNode->IsDirectory) if (!FileNode->IsDirectory)
FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); FspFileNodeOplockCheck(FileNode, Irp);
SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE); SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
MainFileHandle = FileDesc->MainFileHandle; MainFileHandle = FileDesc->MainFileHandle;

View File

@ -595,7 +595,9 @@ NTSTATUS FspFsvolCreatePrepare(
FspFsvolCreateOpenOrOverwriteOplock(Irp, 0, &Result); FspFsvolCreateOpenOrOverwriteOplock(Irp, 0, &Result);
if (!Success) if (!Success)
{ {
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
return Result; return Result;
@ -1047,7 +1049,9 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
FspFsvolCreateOpenOrOverwriteOplock(Irp, Response, &Result); FspFsvolCreateOpenOrOverwriteOplock(Irp, Response, &Result);
if (!Success) if (!Success)
{ {
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Main); FspFileNodeRelease(FileNode, Main);
return Result; return Result;
@ -1191,8 +1195,8 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV
if (OplockIrp) if (OplockIrp)
{ {
ASSERT(IO_TYPE_IRP == OplockIrp->Type); ASSERT(IO_TYPE_IRP == OplockIrp->Type);
FspCheckOplockEx(FspFileNodeAddrOfOplock(FileDesc->FileNode), OplockIrp, FspFileNodeOplockCheckEx(FileDesc->FileNode, OplockIrp,
OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK, 0, 0, 0); OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK);
} }
FspFsvolCreatePostClose(FileDesc); FspFsvolCreatePostClose(FileDesc);
@ -1227,8 +1231,8 @@ static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request,
if (OplockIrp) if (OplockIrp)
{ {
ASSERT(IO_TYPE_IRP == OplockIrp->Type); ASSERT(IO_TYPE_IRP == OplockIrp->Type);
FspCheckOplockEx(FspFileNodeAddrOfOplock(FileDesc->FileNode), OplockIrp, FspFileNodeOplockCheckEx(FileDesc->FileNode, OplockIrp,
OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK, 0, 0, 0); OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK);
} }
FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE); FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE);
@ -1299,9 +1303,9 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
Success = DEBUGTEST(90) && Success = DEBUGTEST(90) &&
!(FspFileNodeSharingViolationMainFile == SharingViolationReason) && !(FspFileNodeSharingViolationMainFile == SharingViolationReason) &&
!(FspFileNodeSharingViolationStream == SharingViolationReason) && !(FspFileNodeSharingViolationStream == SharingViolationReason) &&
!(FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(ExtraFileNode))) && !(FspFileNodeOplockIsBatch(ExtraFileNode)) &&
!(!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) && !(!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) &&
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(ExtraFileNode))); FspFileNodeOplockIsHandle(ExtraFileNode));
FspFileNodeRelease(ExtraFileNode, Main); FspFileNodeRelease(ExtraFileNode, Main);
@ -1354,11 +1358,10 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
Result = STATUS_SHARING_VIOLATION; Result = STATUS_SHARING_VIOLATION;
} }
else else
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(ExtraFileNode))) if (FspFileNodeOplockIsBatch(ExtraFileNode))
{ {
/* wait for Batch oplock break to complete */ /* wait for Batch oplock break to complete */
Result = FspCheckOplock(FspFileNodeAddrOfOplock(ExtraFileNode), Irp, Result = FspFileNodeOplockCheck(ExtraFileNode, Irp);
0, 0, 0);
if (STATUS_SUCCESS != Result) if (STATUS_SUCCESS != Result)
Result = STATUS_SHARING_VIOLATION; Result = STATUS_SHARING_VIOLATION;
else else
@ -1366,11 +1369,10 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
} }
else else
if (!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) && if (!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) &&
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(ExtraFileNode))) FspFileNodeOplockIsHandle(ExtraFileNode))
{ {
/* wait for Handle oplock break to complete */ /* wait for Handle oplock break to complete */
Result = FspOplockBreakH(FspFileNodeAddrOfOplock(ExtraFileNode), Irp, Result = FspFileNodeOplockBreakHandle(ExtraFileNode, Irp, 0);
0, 0, 0, 0);
ASSERT(STATUS_OPLOCK_BREAK_IN_PROGRESS != Result); ASSERT(STATUS_OPLOCK_BREAK_IN_PROGRESS != Result);
if (STATUS_SUCCESS != Result) if (STATUS_SUCCESS != Result)
Result = STATUS_SHARING_VIOLATION; Result = STATUS_SHARING_VIOLATION;
@ -1406,16 +1408,17 @@ static BOOLEAN FspFsvolCreateOpenOrOverwriteOplock(PIRP Irp, const FSP_FSCTL_TRA
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject; PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
UINT32 RequestKind = FspIrpRequest(Irp)->Kind;
ULONG OplockCount = 0; ULONG OplockCount = 0;
NTSTATUS Result; NTSTATUS Result;
ASSERT( ASSERT(
FspFsctlTransactReservedKind == FspIrpRequest(Irp)->Kind || FspFsctlTransactReservedKind == RequestKind ||
FspFsctlTransactOverwriteKind == FspIrpRequest(Irp)->Kind); FspFsctlTransactOverwriteKind == RequestKind);
/* add oplock key to the file object */ /* add oplock key to the file object */
Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckEx(FileNode, Irp,
OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY, 0, 0, 0); OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
*PResult = 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 there are more than one handles, perform oplock check */
if (1 < OplockCount) if (1 < OplockCount)
{ {
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckAsyncEx(
FileNode,
FspFsctlTransactReservedKind == RequestKind ? FspFileNodeAcquireMain : FspFileNodeAcquireFull,
(PVOID)Response, (PVOID)Response,
Irp,
FspFsvolCreateOpenOrOverwriteOplockComplete, FspFsvolCreateOpenOrOverwriteOplockComplete,
FspFsvolCreateOpenOrOverwriteOplockPrepare); FspFsvolCreateOpenOrOverwriteOplockPrepare);
if (STATUS_PENDING == Result) if (STATUS_PENDING == Result)
@ -1462,8 +1468,10 @@ static VOID FspFsvolCreateOpenOrOverwriteOplockPrepare(
{ {
PAGED_CODE(); PAGED_CODE();
if (0 != Context) FSP_FSCTL_TRANSACT_RSP *Response = FspFileNodeReleaseForOplock(Context);
FspIopSetIrpResponse(Irp, Context);
if (0 != Response)
FspIopSetIrpResponse(Irp, Response);
} }
static VOID FspFsvolCreateOpenOrOverwriteOplockComplete( static VOID FspFsvolCreateOpenOrOverwriteOplockComplete(

View File

@ -799,8 +799,6 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp,
FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini,
BOOLEAN CreateAndPost); BOOLEAN CreateAndPost);
VOID FspWqPostIrpWorkItem(PIRP Irp); VOID FspWqPostIrpWorkItem(PIRP Irp);
VOID FspWqOplockPrepare(PVOID Context, PIRP Irp);
VOID FspWqOplockComplete(PVOID Context, PIRP Irp);
#define FspWqCreateIrpWorkItem(I, RW, RF)\ #define FspWqCreateIrpWorkItem(I, RW, RF)\
FspWqCreateAndPostIrpWorkItem(I, RW, RF, FALSE) FspWqCreateAndPostIrpWorkItem(I, RW, RF, FALSE)
#define FspWqRepostIrpWorkItem(I, RW, RF)\ #define FspWqRepostIrpWorkItem(I, RW, RF)\
@ -1236,6 +1234,68 @@ BOOLEAN FspMainFileOpenCheck(PIRP Irp)
#define FspFileNodeAddrOfOplock(N) (&(N)->Header.Oplock) #define FspFileNodeAddrOfOplock(N) (&(N)->Header.Oplock)
#endif #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 */ /* multiversion support */
typedef typedef
NTKERNELAPI NTKERNELAPI

View File

@ -952,20 +952,18 @@ NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
{ {
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex]; DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(DescendantFileNode))) if (FspFileNodeOplockIsBatch(DescendantFileNode))
{ {
NTSTATUS Result0 = FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, NTSTATUS Result0 = FspFileNodeOplockCheck(DescendantFileNode, OplockIrp);
0, 0, 0);
if (STATUS_SUCCESS != Result0) if (STATUS_SUCCESS != Result0)
Result = STATUS_SHARING_VIOLATION; Result = STATUS_SHARING_VIOLATION;
else else
OplockIrp->IoStatus.Information = FILE_OPBATCH_BREAK_UNDERWAY; OplockIrp->IoStatus.Information = FILE_OPBATCH_BREAK_UNDERWAY;
} }
else else
if (FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(DescendantFileNode))) if (FspFileNodeOplockIsHandle(DescendantFileNode))
{ {
NTSTATUS Result0 = FspOplockBreakH(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, NTSTATUS Result0 = FspFileNodeOplockBreakHandle(DescendantFileNode, OplockIrp, 0);
0, 0, 0, 0);
ASSERT(STATUS_OPLOCK_BREAK_IN_PROGRESS != Result0); ASSERT(STATUS_OPLOCK_BREAK_IN_PROGRESS != Result0);
if (STATUS_SUCCESS != Result0) if (STATUS_SUCCESS != Result0)
Result = STATUS_SHARING_VIOLATION; Result = STATUS_SHARING_VIOLATION;
@ -1118,9 +1116,9 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~1); DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~1);
if (HasOpenHandles) if (HasOpenHandles)
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(DescendantFileNode)) || if (FspFileNodeOplockIsBatch(DescendantFileNode) ||
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(DescendantFileNode))) FspFileNodeOplockIsHandle(DescendantFileNode))
FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, 0, 0, 0); FspFileNodeOplockCheck(DescendantFileNode, OplockIrp);
} }
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
@ -1978,6 +1976,36 @@ NTSTATUS FspMainFileClose(
return Result; 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"*"; WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*";
// {904862B4-EB3F-461E-ACB2-4DF2B3FC898B} // {904862B4-EB3F-461E-ACB2-4DF2B3FC898B}

View File

@ -1067,13 +1067,13 @@ retry:
* If that is the case we release the FileNode and wait for the oplock breaks * 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. * to complete. Once they are complete we retry the whole thing.
*/ */
Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckEx(FileNode, Irp,
OPLOCK_FLAG_COMPLETE_IF_OPLOCKED, 0, 0, 0); OPLOCK_FLAG_COMPLETE_IF_OPLOCKED);
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result ||
DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE)) DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); Result = FspFileNodeOplockCheck(FileNode, Irp);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
goto retry; goto retry;
@ -1202,14 +1202,14 @@ retry:
* If that is the case we release the FileNode and wait for the oplock breaks * 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. * to complete. Once they are complete we retry the whole thing.
*/ */
Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckEx(FileNode, Irp,
OPLOCK_FLAG_COMPLETE_IF_OPLOCKED, 0, 0, 0); OPLOCK_FLAG_COMPLETE_IF_OPLOCKED);
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result ||
DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE)) DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject); FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); Result = FspFileNodeOplockCheck(FileNode, Irp);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
goto retry; goto retry;
@ -1425,13 +1425,13 @@ retry:
* If that is the case we release the FileNode and wait for the oplock breaks * 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. * to complete. Once they are complete we retry the whole thing.
*/ */
Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckEx(FileNode, Irp,
OPLOCK_FLAG_COMPLETE_IF_OPLOCKED, 0, 0, 0); OPLOCK_FLAG_COMPLETE_IF_OPLOCKED);
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result || if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result ||
DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE)) DEBUGTEST_EX(NT_SUCCESS(Result), 10, FALSE))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0); Result = FspFileNodeOplockCheck(FileNode, Irp);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
goto retry; goto retry;

View File

@ -50,9 +50,12 @@ static NTSTATUS FspFsvolLockControlRetry(
return FspWqRepostIrpWorkItem(Irp, FspFsvolLockControlRetry, 0); return FspWqRepostIrpWorkItem(Irp, FspFsvolLockControlRetry, 0);
/* perform oplock check; we are only implementing Win7 behavior */ /* perform oplock check; we are only implementing Win7 behavior */
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckAsync(
(PVOID)(UINT_PTR)FspFsvolLockControlRetry, FspWqOplockComplete, FspWqOplockPrepare); FileNode, FspFileNodeAcquireMain, FspFsvolLockControlRetry,
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) Irp);
if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Main); FspFileNodeRelease(FileNode, Main);
return Result; return Result;

View File

@ -117,9 +117,12 @@ static NTSTATUS FspFsvolReadCached(
return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0); return FspWqRepostIrpWorkItem(Irp, FspFsvolReadCached, 0);
/* perform oplock check */ /* perform oplock check */
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckAsync(
(PVOID)(UINT_PTR)FspFsvolReadCached, FspWqOplockComplete, FspWqOplockPrepare); FileNode, FspFileNodeAcquireMain, FspFsvolReadCached,
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) Irp);
if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Main); FspFileNodeRelease(FileNode, Main);
return Result; return Result;
@ -248,9 +251,12 @@ static NTSTATUS FspFsvolReadNonCached(
/* perform oplock check */ /* perform oplock check */
if (!PagingIo) if (!PagingIo)
{ {
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckAsync(
(PVOID)(UINT_PTR)FspFsvolReadNonCached, FspWqOplockComplete, FspWqOplockPrepare); FileNode, FspFileNodeAcquireFull, FspFsvolReadNonCached,
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) Irp);
if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
return Result; return Result;

View File

@ -683,7 +683,7 @@ NTSTATUS FspOplockBreakH(
try try
{ {
Result = FspOplockBreakH( Result = FsRtlOplockBreakH(
Oplock, Oplock,
Irp, Irp,
Flags, Flags,

View File

@ -173,31 +173,3 @@ static VOID FspWqWorkRoutine(PVOID Context)
IoSetTopLevelIrp(0); 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);
}

View File

@ -141,9 +141,12 @@ static NTSTATUS FspFsvolWriteCached(
return FspWqRepostIrpWorkItem(Irp, FspFsvolWriteCached, 0); return FspWqRepostIrpWorkItem(Irp, FspFsvolWriteCached, 0);
/* perform oplock check */ /* perform oplock check */
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckAsync(
(PVOID)(UINT_PTR)FspFsvolWriteCached, FspWqOplockComplete, FspWqOplockPrepare); FileNode, FspFileNodeAcquireMain, FspFsvolWriteCached,
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) Irp);
if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Main); FspFileNodeRelease(FileNode, Main);
return Result; return Result;
@ -318,9 +321,12 @@ static NTSTATUS FspFsvolWriteNonCached(
/* perform oplock check */ /* perform oplock check */
if (!PagingIo) if (!PagingIo)
{ {
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, Result = FspFileNodeOplockCheckAsync(
(PVOID)(UINT_PTR)FspFsvolWriteNonCached, FspWqOplockComplete, FspWqOplockPrepare); FileNode, FspFileNodeAcquireFull, FspFsvolWriteNonCached,
if (!NT_SUCCESS(Result) || STATUS_PENDING == Result) Irp);
if (STATUS_PENDING == Result)
return Result;
if (!NT_SUCCESS(Result))
{ {
FspFileNodeRelease(FileNode, Full); FspFileNodeRelease(FileNode, Full);
return Result; return Result;