mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
sys: fsctl: oplock fixes
This commit is contained in:
parent
ce551d4e0d
commit
127d4cc4eb
@ -1451,7 +1451,7 @@ static BOOLEAN FspFsvolCreateOpenOrOverwriteOplock(PIRP Irp, const FSP_FSCTL_TRA
|
|||||||
if (STATUS_SUCCESS == Result &&
|
if (STATUS_SUCCESS == Result &&
|
||||||
FlagOn(IrpSp->Parameters.Create.Options, FILE_OPEN_REQUIRING_OPLOCK))
|
FlagOn(IrpSp->Parameters.Create.Options, FILE_OPEN_REQUIRING_OPLOCK))
|
||||||
{
|
{
|
||||||
Result = FspOplockFsctrlCreate(FspFileNodeAddrOfOplock(FileNode), Irp, OplockCount);
|
Result = FspFileNodeOplockFsctl(FileNode, Irp, OplockCount);
|
||||||
ASSERT(STATUS_PENDING != Result);
|
ASSERT(STATUS_PENDING != Result);
|
||||||
|
|
||||||
if (STATUS_SUCCESS == Result)
|
if (STATUS_SUCCESS == Result)
|
||||||
|
@ -537,11 +537,10 @@ NTSTATUS FspCheckOplockEx(
|
|||||||
PVOID Context,
|
PVOID Context,
|
||||||
POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine,
|
POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine,
|
||||||
POPLOCK_FS_PREPOST_IRP PostIrpRoutine);
|
POPLOCK_FS_PREPOST_IRP PostIrpRoutine);
|
||||||
NTSTATUS FspOplockFsctrlF(
|
NTSTATUS FspOplockFsctrl(
|
||||||
POPLOCK Oplock,
|
POPLOCK Oplock,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
ULONG OpenCount,
|
ULONG OpenCount);
|
||||||
BOOLEAN Create);
|
|
||||||
#define FspNotifyUninitializeSync(NS)\
|
#define FspNotifyUninitializeSync(NS)\
|
||||||
FsRtlNotifyUninitializeSync(NS)
|
FsRtlNotifyUninitializeSync(NS)
|
||||||
#define FspNotifyCleanupAll(NS, NL)\
|
#define FspNotifyCleanupAll(NS, NL)\
|
||||||
@ -554,10 +553,6 @@ NTSTATUS FspOplockFsctrlF(
|
|||||||
FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0)
|
FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0)
|
||||||
#define FspNotifyReportChange(NS, NL, FN, FO, NP, F, A)\
|
#define FspNotifyReportChange(NS, NL, FN, FO, NP, F, A)\
|
||||||
FspNotifyFullReportChange(NS, NL, (PSTRING)(FN), FO, 0, (PSTRING)(NP), F, A, 0)
|
FspNotifyFullReportChange(NS, NL, (PSTRING)(FN), FO, 0, (PSTRING)(NP), F, A, 0)
|
||||||
#define FspOplockFsctrlCreate(OL, I, OC)\
|
|
||||||
FspOplockFsctrlF(OL, I, OC, TRUE)
|
|
||||||
#define FspOplockFsctrl(OL, I, OC)\
|
|
||||||
FspOplockFsctrlF(OL, I, OC, FALSE)
|
|
||||||
|
|
||||||
/* utility: synchronous work queue */
|
/* utility: synchronous work queue */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -1242,6 +1237,11 @@ typedef struct
|
|||||||
PVOID PrepareContext;
|
PVOID PrepareContext;
|
||||||
} FSP_FILE_NODE_OPLOCK_CONTEXT;
|
} FSP_FILE_NODE_OPLOCK_CONTEXT;
|
||||||
static inline
|
static inline
|
||||||
|
NTSTATUS FspFileNodeOplockFsctl(FSP_FILE_NODE *FileNode, PIRP Irp, ULONG OpenCount)
|
||||||
|
{
|
||||||
|
return FspOplockFsctrl(FspFileNodeAddrOfOplock(FileNode), Irp, OpenCount);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
BOOLEAN FspFileNodeOplockIsBatch(FSP_FILE_NODE *FileNode)
|
BOOLEAN FspFileNodeOplockIsBatch(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
return FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode));
|
return FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode));
|
||||||
|
@ -432,30 +432,18 @@ static NTSTATUS FspFsvolFileSystemControlOplock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is possible for FspOplockFsctrl to complete the IRP immediately.
|
* FspOplockFsctrl takes ownership of the IRP under all circumstances.
|
||||||
* In this case trying to access the IRP (to get its IrpFlags) in FspFileNodeRelease
|
|
||||||
* can lead to a bugcheck. For this reason we set the TopLevelIrp to NULL here.
|
|
||||||
*
|
*
|
||||||
* FspFsvolFileSystemControlOplock does not need the TopLevelIrp functionality,
|
* We mark the IRP pending so that we can safely return STATUS_PENDING.
|
||||||
* because it cannot be used recursively (I believe -- famous last words).
|
|
||||||
*/
|
*/
|
||||||
PIRP TopLevelIrp = IoGetTopLevelIrp();
|
|
||||||
IoSetTopLevelIrp(0);
|
IoSetTopLevelIrp(0);
|
||||||
|
|
||||||
Result = FspOplockFsctrl(FspFileNodeAddrOfOplock(FileNode), Irp, OplockCount);
|
IoMarkIrpPending(Irp);
|
||||||
|
Result = FspFileNodeOplockFsctl(FileNode, Irp, OplockCount);
|
||||||
|
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(FileNode, Main);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
/* set back the top level IRP just in case! */
|
|
||||||
IoSetTopLevelIrp(TopLevelIrp);
|
|
||||||
|
|
||||||
FspIrpHookReset(Irp);
|
|
||||||
FspFree(CompletionContext);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
|
|
||||||
unlock_exit:
|
unlock_exit:
|
||||||
|
@ -87,11 +87,10 @@ NTSTATUS FspCheckOplockEx(
|
|||||||
PVOID Context,
|
PVOID Context,
|
||||||
POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine,
|
POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine,
|
||||||
POPLOCK_FS_PREPOST_IRP PostIrpRoutine);
|
POPLOCK_FS_PREPOST_IRP PostIrpRoutine);
|
||||||
NTSTATUS FspOplockFsctrlF(
|
NTSTATUS FspOplockFsctrl(
|
||||||
POPLOCK Oplock,
|
POPLOCK Oplock,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
ULONG OpenCount,
|
ULONG OpenCount);
|
||||||
BOOLEAN Create);
|
|
||||||
VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem,
|
VOID FspInitializeSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem,
|
||||||
PWORKER_THREAD_ROUTINE Routine, PVOID Context);
|
PWORKER_THREAD_ROUTINE Routine, PVOID Context);
|
||||||
VOID FspExecuteSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem);
|
VOID FspExecuteSynchronousWorkItem(FSP_SYNCHRONOUS_WORK_ITEM *SynchronousWorkItem);
|
||||||
@ -132,7 +131,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
|||||||
#pragma alloc_text(PAGE, FspOplockBreakH)
|
#pragma alloc_text(PAGE, FspOplockBreakH)
|
||||||
#pragma alloc_text(PAGE, FspCheckOplock)
|
#pragma alloc_text(PAGE, FspCheckOplock)
|
||||||
#pragma alloc_text(PAGE, FspCheckOplockEx)
|
#pragma alloc_text(PAGE, FspCheckOplockEx)
|
||||||
#pragma alloc_text(PAGE, FspOplockFsctrlF)
|
#pragma alloc_text(PAGE, FspOplockFsctrl)
|
||||||
#pragma alloc_text(PAGE, FspInitializeSynchronousWorkItem)
|
#pragma alloc_text(PAGE, FspInitializeSynchronousWorkItem)
|
||||||
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItem)
|
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItem)
|
||||||
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItemRoutine)
|
#pragma alloc_text(PAGE, FspExecuteSynchronousWorkItemRoutine)
|
||||||
@ -757,11 +756,10 @@ NTSTATUS FspCheckOplockEx(
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspOplockFsctrlF(
|
NTSTATUS FspOplockFsctrl(
|
||||||
POPLOCK Oplock,
|
POPLOCK Oplock,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
ULONG OpenCount,
|
ULONG OpenCount)
|
||||||
BOOLEAN Create)
|
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
@ -769,21 +767,10 @@ NTSTATUS FspOplockFsctrlF(
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ASSERT(
|
|
||||||
(Create && IRP_MJ_CREATE == IoGetCurrentIrpStackLocation(Irp)->MajorFunction) ||
|
|
||||||
(!Create && IRP_MJ_FILE_SYSTEM_CONTROL == IoGetCurrentIrpStackLocation(Irp)->MajorFunction));
|
|
||||||
|
|
||||||
Result = FsRtlOplockFsctrl(
|
Result = FsRtlOplockFsctrl(
|
||||||
Oplock,
|
Oplock,
|
||||||
Irp,
|
Irp,
|
||||||
OpenCount);
|
OpenCount);
|
||||||
|
|
||||||
/*
|
|
||||||
* When the IRP is IRP_MJ_FILE_SYSTEM_CONTROL, FsRtlOplockFsctrl always takes ownership
|
|
||||||
* of the IRP (unless it raises). So return STATUS_SUCCESS in that case.
|
|
||||||
*/
|
|
||||||
if (!Create)
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
except (EXCEPTION_EXECUTE_HANDLER)
|
except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user