sys: introduce private NTSTATUS codes FSP_STATUS_POST_IOQ* and ensure that Irp is not touched after STATUS_PENDING

This commit is contained in:
Bill Zissimopoulos 2016-01-17 14:12:05 -08:00
parent 9c7d9c5944
commit 0bedee7d5f
7 changed files with 63 additions and 41 deletions

View File

@ -73,17 +73,14 @@ static NTSTATUS FspFsvolCleanup(
Request->Req.Cleanup.UserContext2 = UserContext2; Request->Req.Cleanup.UserContext2 = UserContext2;
Request->Req.Cleanup.Delete = DeletePending; Request->Req.Cleanup.Delete = DeletePending;
return FSP_STATUS_IOQ_POST_BEST_EFFORT;
/* /*
* Note that it is still possible for this request to not be delivered, * Note that it is still possible for this request to not be delivered,
* if the volume device Ioq is stopped. But such failures are benign * if the volume device Ioq is stopped. But such failures are benign
* from our perspective, because they mean that the file system is going * from our perspective, because they mean that the file system is going
* away and should correctly tear things down. * away and should correctly tear things down.
*/ */
if (FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, 0))
return STATUS_PENDING;
else
return STATUS_SUCCESS;
} }
VOID FspFsvolCleanupComplete( VOID FspFsvolCleanupComplete(

View File

@ -312,7 +312,7 @@ static NTSTATUS FspFsvolCreate(
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
SecurityDescriptor, SecurityDescriptorSize); SecurityDescriptor, SecurityDescriptorSize);
return STATUS_PENDING; return FSP_STATUS_IOQ_POST;
} }
NTSTATUS FspFsvolCreatePrepare( NTSTATUS FspFsvolCreatePrepare(
@ -380,8 +380,7 @@ NTSTATUS FspFsvolCreatePrepare(
/* repost the IRP to retry later */ /* repost the IRP to retry later */
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(IrpSp->DeviceObject); FspFsvolDeviceExtension(IrpSp->DeviceObject);
if (FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result)) FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result);
Result = STATUS_PENDING;
return Result; return Result;
} }
@ -593,8 +592,7 @@ VOID FspFsvolCreateComplete(
* Note that it is still possible for this request to not be delivered, * Note that it is still possible for this request to not be delivered,
* if the volume device Ioq is stopped or if the IRP is canceled. * if the volume device Ioq is stopped or if the IRP is canceled.
*/ */
if (FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result)) FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result);
Result = STATUS_PENDING;
} }
else else
{ {

View File

@ -16,6 +16,10 @@ const char *NtStatusSym(NTSTATUS Status)
{ {
// cygwin: sed -n '/_WAIT_0/!s/^#define[ \t]*\(STATUS_[^ \t]*\).*NTSTATUS.*$/SYM(\1)/p' // cygwin: sed -n '/_WAIT_0/!s/^#define[ \t]*\(STATUS_[^ \t]*\).*NTSTATUS.*$/SYM(\1)/p'
#include "ntstatus.i" #include "ntstatus.i"
case FSP_STATUS_IOQ_POST:
return "FSP_STATUS_IOQ_POST";
case FSP_STATUS_IOQ_POST_BEST_EFFORT:
return "FSP_STATUS_IOQ_POST_BEST_EFFORT";
default: default:
return "NTSTATUS:Unknown"; return "NTSTATUS:Unknown";
} }

View File

@ -25,6 +25,11 @@
#define FSP_FSVRT_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)" #define FSP_FSVRT_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)"
/* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */ /* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */
/* private NTSTATUS codes */
#define FSP_STATUS_PRIVATE_BIT (0x20000000)
#define FSP_STATUS_IOQ_POST (FSP_STATUS_PRIVATE_BIT | 0x0000)
#define FSP_STATUS_IOQ_POST_BEST_EFFORT (FSP_STATUS_PRIVATE_BIT | 0x0001)
/* misc macros */ /* misc macros */
#define FSP_ALLOC_INTERNAL_TAG 'IpsF' #define FSP_ALLOC_INTERNAL_TAG 'IpsF'
#define FSP_ALLOC_EXTERNAL_TAG 'XpsF' #define FSP_ALLOC_EXTERNAL_TAG 'XpsF'
@ -111,6 +116,10 @@ extern __declspec(selectany) int fsp_bp = 1;
} while (0,0) } while (0,0)
#define FSP_LEAVE_MJ(fmt, ...) \ #define FSP_LEAVE_MJ(fmt, ...) \
FSP_LEAVE_( \ FSP_LEAVE_( \
if (STATUS_PENDING != Result) \
{ \
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\
FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\
FSP_DEBUGLOG_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ FSP_DEBUGLOG_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\
Irp, \ Irp, \
(const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\
@ -120,19 +129,20 @@ extern __declspec(selectany) int fsp_bp = 1;
__VA_ARGS__, \ __VA_ARGS__, \
NtStatusSym(Result), \ NtStatusSym(Result), \
(LONGLONG)Irp->IoStatus.Information);\ (LONGLONG)Irp->IoStatus.Information);\
if (STATUS_PENDING == Result) \ if (FSP_STATUS_PRIVATE_BIT & Result)\
{ \ { \
if (0 == (IrpSp->Control & SL_PENDING_RETURNED))\
{ \
/* if the IRP has not been marked pending already */\
FSP_FSVOL_DEVICE_EXTENSION *fsp_leave_FsvolDeviceExtension =\ FSP_FSVOL_DEVICE_EXTENSION *fsp_leave_FsvolDeviceExtension =\
FspFsvolDeviceExtension(DeviceObject);\ FspFsvolDeviceExtension(DeviceObject);\
if (!FspIoqPostIrp(fsp_leave_FsvolDeviceExtension->Ioq, Irp, &Result))\ if (!FspIoqPostIrpEx(fsp_leave_FsvolDeviceExtension->Ioq, Irp,\
FSP_STATUS_IOQ_POST_BEST_EFFORT == Result, &Result))\
{\
DEBUGLOG("FspIoqPostIrpEx = %s", NtStatusSym(Result));\
FspIopCompleteIrp(Irp, Result);\ FspIopCompleteIrp(Irp, Result);\
}\ }\
} \ } \
else \ else \
FspIopCompleteIrpEx(Irp, Result, fsp_device_release);\ FspIopCompleteIrpEx(Irp, Result, fsp_device_release);\
} \
); \ ); \
return Result return Result
#define FSP_ENTER_IOC(...) \ #define FSP_ENTER_IOC(...) \
@ -141,6 +151,9 @@ extern __declspec(selectany) int fsp_bp = 1;
FSP_ENTER_NOCRIT_(__VA_ARGS__) FSP_ENTER_NOCRIT_(__VA_ARGS__)
#define FSP_LEAVE_IOC(fmt, ...) \ #define FSP_LEAVE_IOC(fmt, ...) \
FSP_LEAVE_NOCRIT_( \ FSP_LEAVE_NOCRIT_( \
if (STATUS_PENDING != Result) \
{ \
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result));\
FSP_DEBUGLOG_NOCRIT_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ FSP_DEBUGLOG_NOCRIT_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\
Irp, \ Irp, \
(const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\
@ -150,8 +163,8 @@ extern __declspec(selectany) int fsp_bp = 1;
__VA_ARGS__, \ __VA_ARGS__, \
NtStatusSym(Result), \ NtStatusSym(Result), \
(LONGLONG)Irp->IoStatus.Information);\ (LONGLONG)Irp->IoStatus.Information);\
if (STATUS_PENDING != Result) \
FspIopCompleteIrp(Irp, Result);\ FspIopCompleteIrp(Irp, Result);\
} \
) )
#define FSP_ENTER_BOOL(...) \ #define FSP_ENTER_BOOL(...) \
BOOLEAN Result = TRUE; FSP_ENTER_(__VA_ARGS__) BOOLEAN Result = TRUE; FSP_ENTER_(__VA_ARGS__)

