mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: oplock testing
This commit is contained in:
parent
6a48087d5f
commit
959d8537c6
@ -649,7 +649,8 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
/* did the user-mode file system sent us a failure code? */
|
/* did the user-mode file system sent us a failure code? */
|
||||||
if (!NT_SUCCESS(Response->IoStatus.Status))
|
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = STATUS_SHARING_VIOLATION == Response->IoStatus.Status ?
|
||||||
|
Response->IoStatus.Information : 0;
|
||||||
Result = Response->IoStatus.Status;
|
Result = Response->IoStatus.Status;
|
||||||
FSP_RETURN();
|
FSP_RETURN();
|
||||||
}
|
}
|
||||||
@ -842,8 +843,10 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
{
|
{
|
||||||
if (STATUS_SHARING_VIOLATION == Result)
|
if (STATUS_SHARING_VIOLATION == Result)
|
||||||
{
|
{
|
||||||
|
ASSERT(0 != OpenedFileNode);
|
||||||
|
|
||||||
FspIopSetIrpResponse(Irp, Response);
|
FspIopSetIrpResponse(Irp, Response);
|
||||||
FspIopRequestContext(Request, FspIopRequestExtraContext) = FileNode;
|
FspIopRequestContext(Request, FspIopRequestExtraContext) = OpenedFileNode;
|
||||||
|
|
||||||
Result = FspFsvolCreateSharingViolationOplock(
|
Result = FspFsvolCreateSharingViolationOplock(
|
||||||
FsvolDeviceObject, Irp, IrpSp, FALSE);
|
FsvolDeviceObject, Irp, IrpSp, FALSE);
|
||||||
@ -1240,13 +1243,13 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
|
|||||||
|
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
FSP_FSCTL_TRANSACT_RSP *Response;
|
FSP_FSCTL_TRANSACT_RSP *Response;
|
||||||
FSP_FILE_NODE *FileNode = FspIopRequestContext(Request, FspIopRequestExtraContext);
|
FSP_FILE_NODE *ExtraFileNode = FspIopRequestContext(Request, FspIopRequestExtraContext);
|
||||||
BOOLEAN OpbatchBreakUnderway = FALSE;
|
BOOLEAN OpbatchBreakUnderway = FALSE;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
|
|
||||||
Success = DEBUGTEST(90) &&
|
Success = DEBUGTEST(90) &&
|
||||||
FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait);
|
FspFileNodeTryAcquireSharedF(ExtraFileNode, FspFileNodeAcquireMain, CanWait);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
return FspWqRepostIrpWorkItem(Irp,
|
return FspWqRepostIrpWorkItem(Irp,
|
||||||
FspFsvolCreateSharingViolationOplock, FspFsvolCreateRequestFini);
|
FspFsvolCreateSharingViolationOplock, FspFsvolCreateRequestFini);
|
||||||
@ -1257,11 +1260,11 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
|
|||||||
* If there is no batch or CACHE_HANDLE_LEVEL oplock we are done;
|
* If there is no batch or CACHE_HANDLE_LEVEL oplock we are done;
|
||||||
* else retry in a worker thread to break the oplocks.
|
* else retry in a worker thread to break the oplocks.
|
||||||
*/
|
*/
|
||||||
Success = !FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode)) &&
|
Success = !FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(ExtraFileNode)) &&
|
||||||
(FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) ||
|
(FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) ||
|
||||||
!FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(FileNode)));
|
!FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(ExtraFileNode)));
|
||||||
|
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(ExtraFileNode, Main);
|
||||||
|
|
||||||
if (!Success)
|
if (!Success)
|
||||||
return FspWqRepostIrpWorkItem(Irp,
|
return FspWqRepostIrpWorkItem(Irp,
|
||||||
@ -1274,7 +1277,7 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
|
|||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* ???: is this needed in this case? */
|
/* ???: is this needed in this case? */
|
||||||
Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(FileNode), Irp,
|
Result = FspCheckOplockEx(FspFileNodeAddrOfOplock(ExtraFileNode), Irp,
|
||||||
OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY, 0, 0, 0);
|
OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY, 0, 0, 0);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
@ -1283,10 +1286,10 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode)))
|
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(ExtraFileNode)))
|
||||||
{
|
{
|
||||||
/* wait for batch oplock break to complete */
|
/* wait for batch oplock break to complete */
|
||||||
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp,
|
Result = FspCheckOplock(FspFileNodeAddrOfOplock(ExtraFileNode), Irp,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (STATUS_SUCCESS == Result)
|
if (STATUS_SUCCESS == Result)
|
||||||
OpbatchBreakUnderway = TRUE;
|
OpbatchBreakUnderway = TRUE;
|
||||||
@ -1295,24 +1298,24 @@ static NTSTATUS FspFsvolCreateSharingViolationOplock(
|
|||||||
Result = STATUS_SHARING_VIOLATION;
|
Result = STATUS_SHARING_VIOLATION;
|
||||||
|
|
||||||
if (!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) &&
|
if (!FlagOn(IrpSp->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) &&
|
||||||
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(FileNode)))
|
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(ExtraFileNode)))
|
||||||
{
|
{
|
||||||
/* wait for CACHE_HANDLE_LEVEL oplock break to complete */
|
/* wait for CACHE_HANDLE_LEVEL oplock break to complete */
|
||||||
Result = FspOplockBreakH(FspFileNodeAddrOfOplock(FileNode), Irp,
|
Result = FspOplockBreakH(FspFileNodeAddrOfOplock(ExtraFileNode), Irp,
|
||||||
0, 0, 0, 0);
|
0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
exit:
|
exit:
|
||||||
#endif
|
#endif
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(ExtraFileNode, Main);
|
||||||
|
|
||||||
Response = FspIopIrpResponse(Irp);
|
Response = FspIopIrpResponse(Irp);
|
||||||
|
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
FspFileNodeClose(FileNode, 0, TRUE);
|
FspFileNodeClose(ExtraFileNode, 0, TRUE);
|
||||||
FspFileNodeDereference(FileNode);
|
FspFileNodeDereference(ExtraFileNode);
|
||||||
FspIopRequestContext(Request, FspIopRequestExtraContext) = 0;
|
FspIopRequestContext(Request, FspIopRequestExtraContext) = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1114,7 +1114,7 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
|||||||
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
||||||
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||||
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
||||||
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
||||||
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName);
|
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName);
|
||||||
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
|
@ -41,7 +41,7 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
|||||||
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
||||||
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||||
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
||||||
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
||||||
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName);
|
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName);
|
||||||
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
@ -493,6 +493,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
FlagOn(GrantedAccess,
|
FlagOn(GrantedAccess,
|
||||||
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE))
|
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE))
|
||||||
{
|
{
|
||||||
|
OpenedFileNode = FileNode->MainFileNode;
|
||||||
Result = STATUS_SHARING_VIOLATION;
|
Result = STATUS_SHARING_VIOLATION;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -833,7 +834,7 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
|||||||
return IoStatus.Status;
|
return IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
||||||
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName)
|
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -860,6 +861,8 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
|||||||
DescendantFileNodes = DescendantFileNodeArray;
|
DescendantFileNodes = DescendantFileNodeArray;
|
||||||
DescendantFileNodeCount = 0;
|
DescendantFileNodeCount = 0;
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
/* if we are checking the existing file name, do a quick check here */
|
/* if we are checking the existing file name, do a quick check here */
|
||||||
if (CheckingOldName)
|
if (CheckingOldName)
|
||||||
{
|
{
|
||||||
@ -873,8 +876,6 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
|||||||
/* Note: when CheckingOldName==TRUE, the old FileNode is not included in enumerations below */
|
/* Note: when CheckingOldName==TRUE, the old FileNode is not included in enumerations below */
|
||||||
}
|
}
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
/* count descendant file nodes and try to gather them in a local array if possible */
|
/* count descendant file nodes and try to gather them in a local array if possible */
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
memset(&RestartKey, 0, sizeof RestartKey);
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -895,6 +896,12 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
|||||||
DescendantFileNodeCount++;
|
DescendantFileNodeCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 == DescendantFileNodeCount)
|
||||||
|
{
|
||||||
|
ASSERT(Success);
|
||||||
|
goto unlock_exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the local array is out of space, gather descendant file nodes in the pool */
|
/* if the local array is out of space, gather descendant file nodes in the pool */
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount)
|
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount)
|
||||||
{
|
{
|
||||||
@ -956,7 +963,7 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
|||||||
DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~1);
|
DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~1);
|
||||||
|
|
||||||
if (HasOpenHandles)
|
if (HasOpenHandles)
|
||||||
FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), Irp, 0, 0, 0);
|
FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), OplockIrp, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
@ -1280,7 +1280,7 @@ retry:
|
|||||||
* that has open handles (except in the batch-oplock case described earlier).
|
* that has open handles (except in the batch-oplock case described earlier).
|
||||||
*/
|
*/
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
if (!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, FileNode, &FileNode->FileName) &&
|
if (!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, FileNode, &FileNode->FileName) ||
|
||||||
!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, 0, &NewFileName))
|
!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, 0, &NewFileName))
|
||||||
Result = STATUS_ACCESS_DENIED;
|
Result = STATUS_ACCESS_DENIED;
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
|
@ -164,6 +164,7 @@ NTSTATUS FspIopCreateRequestWorkItem(FSP_FSCTL_TRANSACT_REQ *Request)
|
|||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem);
|
RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem);
|
||||||
|
RequestHeader->WorkItem = RequestWorkItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -93,6 +93,9 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp,
|
|||||||
ExInitializeWorkItem(&RequestWorkItem->WorkQueueItem, FspWqWorkRoutine, Irp);
|
ExInitializeWorkItem(&RequestWorkItem->WorkQueueItem, FspWqWorkRoutine, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT(RequestFini == ((FSP_FSCTL_TRANSACT_REQ_HEADER *)
|
||||||
|
((PUINT8)Request - sizeof(FSP_FSCTL_TRANSACT_REQ_HEADER)))->RequestFini);
|
||||||
|
|
||||||
if (!CreateAndPost)
|
if (!CreateAndPost)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
@ -117,6 +120,7 @@ VOID FspWqPostIrpWorkItem(PIRP Irp)
|
|||||||
case IRP_MJ_WRITE:
|
case IRP_MJ_WRITE:
|
||||||
case IRP_MJ_DIRECTORY_CONTROL:
|
case IRP_MJ_DIRECTORY_CONTROL:
|
||||||
case IRP_MJ_LOCK_CONTROL:
|
case IRP_MJ_LOCK_CONTROL:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user