mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: fileinfo: oplocks
This commit is contained in:
parent
764b772731
commit
f49cf412a8
@ -1050,10 +1050,36 @@ static NTSTATUS FspFsvolSetDispositionInformation(
|
|||||||
/* cannot delete root directory */
|
/* cannot delete root directory */
|
||||||
return STATUS_CANNOT_DELETE;
|
return STATUS_CANNOT_DELETE;
|
||||||
|
|
||||||
|
retry:
|
||||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||||
|
|
||||||
if (Info->DeleteFile)
|
if (Info->DeleteFile)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Perform oplock check.
|
||||||
|
*
|
||||||
|
* It is ok to block our thread during receipt of the SetInformation IRP.
|
||||||
|
* However we cannot acquire the FileNode exclusive and wait for oplock
|
||||||
|
* breaks to complete, because oplock break processing acquires the FileNode
|
||||||
|
* shared.
|
||||||
|
*
|
||||||
|
* Instead we initiate the oplock breaks and then check if any are in progress.
|
||||||
|
* 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);
|
||||||
|
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result)
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto unlock_exit;
|
||||||
|
|
||||||
/* make sure no process is mapping the file as an image */
|
/* make sure no process is mapping the file as an image */
|
||||||
Success = MmFlushImageSection(FileObject->SectionObjectPointer, MmFlushForDelete);
|
Success = MmFlushImageSection(FileObject->SectionObjectPointer, MmFlushForDelete);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
@ -1159,9 +1185,36 @@ static NTSTATUS FspFsvolSetRenameInformation(
|
|||||||
ASSERT(TargetFileNode->IsDirectory);
|
ASSERT(TargetFileNode->IsDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retry:
|
||||||
FspFsvolDeviceFileRenameAcquireExclusive(FsvolDeviceObject);
|
FspFsvolDeviceFileRenameAcquireExclusive(FsvolDeviceObject);
|
||||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform oplock check.
|
||||||
|
*
|
||||||
|
* It is ok to block our thread during receipt of the SetInformation IRP.
|
||||||
|
* However we cannot acquire the FileNode exclusive and wait for oplock
|
||||||
|
* breaks to complete, because oplock break processing acquires the FileNode
|
||||||
|
* shared.
|
||||||
|
*
|
||||||
|
* Instead we initiate the oplock breaks and then check if any are in progress.
|
||||||
|
* 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);
|
||||||
|
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result)
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
FspFsvolDeviceFileRenameRelease(FsvolDeviceObject);
|
||||||
|
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto unlock_exit;
|
||||||
|
|
||||||
if (0 != TargetFileNode)
|
if (0 != TargetFileNode)
|
||||||
Remain = TargetFileNode->FileName;
|
Remain = TargetFileNode->FileName;
|
||||||
else
|
else
|
||||||
@ -1355,16 +1408,52 @@ static NTSTATUS FspFsvolSetInformation(
|
|||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolSetInformationRequestFini, &Request);
|
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||||
|
|
||||||
|
if (FileAllocationInformation == FileInformationClass ||
|
||||||
|
FileEndOfFileInformation == FileInformationClass)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Perform oplock check.
|
||||||
|
*
|
||||||
|
* It is ok to block our thread during receipt of the SetInformation IRP.
|
||||||
|
* However we cannot acquire the FileNode exclusive and wait for oplock
|
||||||
|
* breaks to complete, because oplock break processing acquires the FileNode
|
||||||
|
* shared.
|
||||||
|
*
|
||||||
|
* Instead we initiate the oplock breaks and then check if any are in progress.
|
||||||
|
* 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);
|
||||||
|
if (STATUS_OPLOCK_BREAK_IN_PROGRESS == Result)
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp, 0, 0, 0);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolSetInformationRequestFini, &Request);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
Request->Kind = FspFsctlTransactSetInformationKind;
|
Request->Kind = FspFsctlTransactSetInformationKind;
|
||||||
Request->Req.SetInformation.UserContext = FileNode->UserContext;
|
Request->Req.SetInformation.UserContext = FileNode->UserContext;
|
||||||
Request->Req.SetInformation.UserContext2 = FileDesc->UserContext2;
|
Request->Req.SetInformation.UserContext2 = FileDesc->UserContext2;
|
||||||
Request->Req.SetInformation.FileInformationClass = FileInformationClass;
|
Request->Req.SetInformation.FileInformationClass = FileInformationClass;
|
||||||
|
|
||||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user