View File

@ -214,6 +214,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease)
PAGED_CODE(); PAGED_CODE();
ASSERT(STATUS_PENDING != Result); ASSERT(STATUS_PENDING != Result);
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result));
if (0 != FspIrpRequest(Irp)) if (0 != FspIrpRequest(Irp))
{ {

View File

@ -384,11 +384,18 @@ BOOLEAN FspIoqPostIrpEx(FSP_IOQ *Ioq, PIRP Irp, BOOLEAN BestEffort, NTSTATUS *PR
QueryInterruptTimeInSec() + Ioq->IrpTimeout; QueryInterruptTimeInSec() + Ioq->IrpTimeout;
Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, (PVOID)BestEffort); Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, (PVOID)BestEffort);
if (NT_SUCCESS(Result)) if (NT_SUCCESS(Result))
{
if (0 != PResult)
*PResult = STATUS_PENDING;
return TRUE; return TRUE;
}
else
{
if (0 != PResult) if (0 != PResult)
*PResult = Result; *PResult = Result;
return FALSE; return FALSE;
} }
}
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout) PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout)
{ {

View File

@ -644,8 +644,10 @@ NTSTATUS FspVolumeWork(
Request->Hint = 0; Request->Hint = 0;
FspIrpRequest(Irp) = 0; FspIrpRequest(Irp) = 0;
} }
else
Result = STATUS_PENDING; DEBUGLOG("%s = %s",
IoctlCodeSym(BestEffort ? FSP_FSCTL_WORK_BEST_EFFORT : FSP_FSCTL_WORK),
NtStatusSym(Result));
return Result; return Result;
} }