mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -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 */
|
||||
return STATUS_CANNOT_DELETE;
|
||||
|
||||
retry:
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
|
||||
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 */
|
||||
Success = MmFlushImageSection(FileObject->SectionObjectPointer, MmFlushForDelete);
|
||||
if (!Success)
|
||||
@ -1159,9 +1185,36 @@ static NTSTATUS FspFsvolSetRenameInformation(
|
||||
ASSERT(TargetFileNode->IsDirectory);
|
||||
}
|
||||
|
||||
retry:
|
||||
FspFsvolDeviceFileRenameAcquireExclusive(FsvolDeviceObject);
|
||||
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)
|
||||
Remain = TargetFileNode->FileName;
|
||||
else
|
||||
@ -1355,16 +1408,52 @@ static NTSTATUS FspFsvolSetInformation(
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
|
||||
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))
|
||||
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->Req.SetInformation.UserContext = FileNode->UserContext;
|
||||
Request->Req.SetInformation.UserContext2 = FileDesc->UserContext2;
|
||||
Request->Req.SetInformation.FileInformationClass = FileInformationClass;
|
||||
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user