mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: ioq: now supports IRP expiration
This commit is contained in:
parent
3ae924e3f9
commit
9e82247366
@ -392,7 +392,7 @@ VOID FspFsvolCreateComplete(
|
|||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIopRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
|
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
|
||||||
ULONG CreateOptions = IrpSp->Parameters.Create.Options;
|
ULONG CreateOptions = IrpSp->Parameters.Create.Options;
|
||||||
@ -672,7 +672,7 @@ static VOID FspFsvolCreateCleanupClose(
|
|||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
||||||
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
|
FspFsvrtDeviceExtension(FsvolDeviceExtension->FsvrtDeviceObject);
|
||||||
FSP_FSCTL_TRANSACT_REQ *OriginalRequest = FspIopRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *OriginalRequest = FspIrpRequest(Irp);
|
||||||
FSP_FILE_CONTEXT *FsContext = FspIopRequestContext(OriginalRequest, RequestFsContext);
|
FSP_FILE_CONTEXT *FsContext = FspIopRequestContext(OriginalRequest, RequestFsContext);
|
||||||
UINT64 UserContext = Response->Rsp.Create.Opened.UserContext;
|
UINT64 UserContext = Response->Rsp.Create.Opened.UserContext;
|
||||||
UINT64 UserContext2 = Response->Rsp.Create.Opened.UserContext2;
|
UINT64 UserContext2 = Response->Rsp.Create.Opened.UserContext2;
|
||||||
|
@ -245,6 +245,13 @@ FAST_IO_RELEASE_FOR_MOD_WRITE FspReleaseForModWrite;
|
|||||||
FAST_IO_ACQUIRE_FOR_CCFLUSH FspAcquireForCcFlush;
|
FAST_IO_ACQUIRE_FOR_CCFLUSH FspAcquireForCcFlush;
|
||||||
FAST_IO_RELEASE_FOR_CCFLUSH FspReleaseForCcFlush;
|
FAST_IO_RELEASE_FOR_CCFLUSH FspReleaseForCcFlush;
|
||||||
|
|
||||||
|
/* IRP context */
|
||||||
|
#define FspIrpTimestamp(Irp) \
|
||||||
|
(*(ULONGLONG *)&(Irp)->Tail.Overlay.DriverContext[0])
|
||||||
|
/* FspIrpTimestamp() uses up DriverContext[0] and [1] in 32-bit builds */
|
||||||
|
#define FspIrpRequest(Irp) \
|
||||||
|
(*(FSP_FSCTL_TRANSACT_REQ **)&(Irp)->Tail.Overlay.DriverContext[2])
|
||||||
|
|
||||||
/* I/O queue */
|
/* I/O queue */
|
||||||
#define FspIoqTimeout ((PIRP)1)
|
#define FspIoqTimeout ((PIRP)1)
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -258,6 +265,7 @@ typedef struct
|
|||||||
VOID FspIoqInitialize(FSP_IOQ *Ioq);
|
VOID FspIoqInitialize(FSP_IOQ *Ioq);
|
||||||
VOID FspIoqStop(FSP_IOQ *Ioq);
|
VOID FspIoqStop(FSP_IOQ *Ioq);
|
||||||
BOOLEAN FspIoqStopped(FSP_IOQ *Ioq);
|
BOOLEAN FspIoqStopped(FSP_IOQ *Ioq);
|
||||||
|
VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout);
|
||||||
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout);
|
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout);
|
||||||
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
@ -266,8 +274,6 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
|||||||
/* I/O processing */
|
/* I/O processing */
|
||||||
#define FSP_FSCTL_WORK \
|
#define FSP_FSCTL_WORK \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'W', METHOD_NEITHER, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'W', METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||||
#define FspIopRequest(Irp) \
|
|
||||||
(*(FSP_FSCTL_TRANSACT_REQ **)&(Irp)->Tail.Overlay.DriverContext[0])
|
|
||||||
#define FspIopRequestContext(Request, I)\
|
#define FspIopRequestContext(Request, I)\
|
||||||
(*FspIopRequestContextAddress(Request, I))
|
(*FspIopRequestContextAddress(Request, I))
|
||||||
#define FspIopCreateRequest(I, F, E, P) FspIopCreateRequestEx(I, F, E, 0, P)
|
#define FspIopCreateRequest(I, F, E, P) FspIopCreateRequestEx(I, F, E, 0, P)
|
||||||
|
@ -473,7 +473,7 @@ static NTSTATUS FspFsvrtTransact(
|
|||||||
ASSERT(FspFsctlTransactCanProduceRequest(Request, SystemBufferEnd));
|
ASSERT(FspFsctlTransactCanProduceRequest(Request, SystemBufferEnd));
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
PendingIrpRequest = FspIopRequest(PendingIrp);
|
PendingIrpRequest = FspIrpRequest(PendingIrp);
|
||||||
|
|
||||||
Result = FspIopDispatchPrepare(PendingIrp, PendingIrpRequest);
|
Result = FspIopDispatchPrepare(PendingIrp, PendingIrpRequest);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
|
@ -42,7 +42,7 @@ static NTSTATUS FspFsvolInternalDeviceControl(
|
|||||||
|
|
||||||
/* associate the passed Request with our Irp; acquire ownership of the Request */
|
/* associate the passed Request with our Irp; acquire ownership of the Request */
|
||||||
Request->Hint = (UINT_PTR)Irp;
|
Request->Hint = (UINT_PTR)Irp;
|
||||||
FspIopRequest(Irp) = Request;
|
FspIrpRequest(Irp) = Request;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Post the IRP to our Ioq; we do this here instead of at IRP_LEAVE_MJ time,
|
* Post the IRP to our Ioq; we do this here instead of at IRP_LEAVE_MJ time,
|
||||||
@ -55,7 +55,7 @@ static NTSTATUS FspFsvolInternalDeviceControl(
|
|||||||
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
||||||
|
|
||||||
Request->Hint = 0;
|
Request->Hint = 0;
|
||||||
FspIopRequest(Irp) = 0;
|
FspIrpRequest(Irp) = 0;
|
||||||
|
|
||||||
Result = STATUS_CANCELLED;
|
Result = STATUS_CANCELLED;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -71,7 +71,7 @@ NTSTATUS FspIopCreateRequestEx(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (0 != Irp)
|
if (0 != Irp)
|
||||||
FspIopRequest(Irp) = Request;
|
FspIrpRequest(Irp) = Request;
|
||||||
*PRequest = Request;
|
*PRequest = Request;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -152,10 +152,10 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease)
|
|||||||
|
|
||||||
ASSERT(STATUS_PENDING != Result);
|
ASSERT(STATUS_PENDING != Result);
|
||||||
|
|
||||||
if (0 != FspIopRequest(Irp))
|
if (0 != FspIrpRequest(Irp))
|
||||||
{
|
{
|
||||||
FspIopDeleteRequest(FspIopRequest(Irp));
|
FspIopDeleteRequest(FspIrpRequest(Irp));
|
||||||
FspIopRequest(Irp) = 0;
|
FspIrpRequest(Irp) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the device object out of the IRP before completion */
|
/* get the device object out of the IRP before completion */
|
||||||
|
@ -55,6 +55,12 @@
|
|||||||
* queue is not empty.
|
* queue is not empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PVOID IrpHint;
|
||||||
|
ULONGLONG ExpirationTime;
|
||||||
|
} FSP_IOQ_PEEK_CONTEXT;
|
||||||
|
|
||||||
static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
||||||
@ -81,6 +87,20 @@ static PIRP FspIoqPendingPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext)
|
|||||||
return 0;
|
return 0;
|
||||||
PLIST_ENTRY Head = &Ioq->PendingIrpList;
|
PLIST_ENTRY Head = &Ioq->PendingIrpList;
|
||||||
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
||||||
|
if (!PeekContext)
|
||||||
|
return Head != Entry ? CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry) : 0;
|
||||||
|
PVOID IrpHint = ((FSP_IOQ_PEEK_CONTEXT *)PeekContext)->IrpHint;
|
||||||
|
if (0 == IrpHint)
|
||||||
|
{
|
||||||
|
if (Head != Entry)
|
||||||
|
{
|
||||||
|
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
if (FspIrpTimestamp(Irp) <= ((FSP_IOQ_PEEK_CONTEXT *)PeekContext)->ExpirationTime)
|
||||||
|
/* IRP has expired; return it */
|
||||||
|
return Irp;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return Head != Entry ? CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry) : 0;
|
return Head != Entry ? CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +146,22 @@ static PIRP FspIoqProcessPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext)
|
|||||||
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
||||||
if (!PeekContext)
|
if (!PeekContext)
|
||||||
return Head != Entry ? CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry) : 0;
|
return Head != Entry ? CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry) : 0;
|
||||||
|
PVOID IrpHint = ((FSP_IOQ_PEEK_CONTEXT *)PeekContext)->IrpHint;
|
||||||
|
if (0 == IrpHint)
|
||||||
|
{
|
||||||
|
if (Head != Entry)
|
||||||
|
{
|
||||||
|
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
if (FspIrpTimestamp(Irp) <= ((FSP_IOQ_PEEK_CONTEXT *)PeekContext)->ExpirationTime)
|
||||||
|
/* IRP has expired; return it */
|
||||||
|
return Irp;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for (; Head != Entry; Entry = Entry->Flink)
|
for (; Head != Entry; Entry = Entry->Flink)
|
||||||
{
|
{
|
||||||
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||||
if (Irp == PeekContext)
|
if (Irp == IrpHint)
|
||||||
return Irp;
|
return Irp;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -202,9 +234,22 @@ BOOLEAN FspIoqStopped(FSP_IOQ *Ioq)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout)
|
||||||
|
{
|
||||||
|
FSP_IOQ_PEEK_CONTEXT PeekContext;
|
||||||
|
PeekContext.IrpHint = 0;
|
||||||
|
PeekContext.ExpirationTime = KeQueryInterruptTime() - Timeout->QuadPart;
|
||||||
|
PIRP Irp;
|
||||||
|
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, &PeekContext)))
|
||||||
|
FspIoqPendingCompleteCanceledIrp(&Ioq->PendingIoCsq, Irp);
|
||||||
|
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, &PeekContext)))
|
||||||
|
FspIoqProcessCompleteCanceledIrp(&Ioq->ProcessIoCsq, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
|
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
FspIrpTimestamp(Irp) = KeQueryInterruptTime();
|
||||||
Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, 0);
|
Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, 0);
|
||||||
return NT_SUCCESS(Result);
|
return NT_SUCCESS(Result);
|
||||||
}
|
}
|
||||||
@ -221,12 +266,16 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout)
|
|||||||
if (STATUS_TIMEOUT == Result)
|
if (STATUS_TIMEOUT == Result)
|
||||||
return FspIoqTimeout;
|
return FspIoqTimeout;
|
||||||
}
|
}
|
||||||
return IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, (PVOID)1);
|
FSP_IOQ_PEEK_CONTEXT PeekContext;
|
||||||
|
PeekContext.IrpHint = (PVOID)1;
|
||||||
|
PeekContext.ExpirationTime = 0;
|
||||||
|
return IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, &PeekContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp)
|
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
FspIrpTimestamp(Irp) = KeQueryInterruptTime();
|
||||||
Result = IoCsqInsertIrpEx(&Ioq->ProcessIoCsq, Irp, 0, 0);
|
Result = IoCsqInsertIrpEx(&Ioq->ProcessIoCsq, Irp, 0, 0);
|
||||||
return NT_SUCCESS(Result);
|
return NT_SUCCESS(Result);
|
||||||
}
|
}
|
||||||
@ -235,5 +284,8 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint)
|
|||||||
{
|
{
|
||||||
if (0 == IrpHint)
|
if (0 == IrpHint)
|
||||||
return 0;
|
return 0;
|
||||||
return IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, (PVOID)IrpHint);
|
FSP_IOQ_PEEK_CONTEXT PeekContext;
|
||||||
|
PeekContext.IrpHint = (PVOID)IrpHint;
|
||||||
|
PeekContext.ExpirationTime = 0;
|
||||||
|
return IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, &PeekContext);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user