reactos/sdk/lib/drivers/rxce/rxce.c

9231 lines
264 KiB
C
Raw Normal View History

/*
* ReactOS kernel
* Copyright (C) 2017 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: sdk/lib/drivers/rxce/rxce.c
* PURPOSE: RXCE library
* PROGRAMMER: Pierre Schweitzer (pierre@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include <rx.h>
#include <pseh/pseh2.h>
#include <dfs.h>
#define NDEBUG
#include <debug.h>
VOID
RxAssert(
PVOID Assert,
PVOID File,
ULONG Line,
PVOID Message);
VOID
NTAPI
RxCreateSrvCallCallBack(
IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT Context);
NTSTATUS
RxFinishSrvCallConstruction(
PMRX_SRVCALLDOWN_STRUCTURE Calldown);
VOID
NTAPI
RxFinishSrvCallConstructionDispatcher(
IN PVOID Context);
NTSTATUS
RxInsertWorkQueueItem(
PRDBSS_DEVICE_OBJECT pMRxDeviceObject,
WORK_QUEUE_TYPE WorkQueueType,
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PRX_WORK_QUEUE_ITEM WorkQueueItem);
PVOID
RxNewMapUserBuffer(
PRX_CONTEXT RxContext);
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
VOID
NTAPI
RxpDestroySrvCall(
IN PVOID Context);
VOID
RxpDispatchChangeBufferingStateRequests(
PSRV_CALL SrvCall,
PSRV_OPEN SrvOpen,
PLIST_ENTRY DiscardedRequests);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
VOID
NTAPI
RxScavengerTimerRoutine(
PVOID Context);
VOID
NTAPI
RxTimerDispatch(
_In_ struct _KDPC *Dpc,
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2);
VOID
NTAPI
RxWorkItemDispatcher(
PVOID Context);
PVOID
NTAPI
_RxAllocatePoolWithTag(
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Tag);
VOID
NTAPI
_RxFreePool(
_In_ PVOID Buffer);
VOID
NTAPI
_RxFreePoolWithTag(
_In_ PVOID Buffer,
_In_ ULONG Tag);
extern ULONG ReadAheadGranularity;
volatile LONG RxNumberOfActiveFcbs = 0;
ULONG SerialNumber = 1;
PVOID RxNull = NULL;
volatile ULONG RxContextSerialNumberCounter;
BOOLEAN RxStopOnLoudCompletion = TRUE;
BOOLEAN RxSrvCallConstructionDispatcherActive = FALSE;
LIST_ENTRY RxSrvCalldownList;
RX_SPIN_LOCK RxStrucSupSpinLock;
#if 0
ULONG RdbssReferenceTracingValue = (RDBSS_REF_TRACK_SRVCALL | RDBSS_REF_TRACK_NETROOT |
RDBSS_REF_TRACK_VNETROOT | RDBSS_REF_TRACK_NETFOBX |
RDBSS_REF_TRACK_NETFCB | RDBSS_REF_TRACK_SRVOPEN |
RX_PRINT_REF_TRACKING);
#else
ULONG RdbssReferenceTracingValue = 0;
#endif
LARGE_INTEGER RxWorkQueueWaitInterval[RxMaximumWorkQueue];
LARGE_INTEGER RxSpinUpDispatcherWaitInterval;
RX_DISPATCHER RxDispatcher;
RX_WORK_QUEUE_DISPATCHER RxDispatcherWorkQueues;
FAST_MUTEX RxLowIoPagingIoSyncMutex;
BOOLEAN RxContinueFromAssert = TRUE;
ULONG RxExplodePoolTags = 1;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
LARGE_INTEGER RxTimerInterval;
RX_SPIN_LOCK RxTimerLock;
LIST_ENTRY RxTimerQueueHead;
LIST_ENTRY RxRecurrentWorkItemsList;
KDPC RxTimerDpc;
KTIMER RxTimer;
ULONG RxTimerTickCount;
FAST_MUTEX RxContextPerFileSerializationMutex;
#if DBG
BOOLEAN DumpDispatchRoutine = TRUE;
#else
BOOLEAN DumpDispatchRoutine = FALSE;
#endif
#if RDBSS_ASSERTS
#ifdef ASSERT
#undef ASSERT
#endif
#define ASSERT(exp) \
if (!(exp)) \
{ \
RxAssert(#exp, __FILE__, __LINE__, NULL); \
}
#endif
#if RX_POOL_WRAPPER
#undef RxAllocatePool
#undef RxAllocatePoolWithTag
#undef RxFreePool
#define RxAllocatePool(P, S) _RxAllocatePoolWithTag(P, S, 0)
#define RxAllocatePoolWithTag _RxAllocatePoolWithTag
#define RxFreePool _RxFreePool
#define RxFreePoolWithTag _RxFreePoolWithTag
#endif
/* FUNCTIONS ****************************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
RxAcquireExclusiveFcbResourceInMRx(
_Inout_ PMRX_FCB Fcb)
{
return RxAcquireExclusiveFcb(NULL, (PFCB)Fcb);
}
/*
* @implemented
*/
BOOLEAN
NTAPI
RxAcquireFcbForLazyWrite(
PVOID Context,
BOOLEAN Wait)
{
PFCB Fcb;
BOOLEAN Ret;
PAGED_CODE();
Fcb = Context;
/* The received context is a FCB */
ASSERT(NodeType(Fcb) == RDBSS_NTC_FCB);
ASSERT_CORRECT_FCB_STRUCTURE(Fcb);
ASSERT(Fcb->Specific.Fcb.LazyWriteThread == NULL);
/* Acquire the paging resource (shared) */
Ret = ExAcquireResourceSharedLite(Fcb->Header.PagingIoResource, Wait);
if (Ret)
{
/* Update tracker information */
Fcb->PagingIoResourceFile = __FILE__;
Fcb->PagingIoResourceLine = __LINE__;
/* Lazy writer thread is the current one */
Fcb->Specific.Fcb.LazyWriteThread = PsGetCurrentThread();
/* There is no top level IRP */
ASSERT(RxIsThisTheTopLevelIrp(NULL));
/* Now, there will be! */
Ret = RxTryToBecomeTheTopLevelIrp(NULL, (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP,
Fcb->RxDeviceObject, TRUE);
/* In case of failure, release the lock and reset everything */
if (!Ret)
{
Fcb->PagingIoResourceFile = NULL;
Fcb->PagingIoResourceLine = 0;
ExReleaseResourceLite(Fcb->Header.PagingIoResource);
Fcb->Specific.Fcb.LazyWriteThread = NULL;
}
}
return Ret;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
RxAcquireFcbForReadAhead(
PVOID Context,
BOOLEAN Wait)
{
PFCB Fcb;
BOOLEAN Ret;
PAGED_CODE();
Fcb = Context;
/* The received context is a FCB */
ASSERT(NodeType(Fcb) == RDBSS_NTC_FCB);
ASSERT_CORRECT_FCB_STRUCTURE(Fcb);
Ret = ExAcquireResourceSharedLite(Fcb->Header.Resource, Wait);
if (Ret)
{
/* There is no top level IRP */
ASSERT(RxIsThisTheTopLevelIrp(NULL));
/* Now, there will be! */
Ret = RxTryToBecomeTheTopLevelIrp(NULL, (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP,
Fcb->RxDeviceObject, TRUE);
/* In case of failure, release the lock and reset everything */
if (!Ret)
{
ExReleaseResourceLite(Fcb->Header.Resource);
}
}
return Ret;
}
VOID
NTAPI
RxAcquireFileForNtCreateSection(
PFILE_OBJECT FileObject)
{
UNIMPLEMENTED;
}
NTSTATUS
NTAPI
RxAcquireForCcFlush(
PFILE_OBJECT FileObject,
PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
VOID
RxAddVirtualNetRootToNetRoot(
PNET_ROOT NetRoot,
PV_NET_ROOT VNetRoot)
{
PAGED_CODE();
DPRINT("RxAddVirtualNetRootToNetRoot(%p, %p)\n", NetRoot, VNetRoot);
/* Insert in the VNetRoot list - make sure lock is held */
ASSERT(RxIsPrefixTableLockExclusive(NetRoot->SrvCall->RxDeviceObject->pRxNetNameTable));
VNetRoot->pNetRoot = (PMRX_NET_ROOT)NetRoot;
++NetRoot->NumberOfVirtualNetRoots;
InsertTailList(&NetRoot->VirtualNetRoots, &VNetRoot->NetRootListEntry);
}
/*
* @implemented
*/
PVOID
RxAllocateFcbObject(
PRDBSS_DEVICE_OBJECT RxDeviceObject,
NODE_TYPE_CODE NodeType,
POOL_TYPE PoolType,
ULONG NameSize,
PVOID AlreadyAllocatedObject)
{
PFCB Fcb;
PFOBX Fobx;
PSRV_OPEN SrvOpen;
PVOID Buffer, PAPNBuffer;
PNON_PAGED_FCB NonPagedFcb;
PMINIRDR_DISPATCH Dispatch;
ULONG NonPagedSize, FobxSize, SrvOpenSize, FcbSize;
PAGED_CODE();
Dispatch = RxDeviceObject->Dispatch;
NonPagedSize = 0;
FobxSize = 0;
SrvOpenSize = 0;
FcbSize = 0;
Fcb = NULL;
Fobx = NULL;
SrvOpen = NULL;
NonPagedFcb = NULL;
PAPNBuffer = NULL;
/* If we ask for FOBX, just allocate FOBX and its extension if asked */
if (NodeType == RDBSS_NTC_FOBX)
{
FobxSize = sizeof(FOBX);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_FOBX_EXTENSION))
{
FobxSize += QuadAlign(Dispatch->MRxFobxSize);
}
}
/* If we ask for SRV_OPEN, also allocate the "internal" FOBX and the extensions if asked */
else if (NodeType == RDBSS_NTC_SRVOPEN || NodeType == RDBSS_NTC_INTERNAL_SRVOPEN)
{
SrvOpenSize = sizeof(SRV_OPEN);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_SRV_OPEN_EXTENSION))
{
SrvOpenSize += QuadAlign(Dispatch->MRxSrvOpenSize);
}
FobxSize = sizeof(FOBX);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_FOBX_EXTENSION))
{
FobxSize += QuadAlign(Dispatch->MRxFobxSize);
}
}
/* Otherwise, we're asked to allocate a FCB */
else
{
/* So, allocate the FCB and its extension if asked */
FcbSize = sizeof(FCB);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_FCB_EXTENSION))
{
FcbSize += QuadAlign(Dispatch->MRxFcbSize);
}
/* If we're asked to allocate from nonpaged, also allocate the NON_PAGED_FCB
* Otherwise, it will be allocated later on, specifically
*/
if (PoolType == NonPagedPool)
{
NonPagedSize = sizeof(NON_PAGED_FCB);
}
/* And if it's not for a rename operation also allcoate the internal SRV_OPEN and FOBX and their extensions */
if (NodeType != RDBSS_NTC_OPENTARGETDIR_FCB)
{
SrvOpenSize = sizeof(SRV_OPEN);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_SRV_OPEN_EXTENSION))
{
SrvOpenSize += QuadAlign(Dispatch->MRxSrvOpenSize);
}
FobxSize = sizeof(FOBX);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_FOBX_EXTENSION))
{
FobxSize += QuadAlign(Dispatch->MRxFobxSize);
}
}
}
/* If we already have a buffer, go ahead */
if (AlreadyAllocatedObject != NULL)
{
Buffer = AlreadyAllocatedObject;
}
/* Otherwise, allocate it */
else
{
Buffer = RxAllocatePoolWithTag(PoolType, NameSize + FcbSize + SrvOpenSize + FobxSize + NonPagedSize, RX_FCB_POOLTAG);
if (Buffer == NULL)
{
return NULL;
}
}
/* Now, get the pointers - FOBX is easy */
if (NodeType == RDBSS_NTC_FOBX)
{
Fobx = Buffer;
}
/* SRV_OPEN first, FOBX next */
else if (NodeType == RDBSS_NTC_SRVOPEN)
{
SrvOpen = Buffer;
Fobx = Add2Ptr(Buffer, SrvOpenSize);
}
else if (NodeType == RDBSS_NTC_INTERNAL_SRVOPEN)
{
SrvOpen = Buffer;
}
else
{
/* FCB first, and if needed, SRV_OPEN next, FOBX last */
Fcb = Buffer;
if (NodeType != RDBSS_NTC_OPENTARGETDIR_FCB)
{
SrvOpen = Add2Ptr(Buffer, FcbSize);
Fobx = Add2Ptr(Buffer, FcbSize + SrvOpenSize);
}
/* If we were not allocated from non paged, allocate the NON_PAGED_FCB now */
if (PoolType != NonPagedPool)
{
NonPagedFcb = RxAllocatePoolWithTag(NonPagedPool, sizeof(NON_PAGED_FCB), RX_NONPAGEDFCB_POOLTAG);
if (NonPagedFcb == NULL)
{
RxFreePoolWithTag(Buffer, RX_FCB_POOLTAG);
return NULL;
}
PAPNBuffer = Add2Ptr(Buffer, FcbSize + SrvOpenSize + FobxSize);
}
/* Otherwise, just point at the right place in what has been allocated previously */
else
{
NonPagedFcb = Add2Ptr(Fobx, FobxSize);
PAPNBuffer = Add2Ptr(Fobx, FobxSize + NonPagedSize);
}
}
/* If we have allocated a SRV_OPEN, initialize it */
if (SrvOpen != NULL)
{
ZeroAndInitializeNodeType(SrvOpen, RDBSS_NTC_SRVOPEN, SrvOpenSize);
if (NodeType == RDBSS_NTC_SRVOPEN)
{
SrvOpen->InternalFobx = Fobx;
}
else
{
SrvOpen->InternalFobx = NULL;
SrvOpen->Flags |= SRVOPEN_FLAG_FOBX_USED;
}
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_SRV_OPEN_EXTENSION))
{
SrvOpen->Context = Add2Ptr(SrvOpen, sizeof(SRV_OPEN));
}
InitializeListHead(&SrvOpen->SrvOpenQLinks);
}
/* If we have allocated a FOBX, initialize it */
if (Fobx != NULL)
{
ZeroAndInitializeNodeType(Fobx, RDBSS_NTC_FOBX, FobxSize);
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_FOBX_EXTENSION))
{
Fobx->Context = Add2Ptr(Fobx, sizeof(FOBX));
}
}
/* If we have allocated a FCB, initialize it */
if (Fcb != NULL)
{
ZeroAndInitializeNodeType(Fcb, RDBSS_STORAGE_NTC(FileTypeNotYetKnown), FcbSize);
Fcb->NonPaged = NonPagedFcb;
ZeroAndInitializeNodeType(Fcb->NonPaged, RDBSS_NTC_NONPAGED_FCB, sizeof(NON_PAGED_FCB));
#if DBG
Fcb->CopyOfNonPaged = NonPagedFcb;
NonPagedFcb->FcbBackPointer = Fcb;
#endif
Fcb->InternalSrvOpen = SrvOpen;
Fcb->InternalFobx = Fobx;
Fcb->PrivateAlreadyPrefixedName.Length = NameSize;
Fcb->PrivateAlreadyPrefixedName.MaximumLength = NameSize;
Fcb->PrivateAlreadyPrefixedName.Buffer = PAPNBuffer;
if (BooleanFlagOn(Dispatch->MRxFlags, RDBSS_MANAGE_FCB_EXTENSION))
{
Fcb->Context = Add2Ptr(Fcb, sizeof(FCB));
}
ZeroAndInitializeNodeType(&Fcb->FcbTableEntry, RDBSS_NTC_FCB_TABLE_ENTRY, sizeof(RX_FCB_TABLE_ENTRY));
InterlockedIncrement(&RxNumberOfActiveFcbs);
InterlockedIncrement((volatile long *)&RxDeviceObject->NumberOfActiveFcbs);
ExInitializeFastMutex(&NonPagedFcb->AdvancedFcbHeaderMutex);
FsRtlSetupAdvancedHeader(Fcb, &NonPagedFcb->AdvancedFcbHeaderMutex);
}
DPRINT("Allocated %p\n", Buffer);
return Buffer;
}
/*
* @implemented
*/
PVOID
RxAllocateObject(
NODE_TYPE_CODE NodeType,
PMINIRDR_DISPATCH MRxDispatch,
ULONG NameLength)
{
ULONG Tag, ObjectSize;
PVOID Object, *Extension;
PRX_PREFIX_ENTRY PrefixEntry;
USHORT StructSize, ExtensionSize;
PAGED_CODE();
/* Select the node to allocate and always deal with the fact we may have to manage its extension */
ExtensionSize = 0;
switch (NodeType)
{
case RDBSS_NTC_SRVCALL:
Tag = RX_SRVCALL_POOLTAG;
StructSize = sizeof(SRV_CALL);
if (MRxDispatch != NULL && BooleanFlagOn(MRxDispatch->MRxFlags, RDBSS_MANAGE_SRV_CALL_EXTENSION))
{
ExtensionSize = QuadAlign(MRxDispatch->MRxSrvCallSize);
}
break;
case RDBSS_NTC_NETROOT:
Tag = RX_NETROOT_POOLTAG;
StructSize = sizeof(NET_ROOT);
if (BooleanFlagOn(MRxDispatch->MRxFlags, RDBSS_MANAGE_NET_ROOT_EXTENSION))
{
ExtensionSize = QuadAlign(MRxDispatch->MRxNetRootSize);
}
break;
case RDBSS_NTC_V_NETROOT:
Tag = RX_V_NETROOT_POOLTAG;
StructSize = sizeof(V_NET_ROOT);
if (BooleanFlagOn(MRxDispatch->MRxFlags, RDBSS_MANAGE_V_NET_ROOT_EXTENSION))
{
ExtensionSize = QuadAlign(MRxDispatch->MRxVNetRootSize);
}
break;
default:
ASSERT(FALSE);
break;
}
/* Now, allocate the object */
ObjectSize = ExtensionSize + StructSize + NameLength;
Object = RxAllocatePoolWithTag(NonPagedPool, ObjectSize, Tag);
if (Object == NULL)
{
return NULL;
}
/* Initialize it */
ZeroAndInitializeNodeType(Object, NodeType, ObjectSize);
/* For SRV_CALL and NETROOT, the name points to the prefix table name */
switch (NodeType)
{
case RDBSS_NTC_SRVCALL:
PrefixEntry = &((PSRV_CALL)Object)->PrefixEntry;
Extension = &((PSRV_CALL)Object)->Context;
((PSRV_CALL)Object)->pSrvCallName = &PrefixEntry->Prefix;
break;
case RDBSS_NTC_NETROOT:
PrefixEntry = &((PNET_ROOT)Object)->PrefixEntry;
Extension = &((PNET_ROOT)Object)->Context;
((PNET_ROOT)Object)->pNetRootName = &PrefixEntry->Prefix;
break;
case RDBSS_NTC_V_NETROOT:
PrefixEntry = &((PV_NET_ROOT)Object)->PrefixEntry;
Extension = &((PV_NET_ROOT)Object)->Context;
break;
default:
ASSERT(FALSE);
break;
}
/* Set the prefix table unicode string */
RtlZeroMemory(PrefixEntry, sizeof(RX_PREFIX_ENTRY));
PrefixEntry->NodeTypeCode = RDBSS_NTC_PREFIX_ENTRY;
PrefixEntry->NodeByteSize = sizeof(RX_PREFIX_ENTRY);
PrefixEntry->Prefix.Length = NameLength;
PrefixEntry->Prefix.MaximumLength = NameLength;
PrefixEntry->Prefix.Buffer = Add2Ptr(Object, ExtensionSize + StructSize);
/* Return the extension if we are asked to manage it */
if (ExtensionSize != 0)
{
*Extension = Add2Ptr(Object, StructSize);
}
return Object;
}
/*
* @implemented
*/
VOID
RxAssert(
PVOID Assert,
PVOID File,
ULONG Line,
PVOID Message)
{
CHAR Response[2];
CONTEXT Context;
/* If we're not asked to continue, just stop the system */
if (!RxContinueFromAssert)
{
KeBugCheckEx(RDBSS_FILE_SYSTEM, RDBSS_BUG_CHECK_ASSERT | Line, 0, 0, 0);
}
/* Otherwise, capture context to offer the user to dump it */
RtlCaptureContext(&Context);
/* Loop until the user hits 'i' */
while (TRUE)
{
/* If no file provided, use empty name */
if (File == NULL)
{
File = "";
}
/* If no message provided, use empty one */
if (Message == NULL)
{
Message = "";
}
/* Display the message */
DbgPrint("\n*** Assertion failed: %s%s\n*** Source File: %s, line %ld\n\n", Message, Assert, File, Line);
/* And ask the user */
DbgPrompt("Break, Ignore (bi)? ", Response, sizeof(Response));
/* If he asks for ignore, quit
* In case of invalid input, ask again
*/
if (Response[0] != 'B' && Response[0] != 'b')
{
if (Response[0] == 'I' || Response[0] == 'i')
{
return;
}
continue;
}
/* Break: offer the user to dump the context and break */
DbgPrint("Execute '!cxr %lx' to dump context\n", &Context);
DbgBreakPoint();
/* Continue looping, so that after dump, execution can continue (with ignore) */
}
}
/*
* @implemented
*/
VOID
NTAPI
RxBootstrapWorkerThreadDispatcher(
IN PVOID WorkQueue)
{
PRX_WORK_QUEUE RxWorkQueue;
PAGED_CODE();
RxWorkQueue = WorkQueue;
RxpWorkerThreadDispatcher(RxWorkQueue, NULL);
}
/*
* @implemented
*/
VOID
RxCancelBlockingOperation(
IN OUT PRX_CONTEXT RxContext)
{
PFOBX Fobx;
BOOLEAN PostRequest;
2019-01-03 13:27:15 +00:00
PAGED_CODE();
Fobx = (PFOBX)RxContext->pFobx;
PostRequest = FALSE;
/* Acquire the pipe mutex */
ExAcquireFastMutex(&RxContextPerFileSerializationMutex);
/* If that's a blocking pipe operation which is not the CCB one, then handle it */
if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION) &&
RxContext->RxContextSerializationQLinks.Flink != NULL &&
RxContext != CONTAINING_RECORD(&Fobx->Specific.NamedPipe.ReadSerializationQueue, RX_CONTEXT, RxContextSerializationQLinks) &&
RxContext != CONTAINING_RECORD(&Fobx->Specific.NamedPipe.WriteSerializationQueue, RX_CONTEXT, RxContextSerializationQLinks))
{
/* Clear it! */
ClearFlag(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION);
/* Drop it off the list */
RemoveEntryList(&RxContext->RxContextSerializationQLinks);
RxContext->RxContextSerializationQLinks.Flink = NULL;
RxContext->RxContextSerializationQLinks.Blink = NULL;
/* Set we've been cancelled */
RxContext->IoStatusBlock.Status = STATUS_CANCELLED;
/*
* If it's async, we'll post completion, otherwise, we signal to waiters
* it's being cancelled
*/
if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
{
PostRequest = TRUE;
}
else
{
RxSignalSynchronousWaiter(RxContext);
}
}
/* Done */
ExReleaseFastMutex(&RxContextPerFileSerializationMutex);
/* Post if async */
if (PostRequest)
{
RxFsdPostRequest(RxContext);
}
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
NTSTATUS
NTAPI
RxChangeBufferingState(
PSRV_OPEN SrvOpen,
PVOID Context,
BOOLEAN ComputeNewState)
{
PFCB Fcb;
NTSTATUS Status, MiniStatus;
ULONG NewBufferingState, OldBufferingState;
PAGED_CODE();
DPRINT("RxChangeBufferingState(%p, %p, %d)\n", SrvOpen, Context, ComputeNewState);
Fcb = (PFCB)SrvOpen->pFcb;
ASSERT(NodeTypeIsFcb(Fcb));
/* First of all, mark that buffering state is changing */
SetFlag(Fcb->FcbState, FCB_STATE_BUFFERSTATE_CHANGING);
/* Assume success */
Status = STATUS_SUCCESS;
_SEH2_TRY
{
/* If we're asked to compute a new state, ask the mini-rdr for it */
if (ComputeNewState)
{
MINIRDR_CALL_THROUGH(MiniStatus, Fcb->MRxDispatch, MRxComputeNewBufferingState,
((PMRX_SRV_OPEN)SrvOpen, Context, &NewBufferingState));
if (MiniStatus != STATUS_SUCCESS)
{
NewBufferingState = 0;
}
}
else
{
/* If not, use SRV_OPEN state */
NewBufferingState = SrvOpen->BufferingFlags;
}
/* If no shared access, and if we're not asked to compute a new state, use maximum flags set */
if ((Fcb->ShareAccess.SharedRead + Fcb->ShareAccess.SharedWrite + Fcb->ShareAccess.SharedDelete) == 0 && !ComputeNewState)
{
SetFlag(NewBufferingState, FCB_STATE_BUFFERING_STATE_WITH_NO_SHARES);
}
/* If there's a lock operation to complete, clear that flag */
if (Fcb->OutstandingLockOperationsCount != 0)
{
ClearFlag(NewBufferingState, FCB_STATE_LOCK_BUFFERING_ENABLED);
}
/* Get the old state */
OldBufferingState = Fcb->FcbState & FCB_STATE_BUFFERING_STATE_MASK;
DPRINT("ChangeBufferingState %x -> %x (%x)\n", OldBufferingState, NewBufferingState, SrvOpen->BufferingFlags);
/* If we're dropping write cache, then flush the FCB */
if (BooleanFlagOn(OldBufferingState, FCB_STATE_WRITECACHING_ENABLED) &&
!BooleanFlagOn(NewBufferingState, FCB_STATE_WRITECACHING_ENABLED))
{
DPRINT("Flushing\n");
Status = RxFlushFcbInSystemCache(Fcb, TRUE);
}
/* If we're dropping read cache, then purge */
if (Fcb->UncleanCount == 0 ||
(BooleanFlagOn(OldBufferingState, FCB_STATE_READCACHING_ENABLED) &&
!BooleanFlagOn(NewBufferingState, FCB_STATE_READCACHING_ENABLED)) ||
BooleanFlagOn(NewBufferingState, FCB_STATE_DELETE_ON_CLOSE))
{
DPRINT("Purging\n");
if (!NT_SUCCESS(Status))
{
DPRINT("Previous flush failed with status: %lx\n", Status);
}
CcPurgeCacheSection(&Fcb->NonPaged->SectionObjectPointers, NULL, 0, TRUE);
}
/* If there's already a change pending in SRV_OPEN */
if (ComputeNewState && BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING))
{
/* If there's a FOBX at least */
if (!IsListEmpty(&SrvOpen->FobxList))
{
PRX_CONTEXT RxContext;
/* Create a fake context to pass to the mini-rdr */
RxContext = RxCreateRxContext(NULL, Fcb->RxDeviceObject, RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING | RX_CONTEXT_FLAG_WAIT);
if (RxContext != NULL)
{
PFOBX Fobx;
RxContext->pFcb = RX_GET_MRX_FCB(Fcb);
/* Give the first FOBX */
Fobx = CONTAINING_RECORD(SrvOpen->FobxList.Flink, FOBX, FobxQLinks);
RxContext->pFobx = (PMRX_FOBX)Fobx;
RxContext->pRelevantSrvOpen = Fobx->pSrvOpen;
/* If there was a delayed close, perform it */
if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
{
DPRINT("Oplock break close for %p\n", SrvOpen);
RxCloseAssociatedSrvOpen(Fobx, RxContext);
}
/* Otherwise, inform the mini-rdr about completion */
else
{
MINIRDR_CALL_THROUGH(MiniStatus, Fcb->MRxDispatch, MRxCompleteBufferingStateChangeRequest,
(RxContext, (PMRX_SRV_OPEN)SrvOpen, Context));
(void)MiniStatus;
}
RxDereferenceAndDeleteRxContext(RxContext);
}
}
}
/* Set the new state */
Fcb->FcbState ^= (NewBufferingState ^ Fcb->FcbState) & FCB_STATE_BUFFERING_STATE_MASK;
}
_SEH2_FINALLY
{
/* Job done, clear the flag */
ClearFlag(Fcb->FcbState, FCB_STATE_BUFFERSTATE_CHANGING);
if (!BooleanFlagOn(NewBufferingState, FCB_STATE_FILETIMECACHEING_ENABLED))
{
ClearFlag(Fcb->FcbState, FCB_STATE_TIME_AND_SIZE_ALREADY_SET);
}
}
_SEH2_END;
return Status;
}
NTSTATUS
RxCheckVNetRootCredentials(
PRX_CONTEXT RxContext,
PV_NET_ROOT VNetRoot,
PLUID LogonId,
PUNICODE_STRING UserName,
PUNICODE_STRING UserDomain,
PUNICODE_STRING Password,
ULONG Flags)
{
PAGED_CODE();
/* If that's a UNC name, there's nothing to process */
if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_CREATE_FLAG_UNC_NAME) &&
(BooleanFlagOn(VNetRoot->Flags, VNETROOT_FLAG_CSCAGENT_INSTANCE) ||
Flags != 0))
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
/* Compare the logon ID in the VNetRoot with the one provided */
if (RtlCompareMemory(&VNetRoot->LogonId, LogonId, sizeof(LUID)) != sizeof(LUID))
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
/* No credential provided? That's OK */
if (UserName == NULL && UserDomain == NULL && Password == NULL)
{
return STATUS_SUCCESS;
}
/* Left to do! */
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
RxCompleteRequest(
PRX_CONTEXT Context,
NTSTATUS Status)
{
PIRP Irp;
PAGED_CODE();
DPRINT("RxCompleteRequest(%p, %lx)\n", Context, Status);
ASSERT(Context != NULL);
ASSERT(Context->CurrentIrp != NULL);
Irp = Context->CurrentIrp;
/* Debug what the caller asks for */
if (Context->LoudCompletionString != NULL)
{
DPRINT("LoudCompletion: %lx/%lx with %wZ\n", Status, Irp->IoStatus.Information, Context->LoudCompletionString);
/* Does the user asks to stop on failed completion */
if (!NT_SUCCESS(Status) && RxStopOnLoudCompletion)
{
DPRINT1("LoudFailure: %lx/%lx with %wZ\n", Status, Irp->IoStatus.Information, Context->LoudCompletionString);
}
}
/* Complete for real */
Context->CurrentIrp = NULL;
RxCompleteRequest_Real(Context, Irp, Status);
DPRINT("Status: %lx\n", Status);
return Status;
}
/*
* @implemented
*/
VOID
RxCompleteRequest_Real(
IN PRX_CONTEXT RxContext,
IN PIRP Irp,
IN NTSTATUS Status)
{
CCHAR Boost;
KIRQL OldIrql;
PIO_STACK_LOCATION Stack;
DPRINT("RxCompleteRequest_Real(%p, %p, %lx)\n", RxContext, Irp, Status);
/* Nothing to complete, just free context */
if (Irp == NULL)
{
DPRINT("NULL IRP for %p\n", RxContext);
if (RxContext != NULL)
{
RxDereferenceAndDeleteRxContext_Real(RxContext);
}
return;
}
/* Remove cancel routine */
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(OldIrql);
/* Select the boost, given the success/paging operation */
if (NT_SUCCESS(Status) || !BooleanFlagOn(Irp->Flags, IRP_SYNCHRONOUS_PAGING_IO))
{
Boost = IO_DISK_INCREMENT;
}
else
{
Irp->IoStatus.Information = 0;
Boost = IO_NO_INCREMENT;
}
Irp->IoStatus.Status = Status;
if (RxContext != NULL)
{
ASSERT(RxContext->MajorFunction <= IRP_MJ_MAXIMUM_FUNCTION);
if (RxContext->MajorFunction != IRP_MJ_DEVICE_CONTROL)
{
DPRINT("Completing: MN: %d, Context: %p, IRP: %p, Status: %lx, Info: %lx, #%lx\n",
RxContext->MinorFunction, RxContext, Irp,
Status, Irp->IoStatus.Information, RxContext->SerialNumber);
}
}
/* If that's an opening, there might be a canonical name allocated,
* if completion isn't pending, release it
*/
Stack = IoGetCurrentIrpStackLocation(Irp);
if (Stack->MajorFunction == IRP_MJ_CREATE && Status != STATUS_PENDING &&
RxContext != NULL)
{
if (BooleanFlagOn(RxContext->Create.Flags, 2))
{
Stack->FileObject->FileName.Length += sizeof(WCHAR);
}
RxpPrepareCreateContextForReuse(RxContext);
ASSERT(RxContext->Create.CanonicalNameBuffer == NULL);
}
/* If it's a write, validate the correct behavior of the operation */
if (Stack->MajorFunction == IRP_MJ_WRITE)
{
if (NT_SUCCESS(Irp->IoStatus.Status))
{
ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Write.Length);
}
}
/* If it's pending, make sure IRP is marked as such */
if (RxContext != NULL)
{
if (RxContext->PendingReturned)
{
ASSERT(BooleanFlagOn(Stack->Control, SL_PENDING_RETURNED));
}
}
/* Complete now */
DPRINT("Completing IRP with %x/%x\n", Irp->IoStatus.Status, Irp->IoStatus.Information);
IoCompleteRequest(Irp, Boost);
/* If there's a context, dereference it */
if (RxContext != NULL)
{
RxDereferenceAndDeleteRxContext_Real(RxContext);
}
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
RxCompleteSrvOpenKeyAssociation(
IN OUT PSRV_OPEN SrvOpen)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PSRV_CALL SrvCall;
SrvCall = (PSRV_CALL)((PFCB)SrvOpen->pFcb)->VNetRoot->pNetRoot->pSrvCall;
/* Only handle requests if opening was a success */
if (SrvOpen->Condition == Condition_Good)
{
KIRQL OldIrql;
BOOLEAN ProcessChange;
LIST_ENTRY DiscardedRequests;
/* Initialize our discarded requests list */
InitializeListHead(&DiscardedRequests);
RxAcquireBufferingManagerMutex(&SrvCall->BufferingManager);
/* Transfer our requests in the SRV_CALL */
RxTransferList(&SrvCall->BufferingManager.SrvOpenLists[0], &SrvOpen->SrvOpenKeyList);
/* Was increased in RxInitiateSrvOpenKeyAssociation(), opening is done */
InterlockedDecrement(&SrvCall->BufferingManager.NumberOfOutstandingOpens);
/* Dispatch requests and get the discarded ones */
RxpDispatchChangeBufferingStateRequests(SrvCall, SrvOpen, &DiscardedRequests);
RxReleaseBufferingManagerMutex(&SrvCall->BufferingManager);
/* Is there still anything to process? */
KeAcquireSpinLock(&SrvCall->BufferingManager.SpinLock, &OldIrql);
if (IsListEmpty(&SrvCall->BufferingManager.HandlerList))
{
ProcessChange = FALSE;
}
else
{
ProcessChange = (SrvCall->BufferingManager.HandlerInactive == FALSE);
if (ProcessChange)
{
SrvCall->BufferingManager.HandlerInactive = TRUE;
}
}
KeReleaseSpinLock(&SrvCall->BufferingManager.SpinLock, OldIrql);
/* Yes? Go ahead! */
if (ProcessChange)
{
RxReferenceSrvCall(SrvCall);
RxPostToWorkerThread(RxFileSystemDeviceObject, HyperCriticalWorkQueue,
&SrvCall->BufferingManager.HandlerWorkItem,
RxProcessChangeBufferingStateRequests, SrvCall);
}
/* And discard left requests */
RxpDiscardChangeBufferingStateRequests(&DiscardedRequests);
}
else
{
InterlockedDecrement(&SrvCall->BufferingManager.NumberOfOutstandingOpens);
}
}
/*
* @implemented
*/
NTSTATUS
RxConstructNetRoot(
IN PRX_CONTEXT RxContext,
IN PSRV_CALL SrvCall,
IN PNET_ROOT NetRoot,
IN PV_NET_ROOT VirtualNetRoot,
OUT PLOCK_HOLDING_STATE LockHoldingState)
{
NTSTATUS Status;
PRX_PREFIX_TABLE PrefixTable;
PMRX_CREATENETROOT_CONTEXT Context;
RX_BLOCK_CONDITION RootCondition, VRootCondition;
PAGED_CODE();
DPRINT("RxConstructNetRoot(%p, %p, %p, %p, %p)\n", RxContext, SrvCall, NetRoot,
VirtualNetRoot, LockHoldingState);
/* Validate the lock is exclusively held */
PrefixTable = RxContext->RxDeviceObject->pRxNetNameTable;
ASSERT(*LockHoldingState == LHS_ExclusiveLockHeld);
/* Allocate the context */
Context = RxAllocatePoolWithTag(PagedPool, sizeof(MRX_CREATENETROOT_CONTEXT), RX_SRVCALL_POOLTAG);
if (Context == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* We can release lock now */
RxReleasePrefixTableLock(PrefixTable);
*LockHoldingState = LHS_LockNotHeld;
RootCondition = Condition_Bad;
VRootCondition = Condition_Bad;
/* Initialize the context */
RtlZeroMemory(Context, sizeof(MRX_CREATENETROOT_CONTEXT));
KeInitializeEvent(&Context->FinishEvent, SynchronizationEvent, FALSE);
Context->RxContext = RxContext;
Context->pVNetRoot = VirtualNetRoot;
Context->Callback = RxCreateNetRootCallBack;
/* And call the mini-rdr */
MINIRDR_CALL_THROUGH(Status, SrvCall->RxDeviceObject->Dispatch, MRxCreateVNetRoot, (Context));
if (Status == STATUS_PENDING)
{
/* Wait for the mini-rdr to be done */
KeWaitForSingleObject(&Context->FinishEvent, Executive, KernelMode, FALSE, NULL);
/* Update the structures condition according to mini-rdr return */
if (NT_SUCCESS(Context->NetRootStatus))
{
if (NT_SUCCESS(Context->VirtualNetRootStatus))
{
RootCondition = Condition_Good;
VRootCondition = Condition_Good;
Status = STATUS_SUCCESS;
}
else
{
RootCondition = Condition_Good;
Status = Context->VirtualNetRootStatus;
}
}
else
{
Status = Context->VirtualNetRootStatus;
if (NT_SUCCESS(Status))
{
Status = Context->NetRootStatus;
}
}
}
else
{
/* It has to return STATUS_PENDING! */
ASSERT(FALSE);
}
/* Acquire lock again - for caller lock status will remain unchanged */
ASSERT(*LockHoldingState == LHS_LockNotHeld);
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
*LockHoldingState = LHS_ExclusiveLockHeld;
/* Do the transition to the condition got from mini-rdr */
RxTransitionNetRoot(NetRoot, RootCondition);
RxTransitionVNetRoot(VirtualNetRoot, VRootCondition);
/* Context is not longer needed */
RxFreePoolWithTag(Context, RX_SRVCALL_POOLTAG);
DPRINT("Status: %x\n", Status);
return Status;
}
/*
* @implemented
*/
NTSTATUS
RxConstructSrvCall(
IN PRX_CONTEXT RxContext,
IN PSRV_CALL SrvCall,
OUT PLOCK_HOLDING_STATE LockHoldingState)
{
NTSTATUS Status;
PRX_PREFIX_TABLE PrefixTable;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
PMRX_SRVCALLDOWN_STRUCTURE Calldown;
PMRX_SRVCALL_CALLBACK_CONTEXT CallbackContext;
PAGED_CODE();
DPRINT("RxConstructSrvCall(%p, %p, %p)\n", RxContext, SrvCall, LockHoldingState);
/* Validate the lock is exclusively held */
RxDeviceObject = RxContext->RxDeviceObject;
PrefixTable = RxDeviceObject->pRxNetNameTable;
ASSERT(*LockHoldingState == LHS_ExclusiveLockHeld);
/* Allocate the context for mini-rdr */
Calldown = RxAllocatePoolWithTag(NonPagedPool, sizeof(MRX_SRVCALLDOWN_STRUCTURE), RX_SRVCALL_POOLTAG);
if (Calldown == NULL)
{
SrvCall->Context = NULL;
SrvCall->Condition = Condition_Bad;
RxReleasePrefixTableLock(PrefixTable);
*LockHoldingState = LHS_LockNotHeld;
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Initialize it */
RtlZeroMemory(Calldown, sizeof(MRX_SRVCALLDOWN_STRUCTURE));
SrvCall->Context = NULL;
SrvCall->Condition = Condition_InTransition;
RxReleasePrefixTableLock(PrefixTable);
*LockHoldingState = LHS_LockNotHeld;
CallbackContext = &Calldown->CallbackContexts[0];
DPRINT("CalldownContext %p for %wZ\n", CallbackContext, &RxDeviceObject->DeviceName);
DPRINT("With calldown %p and SrvCall %p\n", Calldown, SrvCall);
CallbackContext->SrvCalldownStructure = Calldown;
CallbackContext->CallbackContextOrdinal = 0;
CallbackContext->RxDeviceObject = RxDeviceObject;
RxReferenceSrvCall(SrvCall);
/* If we're async, we'll post, otherwise, we'll have to wait for completion */
if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
{
RxPrePostIrp(RxContext, RxContext->CurrentIrp);
}
else
{
KeInitializeEvent(&Calldown->FinishEvent, SynchronizationEvent, FALSE);
}
Calldown->NumberToWait = 1;
Calldown->NumberRemaining = 1;
Calldown->RxContext = RxContext;
Calldown->SrvCall = (PMRX_SRV_CALL)SrvCall;
Calldown->CallBack = RxCreateSrvCallCallBack;
Calldown->BestFinisher = NULL;
CallbackContext->Status = STATUS_BAD_NETWORK_PATH;
InitializeListHead(&Calldown->SrvCalldownList);
/* Call the mini-rdr */
ASSERT(RxDeviceObject->Dispatch != NULL);
ASSERT(NodeType(RxDeviceObject->Dispatch) == RDBSS_NTC_MINIRDR_DISPATCH);
ASSERT(RxDeviceObject->Dispatch->MRxCreateSrvCall != NULL);
Status = RxDeviceObject->Dispatch->MRxCreateSrvCall((PMRX_SRV_CALL)SrvCall, CallbackContext);
/* It has to return STATUS_PENDING! */
ASSERT(Status == STATUS_PENDING);
/* No async, start completion */
if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
{
KeWaitForSingleObject(&Calldown->FinishEvent, Executive, KernelMode, FALSE, NULL);
/* Finish construction - we'll notify mini-rdr it's the winner */
Status = RxFinishSrvCallConstruction(Calldown);
if (!NT_SUCCESS(Status))
{
RxReleasePrefixTableLock(PrefixTable);
*LockHoldingState = LHS_LockNotHeld;
}
else
{
ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
*LockHoldingState = LHS_ExclusiveLockHeld;
}
}
DPRINT("RxConstructSrvCall() = Status: %x\n", Status);
return Status;
}
/*
* @implemented
*/
NTSTATUS
RxConstructVirtualNetRoot(
IN PRX_CONTEXT RxContext,
IN PUNICODE_STRING CanonicalName,
IN NET_ROOT_TYPE NetRootType,
OUT PV_NET_ROOT *VirtualNetRootPointer,
OUT PLOCK_HOLDING_STATE LockHoldingState,
OUT PRX_CONNECTION_ID RxConnectionId)
{
NTSTATUS Status;
PV_NET_ROOT VNetRoot;
RX_BLOCK_CONDITION Condition;
UNICODE_STRING LocalNetRootName, FilePathName;
PAGED_CODE();
ASSERT(*LockHoldingState != LHS_LockNotHeld);
VNetRoot = NULL;
Condition = Condition_Bad;
/* Before creating the VNetRoot, try to find the appropriate connection */
Status = RxFindOrCreateConnections(RxContext, CanonicalName, NetRootType,
&LocalNetRootName, &FilePathName,
LockHoldingState, RxConnectionId);
/* Found and active */
if (Status == STATUS_CONNECTION_ACTIVE)
{
/* We need a new VNetRoot */
VNetRoot = RxCreateVNetRoot(RxContext, (PNET_ROOT)RxContext->Create.pVNetRoot->pNetRoot,
CanonicalName, &LocalNetRootName, &FilePathName, RxConnectionId);
if (VNetRoot != NULL)
{
RxReferenceVNetRoot(VNetRoot);
}
/* Dereference previous VNetRoot */
RxDereferenceVNetRoot(RxContext->Create.pVNetRoot->pNetRoot, *LockHoldingState);
/* Reset and start construct (new structures will replace old ones) */
RxContext->Create.pSrvCall = NULL;
RxContext->Create.pNetRoot = NULL;
RxContext->Create.pVNetRoot = NULL;
/* Construct new NetRoot */
if (VNetRoot != NULL)
{
Status = RxConstructNetRoot(RxContext, (PSRV_CALL)VNetRoot->pNetRoot->pSrvCall,
(PNET_ROOT)VNetRoot->pNetRoot, VNetRoot, LockHoldingState);
if (NT_SUCCESS(Status))
{
Condition = Condition_Good;
}
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
/* If it failed creating the connection, leave */
if (Status != STATUS_SUCCESS)
{
if (*LockHoldingState != LHS_LockNotHeld)
{
RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
*LockHoldingState = LHS_LockNotHeld;
}
*VirtualNetRootPointer = VNetRoot;
DPRINT("RxConstructVirtualNetRoot() = Status: %x\n", Status);
return Status;
}
*LockHoldingState = LHS_ExclusiveLockHeld;
VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
Condition = Condition_Good;
}
/* We have a non stable VNetRoot - transition it */
if (VNetRoot != NULL && !StableCondition(VNetRoot->Condition))
{
RxTransitionVNetRoot(VNetRoot, Condition);
}
/* If recreation failed */
if (Status != STATUS_SUCCESS)
{
/* Dereference potential VNetRoot */
if (VNetRoot != NULL)
{
ASSERT(*LockHoldingState != LHS_LockNotHeld);
RxDereferenceVNetRoot(VNetRoot, *LockHoldingState);
VNetRoot = NULL;
}
/* Release lock */
if (*LockHoldingState != LHS_LockNotHeld)
{
RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
*LockHoldingState = LHS_LockNotHeld;
}
/* Set NULL ptr */
*VirtualNetRootPointer = VNetRoot;
return Status;
}
/* Return the allocated VNetRoot */
*VirtualNetRootPointer = VNetRoot;
return Status;
}
/*
* @implemented
*/
PFCB
RxCreateNetFcb(
IN PRX_CONTEXT RxContext,
IN PV_NET_ROOT VNetRoot,
IN PUNICODE_STRING Name)
{
PFCB Fcb;
BOOLEAN FakeFcb;
PNET_ROOT NetRoot;
POOL_TYPE PoolType;
NODE_TYPE_CODE NodeType;
PIO_STACK_LOCATION Stack;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
PAGED_CODE();
/* We need a decent VNetRoot */
ASSERT(VNetRoot != NULL && NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT);
NetRoot = (PNET_ROOT)VNetRoot->pNetRoot;
ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
ASSERT((PMRX_NET_ROOT)NetRoot == RxContext->Create.pNetRoot);
RxDeviceObject = NetRoot->pSrvCall->RxDeviceObject;
ASSERT(RxDeviceObject == RxContext->RxDeviceObject);
Stack = RxContext->CurrentIrpSp;
/* Do we need to create a fake FCB? Like for renaming */
FakeFcb = BooleanFlagOn(Stack->Flags, SL_OPEN_TARGET_DIRECTORY) &&
!BooleanFlagOn(NetRoot->Flags, NETROOT_FLAG_SUPPORTS_SYMBOLIC_LINKS);
ASSERT(FakeFcb || RxIsFcbTableLockExclusive(&NetRoot->FcbTable));
PoolType = (BooleanFlagOn(Stack->Flags, SL_OPEN_PAGING_FILE) ? NonPagedPool : PagedPool);
NodeType = (FakeFcb) ? RDBSS_NTC_OPENTARGETDIR_FCB : RDBSS_STORAGE_NTC(FileTypeNotYetKnown);
/* Allocate the FCB */
Fcb = RxAllocateFcbObject(RxDeviceObject, NodeType, PoolType,
NetRoot->InnerNamePrefix.Length + Name->Length, NULL);
if (Fcb == NULL)
{
return NULL;
}
/* Initialize the FCB */
Fcb->CachedNetRootType = NetRoot->Type;
Fcb->RxDeviceObject = RxDeviceObject;
Fcb->MRxDispatch = RxDeviceObject->Dispatch;
Fcb->VNetRoot = VNetRoot;
Fcb->pNetRoot = VNetRoot->pNetRoot;
InitializeListHead(&Fcb->SrvOpenList);
Fcb->SrvOpenListVersion = 0;
Fcb->FcbTableEntry.Path.Length = Name->Length;
Fcb->FcbTableEntry.Path.MaximumLength = Name->Length;
Fcb->FcbTableEntry.Path.Buffer = Add2Ptr(Fcb->PrivateAlreadyPrefixedName.Buffer, NetRoot->InnerNamePrefix.Length);
RtlMoveMemory(Fcb->PrivateAlreadyPrefixedName.Buffer, NetRoot->InnerNamePrefix.Buffer,
NetRoot->InnerNamePrefix.Length);
RtlMoveMemory(Fcb->FcbTableEntry.Path.Buffer, Name->Buffer, Name->Length);
/* Copy back parameters from RxContext */
if (BooleanFlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_ADDEDBACKSLASH))
{
Fcb->FcbState |= FCB_STATE_ADDEDBACKSLASH;
}
InitializeListHead(&Fcb->NonPaged->TransitionWaitList);
if (BooleanFlagOn(Stack->Flags, SL_OPEN_PAGING_FILE))
{
Fcb->FcbState |= FCB_STATE_PAGING_FILE;
}
if (RxContext->MajorFunction == IRP_MJ_CREATE && BooleanFlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_SPECIAL_PATH))
{
Fcb->FcbState |= FCB_STATE_SPECIAL_PATH;
}
Fcb->Header.Resource = &Fcb->NonPaged->HeaderResource;
ExInitializeResourceLite(Fcb->Header.Resource);
Fcb->Header.PagingIoResource = &Fcb->NonPaged->PagingIoResource;
ExInitializeResourceLite(Fcb->Header.PagingIoResource);
Fcb->BufferedLocks.Resource = &Fcb->NonPaged->BufferedLocksResource;
ExInitializeResourceLite(Fcb->BufferedLocks.Resource);
/* Fake FCB doesn't go in prefix table */
if (FakeFcb)
{
Fcb->FcbState |= (FCB_STATE_FAKEFCB | FCB_STATE_NAME_ALREADY_REMOVED);
InitializeListHead(&Fcb->FcbTableEntry.HashLinks);
DPRINT("Fake FCB: %p\n", Fcb);
}
else
{
RxFcbTableInsertFcb(&NetRoot->FcbTable, Fcb);
}
RxReferenceVNetRoot(VNetRoot);
InterlockedIncrement((volatile long *)&Fcb->pNetRoot->NumberOfFcbs);
Fcb->ulFileSizeVersion = 0;
DPRINT("FCB %p for %wZ\n", Fcb, &Fcb->FcbTableEntry.Path);
RxReferenceNetFcb(Fcb);
return Fcb;
}
/*
* @implemented
*/
PMRX_FOBX
NTAPI
RxCreateNetFobx(
OUT PRX_CONTEXT RxContext,
IN PMRX_SRV_OPEN MrxSrvOpen)
{
PFCB Fcb;
PFOBX Fobx;
ULONG Flags;
PNET_ROOT NetRoot;
PSRV_OPEN SrvOpen;
POOL_TYPE PoolType;
PAGED_CODE();
SrvOpen = (PSRV_OPEN)MrxSrvOpen;
ASSERT(NodeType(SrvOpen) == RDBSS_NTC_SRVOPEN);
ASSERT(NodeTypeIsFcb(SrvOpen->Fcb));
ASSERT(RxIsFcbAcquiredExclusive(SrvOpen->Fcb));
Fcb = SrvOpen->Fcb;
PoolType = (BooleanFlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE) ? NonPagedPool : PagedPool);
/* Can we use pre-allocated FOBX? */
if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_FOBX_USED) && Fcb->InternalSrvOpen == (PSRV_OPEN)MrxSrvOpen)
{
Fobx = Fcb->InternalFobx;
/* Call allocate to initialize the FOBX */
RxAllocateFcbObject(Fcb->RxDeviceObject, RDBSS_NTC_FOBX, PoolType, 0, Fobx);
/* Mark it used now */
Fcb->FcbState |= FCB_STATE_FOBX_USED;
Flags = FOBX_FLAG_ENCLOSED_ALLOCATED;
}
else if (!BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FOBX_USED))
{
Fobx = SrvOpen->InternalFobx;
/* Call allocate to initialize the FOBX */
RxAllocateFcbObject(Fcb->RxDeviceObject, RDBSS_NTC_FOBX, PoolType, 0, Fobx);
/* Mark it used now */
SrvOpen->Flags |= SRVOPEN_FLAG_FOBX_USED;
Flags = FOBX_FLAG_ENCLOSED_ALLOCATED;
}
else
{
/* Last case, we cannot, allocate a FOBX */
Fobx = RxAllocateFcbObject(Fcb->RxDeviceObject, RDBSS_NTC_FOBX, PoolType, 0, NULL);
Flags = 0;
}
/* Allocation failed! */
if (Fobx == NULL)
{
return NULL;
}
/* Set flags */
Fobx->Flags = Flags;
/* Initialize throttling */
NetRoot = (PNET_ROOT)RxContext->Create.pNetRoot;
if (NetRoot != NULL)
{
if (NetRoot->DeviceType == FILE_DEVICE_DISK)
{
RxInitializeThrottlingState(&Fobx->Specific.DiskFile.LockThrottlingState,
NetRoot->DiskParameters.LockThrottlingParameters.Increment,
NetRoot->DiskParameters.LockThrottlingParameters.MaximumDelay);
}
else if (NetRoot->DeviceType == FILE_DEVICE_NAMED_PIPE)
{
RxInitializeThrottlingState(&Fobx->Specific.NamedPipe.ThrottlingState,
NetRoot->NamedPipeParameters.PipeReadThrottlingParameters.Increment,
NetRoot->NamedPipeParameters.PipeReadThrottlingParameters.MaximumDelay);
}
}
/* Propagate flags fron RxContext */
if (BooleanFlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_UNC_NAME))
{
Fobx->Flags |= FOBX_FLAG_UNC_NAME;
}
if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT))
{
Fobx->Flags |= FOBX_FLAG_BACKUP_INTENT;
}
/* Continue init */
Fobx->FobxSerialNumber = 0;
Fobx->SrvOpen = (PSRV_OPEN)MrxSrvOpen;
Fobx->NodeReferenceCount = 1;
Fobx->RxDeviceObject = Fcb->RxDeviceObject;
RxReferenceSrvOpen(SrvOpen);
InterlockedIncrement((volatile long *)&SrvOpen->pVNetRoot->NumberOfFobxs);
InsertTailList(&SrvOpen->FobxList, &Fobx->FobxQLinks);
InitializeListHead(&Fobx->ScavengerFinalizationList);
InitializeListHead(&Fobx->ClosePendingList);
Fobx->CloseTime.QuadPart = 0;
Fobx->fOpenCountDecremented = FALSE;
DPRINT("FOBX %p for SRV_OPEN %p FCB %p\n", Fobx, Fobx->SrvOpen, Fobx->SrvOpen->pFcb);
return (PMRX_FOBX)Fobx;
}
/*
* @implemented
*/
PNET_ROOT
RxCreateNetRoot(
IN PSRV_CALL SrvCall,
IN PUNICODE_STRING Name,
IN ULONG NetRootFlags,
IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
{
PNET_ROOT NetRoot;
USHORT CaseInsensitiveLength;
PRX_PREFIX_TABLE PrefixTable;
DPRINT("RxCreateNetRoot(%p, %wZ, %x, %p)\n", SrvCall, Name, NetRootFlags, RxConnectionId);
PAGED_CODE();
/* We need a SRV_CALL */
ASSERT(SrvCall != NULL);
PrefixTable = SrvCall->RxDeviceObject->pRxNetNameTable;
ASSERT(RxIsPrefixTableLockExclusive(PrefixTable));
/* Get name length */
CaseInsensitiveLength = SrvCall->PrefixEntry.Prefix.Length + Name->Length;
if (CaseInsensitiveLength > MAXUSHORT)
{
return NULL;
}
/* Allocate the NetRoot */
NetRoot = RxAllocateObject(RDBSS_NTC_NETROOT, SrvCall->RxDeviceObject->Dispatch,
CaseInsensitiveLength);
if (NetRoot == NULL)
{
return NULL;
}
/* Construct name */
RtlMoveMemory(Add2Ptr(NetRoot->PrefixEntry.Prefix.Buffer, SrvCall->PrefixEntry.Prefix.Length),
Name->Buffer, Name->Length);
if (SrvCall->PrefixEntry.Prefix.Length != 0)
{
RtlMoveMemory(NetRoot->PrefixEntry.Prefix.Buffer, SrvCall->PrefixEntry.Prefix.Buffer,
SrvCall->PrefixEntry.Prefix.Length);
}
if (!BooleanFlagOn(SrvCall->Flags, SRVCALL_FLAG_CASE_INSENSITIVE_NETROOTS))
{
CaseInsensitiveLength = SrvCall->PrefixEntry.CaseInsensitiveLength;
}
/* Inisert in prefix table */
RxPrefixTableInsertName(PrefixTable, &NetRoot->PrefixEntry, NetRoot,
(PULONG)&NetRoot->NodeReferenceCount, CaseInsensitiveLength,
RxConnectionId);
/* Prepare the FCB table */
RxInitializeFcbTable(&NetRoot->FcbTable, TRUE);
InitializeListHead(&NetRoot->TransitionWaitList);
InitializeListHead(&NetRoot->ScavengerFinalizationList);
InitializeListHead(&NetRoot->VirtualNetRoots);
RxInitializePurgeSyncronizationContext(&NetRoot->PurgeSyncronizationContext);
NetRoot->SerialNumberForEnum = SerialNumber++;
NetRoot->Flags |= NetRootFlags;
NetRoot->DiskParameters.ClusterSize = 1;
NetRoot->DiskParameters.ReadAheadGranularity = ReadAheadGranularity;
NetRoot->SrvCall = SrvCall;
RxReferenceSrvCall(SrvCall);
DPRINT("NetRootName: %wZ (%p)\n", NetRoot->pNetRootName, NetRoot);
return NetRoot;
}
/*
* @implemented
*/
VOID
NTAPI
RxCreateNetRootCallBack(
IN PMRX_CREATENETROOT_CONTEXT CreateNetRootContext)
{
PAGED_CODE();
KeSetEvent(&CreateNetRootContext->FinishEvent, IO_NETWORK_INCREMENT, FALSE);
}
/*
* @implemented
*/
PRX_CONTEXT
NTAPI
RxCreateRxContext(
IN PIRP Irp,
IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
IN ULONG InitialContextFlags)
{
KIRQL OldIrql;
PRX_CONTEXT Context;
ASSERT(RxDeviceObject != NULL);
DPRINT("RxCreateRxContext(%p, %p, %u)\n", Irp, RxDeviceObject, InitialContextFlags);
#if DBG
InterlockedIncrement((volatile LONG *)&RxFsdEntryCount);
#endif
InterlockedIncrement((volatile LONG *)&RxDeviceObject->NumberOfActiveContexts);
/* Allocate the context from our lookaside list */
Context = ExAllocateFromNPagedLookasideList(&RxContextLookasideList);
if (Context == NULL)
{
return NULL;
}
/* Zero it */
RtlZeroMemory(Context, sizeof(RX_CONTEXT));
/* It was allocated on NP pool, keep track of it! */
SetFlag(Context->Flags, RX_CONTEXT_FLAG_FROM_POOL);
/* And initialize it */
RxInitializeContext(Irp, RxDeviceObject, InitialContextFlags, Context);
ASSERT((Context->MajorFunction != IRP_MJ_CREATE) || !BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED));
/* Add it to our global list */
KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql);
InsertTailList(&RxActiveContexts, &Context->ContextListEntry);
KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql);
DPRINT("Context: %p\n", Context);
return Context;
}
/*
* @implemented
*/
PSRV_CALL
RxCreateSrvCall(
IN PRX_CONTEXT RxContext,
IN PUNICODE_STRING Name,
IN PUNICODE_STRING InnerNamePrefix OPTIONAL,
IN PRX_CONNECTION_ID RxConnectionId)
{
ULONG NameLength;
PSRV_CALL SrvCall;
PAGED_CODE();
DPRINT("RxCreateSrvCall(%p, %wZ, %wZ, %p)\n", RxContext, Name, InnerNamePrefix, RxConnectionId);
ASSERT(RxIsPrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable));
/* Get the name length */
NameLength = Name->Length + 2 * sizeof(WCHAR);
if (InnerNamePrefix != NULL)
{
NameLength += InnerNamePrefix->Length;
}
/* Allocate the object */
SrvCall = RxAllocateObject(RDBSS_NTC_SRVCALL, NULL, NameLength);
if (SrvCall == NULL)
{
return NULL;
}
/* Initialize it */
SrvCall->SerialNumberForEnum = SerialNumber++;
SrvCall->RxDeviceObject = RxContext->RxDeviceObject;
RxInitializeBufferingManager(SrvCall);
InitializeListHead(&SrvCall->TransitionWaitList);
InitializeListHead(&SrvCall->ScavengerFinalizationList);
RxInitializePurgeSyncronizationContext(&SrvCall->PurgeSyncronizationContext);
RxInitializeSrvCallParameters(RxContext, SrvCall);
RtlMoveMemory(SrvCall->PrefixEntry.Prefix.Buffer, Name->Buffer, Name->Length);
SrvCall->PrefixEntry.Prefix.MaximumLength = Name->Length + 2 * sizeof(WCHAR);
SrvCall->PrefixEntry.Prefix.Length = Name->Length;
RxPrefixTableInsertName(RxContext->RxDeviceObject->pRxNetNameTable, &SrvCall->PrefixEntry,
SrvCall, (PULONG)&SrvCall->NodeReferenceCount, Name->Length, RxConnectionId);
DPRINT("SrvCallName: %wZ (%p)\n", SrvCall->pSrvCallName, SrvCall);
return SrvCall;
}
/*
* @implemented
*/
VOID
NTAPI
RxCreateSrvCallCallBack(
IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT Context)
{
KIRQL OldIrql;
PSRV_CALL SrvCall;
PRX_CONTEXT RxContext;
ULONG NumberRemaining;
BOOLEAN StartDispatcher;
PMRX_SRVCALLDOWN_STRUCTURE Calldown;
DPRINT("RxCreateSrvCallCallBack(%p)\n", Context);
/* Get our context structures */
Calldown = Context->SrvCalldownStructure;
SrvCall = (PSRV_CALL)Calldown->SrvCall;
/* If it is a success, that's the winner */
KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql);
if (Context->Status == STATUS_SUCCESS)
{
Calldown->BestFinisherOrdinal = Context->CallbackContextOrdinal;
Calldown->BestFinisher = Context->RxDeviceObject;
}
NumberRemaining = --Calldown->NumberRemaining;
SrvCall->Status = Context->Status;
KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql);
/* Still some to ask, keep going */
if (NumberRemaining != 0)
{
return;
}
/* If that's not async, signal we're done */
RxContext = Calldown->RxContext;
if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
{
KeSetEvent(&Calldown->FinishEvent, IO_NETWORK_INCREMENT, FALSE);
return;
}
/* If that's a mailslot, finish construction, no more to do */
else if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_CREATE_MAILSLOT))
{
RxFinishSrvCallConstruction(Calldown);
return;
}
/* Queue our finish call for delayed completion */
DPRINT("Queuing RxFinishSrvCallConstruction() call\n");
KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql);
InsertTailList(&RxSrvCalldownList, &Calldown->SrvCalldownList);
StartDispatcher = !RxSrvCallConstructionDispatcherActive;
KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql);
/* If we have to start dispatcher, go ahead */
if (StartDispatcher)
{
NTSTATUS Status;
Status = RxDispatchToWorkerThread(RxFileSystemDeviceObject, CriticalWorkQueue,
RxFinishSrvCallConstructionDispatcher, &RxSrvCalldownList);
if (!NT_SUCCESS(Status))
{
/* It failed - run it manually.... */
RxFinishSrvCallConstructionDispatcher(NULL);
}
}
}
/*
* @implemented
*/
PSRV_OPEN
RxCreateSrvOpen(
IN PV_NET_ROOT VNetRoot,
IN OUT PFCB Fcb)
{
ULONG Flags;
PSRV_OPEN SrvOpen;
POOL_TYPE PoolType;
PAGED_CODE();
ASSERT(NodeTypeIsFcb(Fcb));
ASSERT(RxIsFcbAcquiredExclusive(Fcb));
PoolType = (BooleanFlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE) ? NonPagedPool : PagedPool);
_SEH2_TRY
{
SrvOpen = Fcb->InternalSrvOpen;
/* Check whethet we have to allocate a new SRV_OPEN */
if (Fcb->InternalSrvOpen == NULL || BooleanFlagOn(Fcb->FcbState, FCB_STATE_SRVOPEN_USED) ||
BooleanFlagOn(Fcb->InternalSrvOpen->Flags, SRVOPEN_FLAG_ENCLOSED_ALLOCATED) ||
!IsListEmpty(&Fcb->InternalSrvOpen->SrvOpenQLinks))
{
/* Proceed */
SrvOpen = RxAllocateFcbObject(Fcb->VNetRoot->NetRoot->pSrvCall->RxDeviceObject,
RDBSS_NTC_SRVOPEN, PoolType, 0, NULL);
Flags = 0;
}
else
{
/* Otherwise, just use internal one and initialize it */
RxAllocateFcbObject(Fcb->VNetRoot->NetRoot->pSrvCall->RxDeviceObject,
RDBSS_NTC_INTERNAL_SRVOPEN, PoolType, 0,
Fcb->InternalSrvOpen);
Fcb->FcbState |= FCB_STATE_SRVOPEN_USED;
Flags = SRVOPEN_FLAG_ENCLOSED_ALLOCATED | SRVOPEN_FLAG_FOBX_USED;
}
/* If SrvOpen was properly allocated, initialize it */
if (SrvOpen != NULL)
{
SrvOpen->Flags = Flags;
SrvOpen->pFcb = RX_GET_MRX_FCB(Fcb);
SrvOpen->pAlreadyPrefixedName = &Fcb->PrivateAlreadyPrefixedName;
SrvOpen->pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
SrvOpen->ulFileSizeVersion = Fcb->ulFileSizeVersion;
SrvOpen->NodeReferenceCount = 1;
RxReferenceVNetRoot(VNetRoot);
RxReferenceNetFcb(Fcb);
InsertTailList(&Fcb->SrvOpenList, &SrvOpen->SrvOpenQLinks);
++Fcb->SrvOpenListVersion;
InitializeListHead(&SrvOpen->ScavengerFinalizationList);
InitializeListHead(&SrvOpen->TransitionWaitList);
InitializeListHead(&SrvOpen->FobxList);
InitializeListHead(&SrvOpen->SrvOpenKeyList);
}
}
_SEH2_FINALLY
{
if (_SEH2_AbnormalTermination())
{
if (SrvOpen != NULL)
{
RxFinalizeSrvOpen(SrvOpen, TRUE, TRUE);
SrvOpen = NULL;
}
}
else
{
DPRINT("SrvOpen %p for FCB %p\n", SrvOpen, SrvOpen->pFcb);
}
}
_SEH2_END;
return SrvOpen;
}
/*
* @implemented
*/
PV_NET_ROOT
RxCreateVNetRoot(
IN PRX_CONTEXT RxContext,
IN PNET_ROOT NetRoot,
IN PUNICODE_STRING CanonicalName,
IN PUNICODE_STRING LocalNetRootName,
IN PUNICODE_STRING FilePath,
IN PRX_CONNECTION_ID RxConnectionId)
{
NTSTATUS Status;
PV_NET_ROOT VNetRoot;
USHORT CaseInsensitiveLength;
PAGED_CODE();
DPRINT("RxCreateVNetRoot(%p, %p, %wZ, %wZ, %wZ, %p)\n", RxContext, NetRoot, CanonicalName,
LocalNetRootName, FilePath, RxConnectionId);
/* Lock must be held exclusively */
ASSERT(RxIsPrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable));
/* Check for overflow */
if (LocalNetRootName->Length + NetRoot->PrefixEntry.Prefix.Length > MAXUSHORT)
{
return NULL;
}
/* Get name length and allocate VNetRoot */
CaseInsensitiveLength = LocalNetRootName->Length + NetRoot->PrefixEntry.Prefix.Length;
VNetRoot = RxAllocateObject(RDBSS_NTC_V_NETROOT, NetRoot->SrvCall->RxDeviceObject->Dispatch,
CaseInsensitiveLength);
if (VNetRoot == NULL)
{
return NULL;
}
/* Initialize its connection parameters */
Status = RxInitializeVNetRootParameters(RxContext, &VNetRoot->LogonId, &VNetRoot->SessionId,
&VNetRoot->pUserName, &VNetRoot->pUserDomainName,
&VNetRoot->pPassword, &VNetRoot->Flags);
if (!NT_SUCCESS(Status))
{
RxUninitializeVNetRootParameters(VNetRoot->pUserName, VNetRoot->pUserDomainName,
VNetRoot->pPassword, &VNetRoot->Flags);
RxFreeObject(VNetRoot);
return NULL;
}
/* Set name */
RtlMoveMemory(VNetRoot->PrefixEntry.Prefix.Buffer, CanonicalName->Buffer, VNetRoot->PrefixEntry.Prefix.Length);
VNetRoot->PrefixOffsetInBytes = LocalNetRootName->Length + NetRoot->PrefixEntry.Prefix.Length;
VNetRoot->NamePrefix.Buffer = Add2Ptr(VNetRoot->PrefixEntry.Prefix.Buffer, VNetRoot->PrefixOffsetInBytes);
VNetRoot->NamePrefix.Length = VNetRoot->PrefixEntry.Prefix.Length - VNetRoot->PrefixOffsetInBytes;
VNetRoot->NamePrefix.MaximumLength = VNetRoot->PrefixEntry.Prefix.Length - VNetRoot->PrefixOffsetInBytes;
InitializeListHead(&VNetRoot->TransitionWaitList);
InitializeListHead(&VNetRoot->ScavengerFinalizationList);
if (!BooleanFlagOn(NetRoot->SrvCall->Flags, SRVCALL_FLAG_CASE_INSENSITIVE_FILENAMES))
{
USHORT i;
if (BooleanFlagOn(NetRoot->SrvCall->Flags, SRVCALL_FLAG_CASE_INSENSITIVE_NETROOTS))
{
CaseInsensitiveLength = NetRoot->PrefixEntry.CaseInsensitiveLength;
}
else
{
CaseInsensitiveLength = NetRoot->SrvCall->PrefixEntry.CaseInsensitiveLength;
}
for (i = 1; i < CanonicalName->Length / sizeof(WCHAR); ++i)
{
if (CanonicalName->Buffer[i] != OBJ_NAME_PATH_SEPARATOR)
{
break;
}
}
CaseInsensitiveLength += (i * sizeof(WCHAR));
}
/* Insert in prefix table */
RxPrefixTableInsertName(RxContext->RxDeviceObject->pRxNetNameTable, &VNetRoot->PrefixEntry,
VNetRoot, (PULONG)&VNetRoot->NodeReferenceCount, CaseInsensitiveLength,
RxConnectionId);
RxReferenceNetRoot(NetRoot);
RxAddVirtualNetRootToNetRoot(NetRoot, VNetRoot);
/* Finish init */
VNetRoot->SerialNumberForEnum = SerialNumber++;
VNetRoot->UpperFinalizationDone = FALSE;
VNetRoot->ConnectionFinalizationDone = FALSE;
VNetRoot->AdditionalReferenceForDeleteFsctlTaken = 0;
DPRINT("NamePrefix: %wZ\n", &VNetRoot->NamePrefix);
DPRINT("PrefixEntry: %wZ\n", &VNetRoot->PrefixEntry.Prefix);
return VNetRoot;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxDereference(
IN OUT PVOID Instance,
IN LOCK_HOLDING_STATE LockHoldingState)
{
LONG RefCount;
NODE_TYPE_CODE NodeType;
PNODE_TYPE_AND_SIZE Node;
PAGED_CODE();
RxAcquireScavengerMutex();
/* Check we have a node we can handle */
NodeType = NodeType(Instance);
ASSERT((NodeType == RDBSS_NTC_SRVCALL) || (NodeType == RDBSS_NTC_NETROOT) ||
(NodeType == RDBSS_NTC_V_NETROOT) || (NodeType == RDBSS_NTC_SRVOPEN) ||
(NodeType == RDBSS_NTC_FOBX));
Node = (PNODE_TYPE_AND_SIZE)Instance;
RefCount = InterlockedDecrement((volatile long *)&Node->NodeReferenceCount);
ASSERT(RefCount >= 0);
/* Trace refcount */
switch (NodeType)
{
case RDBSS_NTC_SRVCALL:
PRINT_REF_COUNT(SRVCALL, Node->NodeReferenceCount);
break;
case RDBSS_NTC_NETROOT:
PRINT_REF_COUNT(NETROOT, Node->NodeReferenceCount);
break;
case RDBSS_NTC_V_NETROOT:
PRINT_REF_COUNT(VNETROOT, Node->NodeReferenceCount);
break;
case RDBSS_NTC_SRVOPEN:
PRINT_REF_COUNT(SRVOPEN, Node->NodeReferenceCount);
break;
case RDBSS_NTC_FOBX:
PRINT_REF_COUNT(NETFOBX, Node->NodeReferenceCount);
break;
default:
ASSERT(FALSE);
break;
}
/* No need to free - still in use */
if (RefCount > 1)
{
RxReleaseScavengerMutex();
return;
}
/* We have to be locked exclusively */
if (LockHoldingState != LHS_ExclusiveLockHeld)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
if ((NodeType == RDBSS_NTC_FOBX && RefCount == 0) ||
(NodeType >= RDBSS_NTC_SRVCALL && NodeType <= RDBSS_NTC_V_NETROOT))
{
RxpMarkInstanceForScavengedFinalization(Instance);
}
RxReleaseScavengerMutex();
return;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
else
{
if (BooleanFlagOn(NodeType, RX_SCAVENGER_MASK))
{
RxpUndoScavengerFinalizationMarking(Instance);
}
}
RxReleaseScavengerMutex();
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/* Now, deallocate the memory */
switch (NodeType)
{
case RDBSS_NTC_SRVCALL:
{
PSRV_CALL SrvCall;
SrvCall = (PSRV_CALL)Instance;
ASSERT(SrvCall->RxDeviceObject != NULL);
ASSERT(RxIsPrefixTableLockAcquired(SrvCall->RxDeviceObject->pRxNetNameTable));
RxFinalizeSrvCall(SrvCall, TRUE, TRUE);
break;
}
case RDBSS_NTC_NETROOT:
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
{
PNET_ROOT NetRoot;
NetRoot = (PNET_ROOT)Instance;
ASSERT(NetRoot->pSrvCall->RxDeviceObject != NULL);
ASSERT(RxIsPrefixTableLockAcquired(NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable));
RxFinalizeNetRoot(NetRoot, TRUE, TRUE);
break;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
}
case RDBSS_NTC_V_NETROOT:
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
{
PV_NET_ROOT VNetRoot;
VNetRoot = (PV_NET_ROOT)Instance;
ASSERT(VNetRoot->pNetRoot->pSrvCall->RxDeviceObject != NULL);
ASSERT(RxIsPrefixTableLockAcquired(VNetRoot->pNetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable));
RxFinalizeVNetRoot(VNetRoot, TRUE, TRUE);
break;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
}
case RDBSS_NTC_SRVOPEN:
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
{
PSRV_OPEN SrvOpen;
SrvOpen = (PSRV_OPEN)Instance;
ASSERT(RxIsFcbAcquired(SrvOpen->Fcb));
if (SrvOpen->OpenCount == 0)
{
RxFinalizeSrvOpen(SrvOpen, FALSE, FALSE);
}
break;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
}
case RDBSS_NTC_FOBX:
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
{
PFOBX Fobx;
Fobx = (PFOBX)Instance;
ASSERT(RxIsFcbAcquired(Fobx->SrvOpen->Fcb));
RxFinalizeNetFobx(Fobx, TRUE, FALSE);
break;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
}
}
}
/*
* @implemented
*/
VOID
NTAPI
RxDereferenceAndDeleteRxContext_Real(
IN PRX_CONTEXT RxContext)
{
KIRQL OldIrql;
ULONG RefCount;
BOOLEAN Allocated;
PRX_CONTEXT StopContext = NULL;
/* Make sure we really have a context */
KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql);
ASSERT(RxContext->NodeTypeCode == RDBSS_NTC_RX_CONTEXT);
RefCount = InterlockedDecrement((volatile LONG *)&RxContext->ReferenceCount);
/* If refcount is 0, start releasing stuff that needs spinlock held */
if (RefCount == 0)
{
PRDBSS_DEVICE_OBJECT RxDeviceObject;
Allocated = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_FROM_POOL);
/* If that's stop context from DO, remove it */
RxDeviceObject = RxContext->RxDeviceObject;
if (RxDeviceObject->StartStopContext.pStopContext == RxContext)
{
RxDeviceObject->StartStopContext.pStopContext = NULL;
}
else
{
/* Remove it from the list */
ASSERT((RxContext->ContextListEntry.Flink->Blink == &RxContext->ContextListEntry) &&
(RxContext->ContextListEntry.Blink->Flink == &RxContext->ContextListEntry));
RemoveEntryList(&RxContext->ContextListEntry);
/* If that was the last active context, save the stop context */
if (InterlockedExchangeAdd((volatile LONG *)&RxDeviceObject->NumberOfActiveContexts, -1) == 0)
{
if (RxDeviceObject->StartStopContext.pStopContext != NULL)
{
StopContext = RxDeviceObject->StartStopContext.pStopContext;
}
}
}
}
KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql);
/* Now, deal with what can be done without spinlock held */
if (RefCount == 0)
{
/* Refcount shouldn't have changed */
ASSERT(RxContext->ReferenceCount == 0);
/* Reset everything that can be */
RxPrepareContextForReuse(RxContext);
#ifdef RDBSS_TRACKER
ASSERT(RxContext->AcquireReleaseFcbTrackerX == 0);
#endif
/* If that was the last active, set the event */
if (StopContext != NULL)
{
StopContext->Flags &= ~RX_CONTEXT_FLAG_RECURSIVE_CALL;
KeSetEvent(&StopContext->SyncEvent, IO_NO_INCREMENT, FALSE);
}
#if DBG
/* Is ShadowCrit still owned? Shouldn't happen! */
if (RxContext->ShadowCritOwner != 0)
{
2018-04-23 09:27:49 +00:00
DPRINT1("ShadowCritOwner not null! %lx\n", RxContext->ShadowCritOwner);
ASSERT(FALSE);
}
#endif
/* If it was allocated, free it */
if (Allocated)
{
ExFreeToNPagedLookasideList(&RxContextLookasideList, RxContext);
}
}
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
VOID
NTAPI
RxDispatchChangeBufferingStateRequests(
PVOID Context)
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RxDispatchToWorkerThread(
IN PRDBSS_DEVICE_OBJECT pMRxDeviceObject,
IN WORK_QUEUE_TYPE WorkQueueType,
IN PRX_WORKERTHREAD_ROUTINE Routine,
IN PVOID pContext)
{
NTSTATUS Status;
PRX_WORK_DISPATCH_ITEM DispatchItem;
/* Allocate a bit of context */
DispatchItem = RxAllocatePoolWithTag(PagedPool, sizeof(RX_WORK_DISPATCH_ITEM), RX_WORKQ_POOLTAG);
if (DispatchItem == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Set all the routines, the one our dispatcher will call, the one ntoskrnl will call */
DispatchItem->DispatchRoutine = Routine;
DispatchItem->DispatchRoutineParameter = pContext;
DispatchItem->WorkQueueItem.WorkerRoutine = RxWorkItemDispatcher;
DispatchItem->WorkQueueItem.Parameter = DispatchItem;
/* Insert item */
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
Status = RxInsertWorkQueueItem(pMRxDeviceObject, WorkQueueType, &DispatchItem->WorkQueueItem);
if (!NT_SUCCESS(Status))
{
RxFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
DPRINT1("RxInsertWorkQueueItem failed! Queue: %ld, Routine: %p, Context: %p, Status: %lx\n", WorkQueueType, Routine, pContext, Status);
}
DPRINT("Dispatching: %p, %p\n", Routine, pContext);
return Status;
}
/*
* @implemented
*/
VOID
RxExclusivePrefixTableLockToShared(
PRX_PREFIX_TABLE Table)
{
PAGED_CODE();
ExConvertExclusiveToSharedLite(&Table->TableLock);
}
/*
* @implemented
*/
VOID
RxExtractServerName(
IN PUNICODE_STRING FilePathName,
OUT PUNICODE_STRING SrvCallName,
OUT PUNICODE_STRING RestOfName)
{
USHORT i, Length;
PAGED_CODE();
ASSERT(SrvCallName != NULL);
/* SrvCall name will start from the begin up to the first separator */
SrvCallName->Buffer = FilePathName->Buffer;
for (i = 1; i < FilePathName->Length / sizeof(WCHAR); ++i)
{
if (FilePathName->Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
{
break;
}
}
/* Compute length */
Length = (USHORT)((ULONG_PTR)&FilePathName->Buffer[i] - (ULONG_PTR)FilePathName->Buffer);
SrvCallName->MaximumLength = Length;
SrvCallName->Length = Length;
/* Return the rest if asked */
if (RestOfName != NULL)
{
Length = (USHORT)((ULONG_PTR)&FilePathName->Buffer[FilePathName->Length / sizeof(WCHAR)] - (ULONG_PTR)FilePathName->Buffer[i]);
RestOfName->Buffer = &FilePathName->Buffer[i];
RestOfName->MaximumLength = Length;
RestOfName->Length = Length;
}
}
/*
* @implemented
*/
NTSTATUS
RxFcbTableInsertFcb(
IN OUT PRX_FCB_TABLE FcbTable,
IN OUT PFCB Fcb)
{
PAGED_CODE();
/* We deal with the table, make sure it's locked */
ASSERT(RxIsFcbTableLockExclusive(FcbTable));
/* Compute the hash */
Fcb->FcbTableEntry.HashValue = RxTableComputePathHashValue(&Fcb->FcbTableEntry.Path);
RxReferenceNetFcb(Fcb);
/* If no length, it will be our null entry */
if (Fcb->FcbTableEntry.Path.Length == 0)
{
FcbTable->TableEntryForNull = &Fcb->FcbTableEntry;
}
/* Otherwise, insert in the appropriate bucket */
else
{
InsertTailList(FCB_HASH_BUCKET(FcbTable, Fcb->FcbTableEntry.HashValue),
&Fcb->FcbTableEntry.HashLinks);
}
/* Propagate the change by incrementing the version number */
InterlockedIncrement((volatile long *)&FcbTable->Version);
return STATUS_SUCCESS;
}
/*
* @implemented
*/
PFCB
RxFcbTableLookupFcb(
IN PRX_FCB_TABLE FcbTable,
IN PUNICODE_STRING Path)
{
PFCB Fcb;
PRX_FCB_TABLE_ENTRY TableEntry;
PAGED_CODE();
/* No path - easy, that's null entry */
if (Path == NULL)
{
TableEntry = FcbTable->TableEntryForNull;
}
else
{
ULONG Hash;
PLIST_ENTRY HashBucket, ListEntry;
/* Otherwise, compute the hash value and find the associated bucket */
Hash = RxTableComputePathHashValue(Path);
HashBucket = FCB_HASH_BUCKET(FcbTable, Hash);
/* If the bucket is empty, it means there's no entry yet */
if (IsListEmpty(HashBucket))
{
TableEntry = NULL;
}
else
{
/* Otherwise, browse all the entry */
for (ListEntry = HashBucket->Flink;
ListEntry != HashBucket;
ListEntry = ListEntry->Flink)
{
TableEntry = CONTAINING_RECORD(ListEntry, RX_FCB_TABLE_ENTRY, HashLinks);
InterlockedIncrement(&FcbTable->Compares);
/* If entry hash and string are equal, thatt's the one! */
if (TableEntry->HashValue == Hash &&
TableEntry->Path.Length == Path->Length &&
RtlEqualUnicodeString(Path, &TableEntry->Path, FcbTable->CaseInsensitiveMatch))
{
break;
}
}
/* We reached the end? Not found */
if (ListEntry == HashBucket)
{
TableEntry = NULL;
}
}
}
InterlockedIncrement(&FcbTable->Lookups);
/* If table entry isn't null, return the FCB */
if (TableEntry != NULL)
{
Fcb = CONTAINING_RECORD(TableEntry, FCB, FcbTableEntry);
RxReferenceNetFcb(Fcb);
}
else
{
Fcb = NULL;
InterlockedIncrement(&FcbTable->FailedLookups);
}
return Fcb;
}
/*
* @implemented
*/
NTSTATUS
RxFcbTableRemoveFcb(
IN OUT PRX_FCB_TABLE FcbTable,
IN OUT PFCB Fcb)
{
PAGED_CODE();
ASSERT(RxIsPrefixTableLockExclusive(FcbTable));
/* If no path, then remove entry for null */
if (Fcb->FcbTableEntry.Path.Length == 0)
{
FcbTable->TableEntryForNull = NULL;
}
/* Otherwise, remove from the bucket */
else
{
RemoveEntryList(&Fcb->FcbTableEntry.HashLinks);
}
/* Reset its list entry */
InitializeListHead(&Fcb->FcbTableEntry.HashLinks);
/* Propagate the change by incrementing the version number */
InterlockedIncrement((volatile long *)&FcbTable->Version);
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RxFinalizeConnection(
IN OUT PNET_ROOT NetRoot,
IN OUT PV_NET_ROOT VNetRoot OPTIONAL,
IN LOGICAL ForceFilesClosed)
{
NTSTATUS Status;
PRX_PREFIX_TABLE PrefixTable;
ULONG UncleanAny, UncleanDir;
LONG FilesOpen, AdditionalRef;
BOOLEAN PrefixLocked, FcbTableLocked, ForceClose;
PAGED_CODE();
ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
/* Get a BOOLEAN out of LOGICAL
* -1 is like FALSE but also drops extra V_NET_ROOT reference in case of failure
*/
ForceClose = (ForceFilesClosed == TRUE ? TRUE : FALSE);
/* First, delete any notification change */
Status = RxCancelNotifyChangeDirectoryRequestsForVNetRoot(VNetRoot, ForceClose);
/* If it failed, continue if forced */
if (Status != STATUS_SUCCESS && !ForceFilesClosed)
{
return Status;
}
/* Reset status, in case notification deletion failed */
Status = STATUS_SUCCESS;
PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
PrefixLocked = FALSE;
FcbTableLocked = FALSE;
FilesOpen = 0;
AdditionalRef = 0;
UncleanAny = 0;
UncleanDir = 0;
_SEH2_TRY
{
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
PrefixLocked = TRUE;
RxReferenceNetRoot(NetRoot);
RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
FcbTableLocked = TRUE;
/* If our V_NET_ROOT wasn't finalized yet, proceed! */
if (!VNetRoot->ConnectionFinalizationDone)
{
USHORT Bucket;
PRX_FCB_TABLE FcbTable;
DPRINT("Finalizing connection %p: %wZ\n", NetRoot, &NetRoot->PrefixEntry.Prefix);
/* We'll browse all its associated FCB to check whether they're open/orphaned */
FcbTable = &NetRoot->FcbTable;
for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
{
PLIST_ENTRY BucketList, Entry;
BucketList = &FcbTable->HashBuckets[Bucket];
Entry = BucketList->Flink;
while (Entry != BucketList)
{
PFCB Fcb;
Fcb = CONTAINING_RECORD(Entry, FCB, FcbTableEntry.HashLinks);
Entry = Entry->Flink;
/* FCB for this connection, go ahead */
if (Fcb->VNetRoot == VNetRoot)
{
/* It's still open, and no force? Fail and keep track */
if (Fcb->UncleanCount > 0 && !ForceClose)
{
Status = STATUS_CONNECTION_IN_USE;
if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
{
++UncleanDir;
}
else
{
++UncleanAny;
}
}
else
{
/* Else, force purge */
ASSERT(NodeTypeIsFcb(Fcb));
Status = RxAcquireExclusiveFcb(NULL, Fcb);
ASSERT(Status == STATUS_SUCCESS);
ClearFlag(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED);
RxScavengeRelatedFobxs(Fcb);
RxPurgeFcb(Fcb);
/* We don't need to release FCB lock, FCB finalize will take care of it */
}
}
}
}
/* No files left, our V_NET_ROOT is finalized */
if (VNetRoot->NumberOfFobxs == 0)
{
VNetRoot->ConnectionFinalizationDone = TRUE;
}
}
/* Keep Number of open files and track of the extra reference */
FilesOpen = VNetRoot->NumberOfFobxs;
AdditionalRef = VNetRoot->AdditionalReferenceForDeleteFsctlTaken;
/* If force close, caller doesn't want to keep connection alive
* and wants it totally close, so drop the V_NET_ROOT too
*/
if (ForceClose)
{
RxFinalizeVNetRoot(VNetRoot, FALSE, TRUE);
}
}
_SEH2_FINALLY
{
/* Release what was acquired */
if (FcbTableLocked)
{
RxReleaseFcbTableLock(&NetRoot->FcbTable);
}
/* If close is forced, only fix status if there are open files */
if (ForceClose)
{
if (Status != STATUS_SUCCESS && UncleanAny != 0)
{
Status = STATUS_FILES_OPEN;
}
}
/* Else, fix status and fail closing if there are open files */
else
{
if ((Status != STATUS_SUCCESS && UncleanAny != 0) || FilesOpen > 0)
{
Status = STATUS_FILES_OPEN;
}
}
DPRINT("UncleanAny: %ld, UncleanDir: %ld, FilesOpen: %ld\n", UncleanAny, UncleanDir, FilesOpen);
/* If we're are asked to remove the extra ref, or if closing was a success, do it;
* only if it was still referenced!
*/
if ((ForceFilesClosed == 0xFF || Status == STATUS_SUCCESS) && AdditionalRef != 0)
{
VNetRoot->AdditionalReferenceForDeleteFsctlTaken = 0;
RxDereferenceVNetRoot(VNetRoot, LHS_ExclusiveLockHeld);
}
if (PrefixLocked)
{
RxDereferenceNetRoot(NetRoot, LHS_ExclusiveLockHeld);
RxReleasePrefixTableLock(PrefixTable);
}
}
_SEH2_END;
return Status;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
RxFinalizeFcbTable(
IN OUT PRX_FCB_TABLE FcbTable)
{
USHORT Bucket;
PAGED_CODE();
/* Just delete the lock */
ExDeleteResourceLite(&FcbTable->TableLock);
/* And make sure (checked) that the table is really empty... */
for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
{
ASSERT(IsListEmpty(&FcbTable->HashBuckets[Bucket]));
}
}
/*
* @implemented
*/
BOOLEAN
RxFinalizeNetFcb(
OUT PFCB ThisFcb,
IN BOOLEAN RecursiveFinalize,
IN BOOLEAN ForceFinalize,
IN LONG ReferenceCount)
{
PAGED_CODE();
DPRINT("RxFinalizeNetFcb(%p, %d, %d, %d)\n", ThisFcb, RecursiveFinalize, ForceFinalize, ReferenceCount);
DPRINT("Finalize: %wZ\n", &ThisFcb->FcbTableEntry.Path);
/* Make sure we have an exclusively acquired FCB */
ASSERT_CORRECT_FCB_STRUCTURE(ThisFcb);
ASSERT(RxIsFcbAcquiredExclusive(ThisFcb));
/* We shouldn't force finalization... */
ASSERT(!ForceFinalize);
/* If recurisve, finalize all the associated SRV_OPEN */
if (RecursiveFinalize)
{
PLIST_ENTRY ListEntry;
for (ListEntry = ThisFcb->SrvOpenList.Flink;
ListEntry != &ThisFcb->SrvOpenList;
ListEntry = ListEntry->Flink)
{
PSRV_OPEN SrvOpen;
SrvOpen = CONTAINING_RECORD(ListEntry, SRV_OPEN, SrvOpenQLinks);
RxFinalizeSrvOpen(SrvOpen, TRUE, ForceFinalize);
}
}
/* If FCB is still in use, that's over */
else
{
if (ThisFcb->OpenCount != 0 || ThisFcb->UncleanCount != 0)
{
ASSERT(ReferenceCount > 0);
return FALSE;
}
}
ASSERT(ReferenceCount >= 1);
/* If FCB is still referenced, that's over - unless you force it and want to BSOD somewhere */
if (ReferenceCount != 1 && !ForceFinalize)
{
return FALSE;
}
ASSERT(ForceFinalize || ((ThisFcb->OpenCount == 0) && (ThisFcb->UncleanCount == 0)));
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
DPRINT("Finalizing FCB open: %d (%d)\n", ThisFcb->OpenCount, ForceFinalize);
/* If finalization was not already initiated, go ahead */
if (!ThisFcb->UpperFinalizationDone)
{
/* Free any FCB_LOCK */
if (NodeType(ThisFcb) == RDBSS_NTC_STORAGE_TYPE_FILE)
{
FsRtlUninitializeFileLock(&ThisFcb->Specific.Fcb.FileLock);
while (ThisFcb->BufferedLocks.List != NULL)
{
PFCB_LOCK Entry;
Entry = ThisFcb->BufferedLocks.List;
ThisFcb->BufferedLocks.List = Entry->Next;
RxFreePool(Entry);
}
}
/* If not orphaned, it still has a NET_ROOT and potentially is still in a table */
if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_ORPHANED))
{
PNET_ROOT NetRoot;
NetRoot = (PNET_ROOT)ThisFcb->pNetRoot;
ASSERT(RxIsFcbTableLockExclusive(&NetRoot->FcbTable));
/* So, remove it */
if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_NAME_ALREADY_REMOVED))
{
RxFcbTableRemoveFcb(&NetRoot->FcbTable, ThisFcb);
}
}
ThisFcb->UpperFinalizationDone = TRUE;
}
ASSERT(ReferenceCount >= 1);
/* Even if forced, don't allow broken free */
if (ReferenceCount != 1)
{
return FALSE;
}
/* Now, release everything */
if (ThisFcb->pBufferingStateChangeCompletedEvent != NULL)
{
RxFreePool(ThisFcb->pBufferingStateChangeCompletedEvent);
}
if (ThisFcb->MRxDispatch != NULL)
{
ThisFcb->MRxDispatch->MRxDeallocateForFcb(RX_GET_MRX_FCB(ThisFcb));
}
ExDeleteResourceLite(ThisFcb->BufferedLocks.Resource);
ExDeleteResourceLite(ThisFcb->Header.Resource);
ExDeleteResourceLite(ThisFcb->Header.PagingIoResource);
InterlockedDecrement((volatile long *)&ThisFcb->pNetRoot->NumberOfFcbs);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
RxDereferenceVNetRoot(ThisFcb->VNetRoot, LHS_LockNotHeld);
ASSERT(IsListEmpty(&ThisFcb->FcbTableEntry.HashLinks));
ASSERT(!ThisFcb->fMiniInited);
/* And free the object */
RxFreeFcbObject(ThisFcb);
return TRUE;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
BOOLEAN
RxFinalizeNetFobx(
_Out_ PFOBX ThisFobx,
_In_ BOOLEAN RecursiveFinalize,
_In_ BOOLEAN ForceFinalize)
{
PFCB Fcb;
PSRV_OPEN SrvOpen;
PAGED_CODE();
ASSERT(NodeType(ThisFobx) == RDBSS_NTC_FOBX);
/* Only finalize if forced or if there's no ref left */
if (ThisFobx->NodeReferenceCount != 0 &&
!ForceFinalize)
{
return FALSE;
}
DPRINT("Finalize Fobx: %p (with %d ref), forced: %d\n", ThisFobx, ThisFobx->NodeReferenceCount, ForceFinalize);
SrvOpen = ThisFobx->SrvOpen;
Fcb = SrvOpen->Fcb;
/* If it wasn't finalized yet, do it */
if (!ThisFobx->UpperFinalizationDone)
{
ASSERT(NodeType(SrvOpen->Fcb) != RDBSS_NTC_OPENTARGETDIR_FCB);
ASSERT(RxIsFcbAcquiredExclusive(SrvOpen->Fcb));
/* Remove it from the SRV_OPEN */
RemoveEntryList(&ThisFobx->FobxQLinks);
/* If we were used to browse a directory, free the query buffer */
if (BooleanFlagOn(ThisFobx->Flags, FOBX_FLAG_FREE_UNICODE))
{
RxFreePoolWithTag(ThisFobx->UnicodeQueryTemplate.Buffer, RX_DIRCTL_POOLTAG);
}
/* Notify the mini-rdr */
if (Fcb->MRxDispatch != NULL && Fcb->MRxDispatch->MRxDeallocateForFobx != NULL)
{
Fcb->MRxDispatch->MRxDeallocateForFobx((PMRX_FOBX)ThisFobx);
}
/* If the SRV_OPEN wasn't closed yet, do it */
if (!BooleanFlagOn(ThisFobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED))
{
NTSTATUS Status;
Status = RxCloseAssociatedSrvOpen(ThisFobx, FALSE);
DPRINT("Closing SRV_OPEN %p for %p: %x\n", SrvOpen, ThisFobx, Status);
}
/* Finalization done */
ThisFobx->UpperFinalizationDone = TRUE;
}
/* If we're still referenced, don't go any further! */
if (ThisFobx->NodeReferenceCount != 0)
{
return FALSE;
}
/* At that point, everything should be closed */
ASSERT(IsListEmpty(&ThisFobx->ClosePendingList));
/* Was the FOBX allocated with another object?
* If so, mark the buffer free in said object
*/
if (ThisFobx == Fcb->InternalFobx)
{
ClearFlag(Fcb->FcbState, FCB_STATE_FOBX_USED);
}
else if (ThisFobx == SrvOpen->InternalFobx)
{
ClearFlag(SrvOpen->Flags, SRVOPEN_FLAG_FOBX_USED);
}
ThisFobx->pSrvOpen = NULL;
/* A FOBX less */
InterlockedDecrement((volatile long *)&SrvOpen->pVNetRoot->NumberOfFobxs);
RxDereferenceSrvOpen(SrvOpen, LHS_ExclusiveLockHeld);
/* If it wasn't allocated with another object, free the FOBX */
if (!BooleanFlagOn(ThisFobx->Flags, FOBX_FLAG_ENCLOSED_ALLOCATED))
{
RxFreeFcbObject(ThisFobx);
}
return TRUE;
}
/*
* @implemented
*/
BOOLEAN
RxFinalizeNetRoot(
OUT PNET_ROOT ThisNetRoot,
IN BOOLEAN RecursiveFinalize,
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
IN BOOLEAN ForceFinalize)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PSRV_CALL SrvCall;
PRX_FCB_TABLE FcbTable;
PRX_PREFIX_TABLE PrefixTable;
PAGED_CODE();
ASSERT(NodeType(ThisNetRoot) == RDBSS_NTC_NETROOT);
PrefixTable = ThisNetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
/* If sme finalization is already ongoing, leave */
if (BooleanFlagOn(ThisNetRoot->Flags, NETROOT_FLAG_FINALIZATION_IN_PROGRESS))
{
return FALSE;
}
/* Mark we're finalizing */
SetFlag(ThisNetRoot->Flags, NETROOT_FLAG_FINALIZATION_IN_PROGRESS);
FcbTable = &ThisNetRoot->FcbTable;
/* Did caller asked us to finalize any associated FCB? */
if (RecursiveFinalize)
{
USHORT Bucket;
/* Browse all the FCBs in our FCB table */
RxAcquireFcbTableLockExclusive(FcbTable, TRUE);
for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
{
PLIST_ENTRY HashBucket, ListEntry;
HashBucket = &FcbTable->HashBuckets[Bucket];
ListEntry = HashBucket->Flink;
while (ListEntry != HashBucket)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PFCB Fcb;
Fcb = CONTAINING_RECORD(ListEntry, FCB, FcbTableEntry.HashLinks);
ASSERT(NodeTypeIsFcb(Fcb));
ListEntry = ListEntry->Flink;
/* If the FCB isn't orphaned, then, it's time to purge it */
if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_ORPHANED))
{
NTSTATUS Status;
Status = RxAcquireExclusiveFcb(NULL, Fcb);
ASSERT(Status == STATUS_SUCCESS);
RxPurgeFcb(Fcb);
}
}
}
RxReleaseFcbTableLock(FcbTable);
}
/* Only finalize if forced or if there's a single ref left */
if (ThisNetRoot->NodeReferenceCount != 1 && !ForceFinalize)
{
return FALSE;
}
DPRINT("Finalizing NetRoot %p for %wZ\n", ThisNetRoot, &ThisNetRoot->PrefixEntry.Prefix);
/* If we're still referenced, don't go any further! */
if (ThisNetRoot->NodeReferenceCount != 1)
{
return FALSE;
}
/* Finalize the FCB table (and make sure it's empty!) */
RxFinalizeFcbTable(FcbTable);
/* If name wasn't remove already, do it now */
if (!BooleanFlagOn(ThisNetRoot->Flags, NETROOT_FLAG_NAME_ALREADY_REMOVED))
{
RxRemovePrefixTableEntry(PrefixTable, &ThisNetRoot->PrefixEntry);
}
/* Delete the object */
SrvCall = (PSRV_CALL)ThisNetRoot->pSrvCall;
RxFreeObject(ThisNetRoot);
/* And dereference the associated SRV_CALL */
if (SrvCall != NULL)
{
RxDereferenceSrvCall(SrvCall, LHS_ExclusiveLockHeld);
}
return TRUE;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
BOOLEAN
RxFinalizeSrvCall(
OUT PSRV_CALL ThisSrvCall,
IN BOOLEAN RecursiveFinalize,
IN BOOLEAN ForceFinalize)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PRX_PREFIX_TABLE PrefixTable;
PAGED_CODE();
ASSERT(NodeType(ThisSrvCall) == RDBSS_NTC_SRVCALL);
PrefixTable = ThisSrvCall->RxDeviceObject->pRxNetNameTable;
ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
/* Only finalize if forced or if there's a single ref left */
if (ThisSrvCall->NodeReferenceCount != 1 &&
!ForceFinalize)
{
return FALSE;
}
DPRINT("Finalizing SrvCall %p for %wZ\n", ThisSrvCall, &ThisSrvCall->PrefixEntry.Prefix);
/* If it wasn't finalized yet, do it */
if (!ThisSrvCall->UpperFinalizationDone)
{
BOOLEAN WillFree;
/* Remove ourselves from prefix table */
RxRemovePrefixTableEntry(PrefixTable, &ThisSrvCall->PrefixEntry);
/* Remember our third arg, in case we get queued for later execution */
if (ForceFinalize)
{
SetFlag(ThisSrvCall->Flags, SRVCALL_FLAG_FORCE_FINALIZED);
}
/* And done */
ThisSrvCall->UpperFinalizationDone = TRUE;
/* Would defered execution free the object? */
WillFree = (ThisSrvCall->NodeReferenceCount == 1);
/* If we have a device object */
if (ThisSrvCall->RxDeviceObject != NULL)
{
NTSTATUS Status;
/* If we're not executing in the RDBSS thread, queue for execution within the thread */
if (RxGetRDBSSProcess() != IoGetCurrentProcess())
{
/* Extra ref, as usual */
InterlockedIncrement((volatile long *)&ThisSrvCall->NodeReferenceCount);
/* And dispatch */
RxDispatchToWorkerThread(ThisSrvCall->RxDeviceObject, DelayedWorkQueue, RxpDestroySrvCall, ThisSrvCall);
/* Return to the caller, in advance, whether we're freeing the object or not */
return WillFree;
}
/* If in the right thread already, call the mini-rdr */
MINIRDR_CALL_THROUGH(Status, ThisSrvCall->RxDeviceObject->Dispatch,
MRxFinalizeSrvCall, ((PMRX_SRV_CALL)ThisSrvCall, ForceFinalize));
(void)Status;
}
}
/* If we're still referenced, don't go any further! */
if (ThisSrvCall->NodeReferenceCount != 1)
{
return FALSE;
}
/* Don't leak */
if (ThisSrvCall->pDomainName != NULL)
{
RxFreePool(ThisSrvCall->pDomainName);
}
/* And free! */
RxTearDownBufferingManager(ThisSrvCall);
RxFreeObject(ThisSrvCall);
return TRUE;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
BOOLEAN
RxFinalizeSrvOpen(
OUT PSRV_OPEN ThisSrvOpen,
IN BOOLEAN RecursiveFinalize,
IN BOOLEAN ForceFinalize)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PFCB Fcb;
PAGED_CODE();
/* We have to have a SRV_OPEN */
ASSERT(NodeType(ThisSrvOpen) == RDBSS_NTC_SRVOPEN);
/* If that's a recursive finalization, finalize any related FOBX */
if (RecursiveFinalize)
{
PLIST_ENTRY ListEntry;
ListEntry = ThisSrvOpen->FobxList.Flink;
while (ListEntry != &ThisSrvOpen->FobxList)
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
{
PFOBX Fobx;
Fobx = CONTAINING_RECORD(ListEntry, FOBX, FobxQLinks);
ListEntry = ListEntry->Flink;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
RxFinalizeNetFobx(Fobx, TRUE, ForceFinalize);
}
}
/* If we have still references, don't finalize unless forced */
if (ThisSrvOpen->NodeReferenceCount != 0 &&
!ForceFinalize)
{
return FALSE;
}
DPRINT("Finalize SRV_OPEN: %p (with %d ref), forced: %d\n", ThisSrvOpen, ThisSrvOpen->NodeReferenceCount, ForceFinalize);
/* Only finalize if closed, or if it wasn't already done and SRV_OPEN is in a bad shape */
Fcb = (PFCB)ThisSrvOpen->pFcb;
if ((!ThisSrvOpen->UpperFinalizationDone && ThisSrvOpen->Condition != Condition_Good) ||
BooleanFlagOn(ThisSrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
{
PV_NET_ROOT VNetRoot;
/* Associated FCB can't be fake one */
ASSERT(NodeType(Fcb) != RDBSS_NTC_OPENTARGETDIR_FCB);
ASSERT(RxIsFcbAcquiredExclusive (Fcb));
/* Purge any pending operation */
RxPurgeChangeBufferingStateRequestsForSrvOpen(ThisSrvOpen);
/* If the FCB wasn't orphaned, inform the mini-rdr about close */
if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_ORPHANED))
{
NTSTATUS Status;
MINIRDR_CALL_THROUGH(Status, Fcb->MRxDispatch, MRxForceClosed, ((PMRX_SRV_OPEN)ThisSrvOpen));
(void)Status;
}
/* Remove ourselves from the FCB */
RemoveEntryList(&ThisSrvOpen->SrvOpenQLinks);
InitializeListHead(&ThisSrvOpen->SrvOpenQLinks);
++Fcb->SrvOpenListVersion;
/* If we have a V_NET_ROOT, dereference it */
VNetRoot = (PV_NET_ROOT)ThisSrvOpen->pVNetRoot;
if (VNetRoot != NULL)
{
InterlockedDecrement((volatile long *)&VNetRoot->pNetRoot->NumberOfSrvOpens);
RxDereferenceVNetRoot(VNetRoot, LHS_LockNotHeld);
ThisSrvOpen->pVNetRoot = NULL;
}
/* Finalization done */
ThisSrvOpen->UpperFinalizationDone = TRUE;
}
/* Don't free memory if still referenced */
if (ThisSrvOpen->NodeReferenceCount != 0)
{
return FALSE;
}
/* No key association left */
ASSERT(IsListEmpty(&ThisSrvOpen->SrvOpenKeyList));
/* If we're still in some FCB, remove us */
if (!IsListEmpty(&ThisSrvOpen->SrvOpenQLinks))
{
RemoveEntryList(&ThisSrvOpen->SrvOpenQLinks);
}
/* If enclosed allocation, mark the memory zone free */
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
if (BooleanFlagOn(ThisSrvOpen->Flags, SRVOPEN_FLAG_ENCLOSED_ALLOCATED))
{
ClearFlag(Fcb->FcbState, FCB_STATE_SRVOPEN_USED);
}
/* Otherwise, free the memory */
else
{
RxFreeFcbObject(ThisSrvOpen);
}
RxDereferenceNetFcb(Fcb);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
return TRUE;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
BOOLEAN
RxFinalizeVNetRoot(
OUT PV_NET_ROOT ThisVNetRoot,
IN BOOLEAN RecursiveFinalize,
IN BOOLEAN ForceFinalize)
{
PNET_ROOT NetRoot;
PRX_PREFIX_TABLE PrefixTable;
PAGED_CODE();
ASSERT(NodeType(ThisVNetRoot) == RDBSS_NTC_V_NETROOT);
PrefixTable = ThisVNetRoot->pNetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
/* Only finalize if forced or if there's a single ref left */
if (ThisVNetRoot->NodeReferenceCount != 1 &&
!ForceFinalize)
{
return FALSE;
}
DPRINT("Finalizing VNetRoot %p for %wZ\n", ThisVNetRoot, &ThisVNetRoot->PrefixEntry.Prefix);
NetRoot = (PNET_ROOT)ThisVNetRoot->pNetRoot;
/* If it wasn't finalized yet, do it */
if (!ThisVNetRoot->UpperFinalizationDone)
{
ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
/* Reference the NetRoot so that it doesn't disappear */
RxReferenceNetRoot(NetRoot);
RxOrphanSrvOpens(ThisVNetRoot);
/* Remove us from the available VNetRoot for NetRoot */
RxRemoveVirtualNetRootFromNetRoot(NetRoot, ThisVNetRoot);
/* Remove extra ref */
RxDereferenceNetRoot(NetRoot, LHS_ExclusiveLockHeld);
/* Remove ourselves from prefix table */
RxRemovePrefixTableEntry(PrefixTable, &ThisVNetRoot->PrefixEntry);
/* Finalization done */
ThisVNetRoot->UpperFinalizationDone = TRUE;
}
/* If we're still referenced, don't go any further! */
if (ThisVNetRoot->NodeReferenceCount != 1)
{
return FALSE;
}
/* If there's an associated device, notify mini-rdr */
if (NetRoot->pSrvCall->RxDeviceObject != NULL)
{
NTSTATUS Status;
MINIRDR_CALL_THROUGH(Status, NetRoot->pSrvCall->RxDeviceObject->Dispatch,
MRxFinalizeVNetRoot, ((PMRX_V_NET_ROOT)ThisVNetRoot, FALSE));
(void)Status;
}
/* Free parameters */
RxUninitializeVNetRootParameters(ThisVNetRoot->pUserName, ThisVNetRoot->pUserDomainName,
ThisVNetRoot->pPassword, &ThisVNetRoot->Flags);
/* Dereference our NetRoot, we won't reference it anymore */
RxDereferenceNetRoot(NetRoot, LHS_ExclusiveLockHeld);
/* And free the object! */
RxFreePoolWithTag(ThisVNetRoot, RX_V_NETROOT_POOLTAG);
return TRUE;
}
NTSTATUS
RxFindOrConstructVirtualNetRoot(
IN PRX_CONTEXT RxContext,
IN PUNICODE_STRING CanonicalName,
IN NET_ROOT_TYPE NetRootType,
IN PUNICODE_STRING RemainingName)
{
ULONG Flags;
NTSTATUS Status;
PVOID Container;
BOOLEAN Construct;
PV_NET_ROOT VNetRoot;
RX_CONNECTION_ID ConnectionID;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
LOCK_HOLDING_STATE LockHoldingState;
PAGED_CODE();
RxDeviceObject = RxContext->RxDeviceObject;
ASSERT(RxDeviceObject->Dispatch != NULL);
ASSERT(NodeType(RxDeviceObject->Dispatch) == RDBSS_NTC_MINIRDR_DISPATCH);
/* Ask the mini-rdr for connection ID */
ConnectionID.SessionID = 0;
if (RxDeviceObject->Dispatch->MRxGetConnectionId != NULL)
{
Status = RxDeviceObject->Dispatch->MRxGetConnectionId(RxContext, &ConnectionID);
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
{
/* mini-rdr is expected not to fail - unless it's not implemented */
DPRINT1("Failed to initialize connection ID\n");
ASSERT(FALSE);
}
}
RxContext->Create.NetNamePrefixEntry = NULL;
Status = STATUS_MORE_PROCESSING_REQUIRED;
RxAcquirePrefixTableLockShared(RxDeviceObject->pRxNetNameTable, TRUE);
LockHoldingState = LHS_SharedLockHeld;
Construct = TRUE;
Flags = 0;
/* We will try twice to find a matching VNetRoot: shared locked and then exlusively locked */
while (TRUE)
{
PNET_ROOT NetRoot;
PV_NET_ROOT SavedVNetRoot;
/* Look in prefix table */
Container = RxPrefixTableLookupName(RxDeviceObject->pRxNetNameTable, CanonicalName, RemainingName, &ConnectionID);
if (Container != NULL)
{
/* If that's not a VNetRoot, that's a SrvCall, not interesting, loop again */
if (NodeType(Container) != RDBSS_NTC_V_NETROOT)
{
ASSERT(NodeType(Container) == RDBSS_NTC_SRVCALL);
RxDereferenceSrvCall(Container, LockHoldingState);
}
else
{
VNetRoot = Container;
NetRoot = VNetRoot->NetRoot;
/* If the matching VNetRoot isn't in a good shape, there's something wrong - fail */
if ((NetRoot->Condition != Condition_InTransition && NetRoot->Condition != Condition_Good) ||
NetRoot->SrvCall->RxDeviceObject != RxContext->RxDeviceObject)
{
Status = STATUS_BAD_NETWORK_PATH;
SavedVNetRoot = NULL;
}
else
{
LUID LogonId;
ULONG SessionId;
PUNICODE_STRING UserName, UserDomain, Password;
/* We can reuse if we use same credentials */
Status = RxInitializeVNetRootParameters(RxContext, &LogonId,
&SessionId, &UserName,
&UserDomain, &Password,
&Flags);
if (NT_SUCCESS(Status))
{
SavedVNetRoot = VNetRoot;
Status = RxCheckVNetRootCredentials(RxContext, VNetRoot,
&LogonId, UserName,
UserDomain, Password,
Flags);
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
{
PLIST_ENTRY ListEntry;
for (ListEntry = NetRoot->VirtualNetRoots.Flink;
ListEntry != &NetRoot->VirtualNetRoots;
ListEntry = ListEntry->Flink)
{
SavedVNetRoot = CONTAINING_RECORD(ListEntry, V_NET_ROOT, NetRootListEntry);
Status = RxCheckVNetRootCredentials(RxContext, SavedVNetRoot,
&LogonId, UserName,
UserDomain, Password,
Flags);
if (Status != STATUS_MORE_PROCESSING_REQUIRED)
{
break;
}
}
if (ListEntry == &NetRoot->VirtualNetRoots)
{
SavedVNetRoot = NULL;
}
}
if (!NT_SUCCESS(Status))
{
SavedVNetRoot = NULL;
}
RxUninitializeVNetRootParameters(UserName, UserDomain, Password, &Flags);
}
}
/* We'll fail, if we had referenced a VNetRoot, dereference it */
if (Status != STATUS_MORE_PROCESSING_REQUIRED && !NT_SUCCESS(Status))
{
if (SavedVNetRoot == NULL)
{
RxDereferenceVNetRoot(VNetRoot, LockHoldingState);
}
}
/* Reference VNetRoot we'll keep, and dereference current */
else if (SavedVNetRoot != VNetRoot)
{
RxDereferenceVNetRoot(VNetRoot, LockHoldingState);
if (SavedVNetRoot != NULL)
{
RxReferenceVNetRoot(SavedVNetRoot);
}
}
}
/* We may have found something, or we fail hard, so don't attempt to create a VNetRoot */
if (Status != STATUS_MORE_PROCESSING_REQUIRED)
{
Construct = FALSE;
break;
}
}
/* If we're locked exclusive, we won't loop again, it was the second pass */
if (LockHoldingState != LHS_SharedLockHeld)
{
break;
}
/* Otherwise, prepare for second pass, exclusive, making sure we can acquire without delay */
if (RxAcquirePrefixTableLockExclusive(RxDeviceObject->pRxNetNameTable, FALSE))
{
RxReleasePrefixTableLock(RxDeviceObject->pRxNetNameTable);
LockHoldingState = LHS_ExclusiveLockHeld;
break;
}
RxReleasePrefixTableLock(RxDeviceObject->pRxNetNameTable);
RxAcquirePrefixTableLockExclusive(RxDeviceObject->pRxNetNameTable, TRUE);
LockHoldingState = LHS_ExclusiveLockHeld;
}
/* We didn't fail, and didn't find any VNetRoot, construct one */
if (Construct)
{
ASSERT(LockHoldingState == LHS_ExclusiveLockHeld);
Status = RxConstructVirtualNetRoot(RxContext, CanonicalName, NetRootType, &VNetRoot, &LockHoldingState, &ConnectionID);
ASSERT(Status != STATUS_SUCCESS || LockHoldingState != LHS_LockNotHeld);
if (Status == STATUS_SUCCESS)
{
DPRINT("CanonicalName: %wZ (%d)\n", CanonicalName, CanonicalName->Length);
DPRINT("VNetRoot: %wZ (%d)\n", &VNetRoot->PrefixEntry.Prefix, VNetRoot->PrefixEntry.Prefix.Length);
ASSERT(CanonicalName->Length >= VNetRoot->PrefixEntry.Prefix.Length);
RemainingName->Buffer = Add2Ptr(CanonicalName->Buffer, VNetRoot->PrefixEntry.Prefix.Length);
RemainingName->Length = CanonicalName->Length - VNetRoot->PrefixEntry.Prefix.Length;
RemainingName->MaximumLength = RemainingName->Length;
if (BooleanFlagOn(Flags, VNETROOT_FLAG_CSCAGENT_INSTANCE))
{
DPRINT("CSC instance, VNetRoot: %p\n", VNetRoot);
}
VNetRoot->Flags |= Flags;
}
}
/* Release the prefix table - caller expects it to be released */
if (LockHoldingState != LHS_LockNotHeld)
{
RxReleasePrefixTableLock(RxDeviceObject->pRxNetNameTable);
}
/* If we failed creating, quit */
if (Status != STATUS_SUCCESS)
{
DPRINT1("RxFindOrConstructVirtualNetRoot() = Status: %x\n", Status);
return Status;
}
/* Otherwise, wait until the VNetRoot is stable */
DPRINT("Waiting for stable condition for: %p\n", VNetRoot);
RxWaitForStableVNetRoot(VNetRoot, RxContext);
/* It's all good, update the RX_CONTEXT with all our structs */
if (VNetRoot->Condition == Condition_Good)
{
PNET_ROOT NetRoot;
NetRoot = VNetRoot->NetRoot;
RxContext->Create.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
RxContext->Create.pNetRoot = (PMRX_NET_ROOT)NetRoot;
RxContext->Create.pSrvCall = (PMRX_SRV_CALL)NetRoot->SrvCall;
}
else
{
RxDereferenceVNetRoot(VNetRoot, LHS_LockNotHeld);
RxContext->Create.pVNetRoot = NULL;
Status = STATUS_BAD_NETWORK_PATH;
}
return Status;
}
/*
* @implemented
*/
NTSTATUS
RxFindOrCreateConnections(
_In_ PRX_CONTEXT RxContext,
_In_ PUNICODE_STRING CanonicalName,
_In_ NET_ROOT_TYPE NetRootType,
_Out_ PUNICODE_STRING LocalNetRootName,
_Out_ PUNICODE_STRING FilePathName,
_Inout_ PLOCK_HOLDING_STATE LockState,
_In_ PRX_CONNECTION_ID RxConnectionId)
{
PVOID Container;
PSRV_CALL SrvCall;
PNET_ROOT NetRoot;
PV_NET_ROOT VNetRoot;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PRX_PREFIX_TABLE PrefixTable;
UNICODE_STRING RemainingName, NetRootName;
PAGED_CODE();
DPRINT("RxFindOrCreateConnections(%p, %wZ, %x, %p, %p, %p, %p)\n",
RxContext, CanonicalName, NetRootType, LocalNetRootName,
FilePathName, LockState, RxConnectionId);
*FilePathName = *CanonicalName;
LocalNetRootName->Length = 0;
LocalNetRootName->MaximumLength = 0;
LocalNetRootName->Buffer = CanonicalName->Buffer;
/* UNC path, split it */
if (FilePathName->Buffer[1] == ';')
{
BOOLEAN Slash;
USHORT i, Length;
Slash = FALSE;
for (i = 2; i < FilePathName->Length / sizeof(WCHAR); ++i)
{
if (FilePathName->Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
{
Slash = TRUE;
break;
}
}
if (!Slash)
{
return STATUS_OBJECT_NAME_INVALID;
}
FilePathName->Buffer = &FilePathName->Buffer[i];
Length = (USHORT)((ULONG_PTR)FilePathName->Buffer - (ULONG_PTR)LocalNetRootName->Buffer);
LocalNetRootName->Length = Length;
LocalNetRootName->MaximumLength = Length;
FilePathName->Length -= Length;
DPRINT("CanonicalName: %wZ\n", CanonicalName);
DPRINT(" -> FilePathName: %wZ\n", FilePathName);
DPRINT(" -> LocalNetRootName: %wZ\n", LocalNetRootName);
}
Container = NULL;
PrefixTable = RxContext->RxDeviceObject->pRxNetNameTable;
_SEH2_TRY
{
RetryLookup:
ASSERT(*LockState != LHS_LockNotHeld);
/* If previous lookup left something, dereference it */
if (Container != NULL)
{
switch (NodeType(Container))
{
case RDBSS_NTC_SRVCALL:
RxDereferenceSrvCall(Container, *LockState);
break;
case RDBSS_NTC_NETROOT:
RxDereferenceNetRoot(Container, *LockState);
break;
case RDBSS_NTC_V_NETROOT:
RxDereferenceVNetRoot(Container, *LockState);
break;
default:
/* Should never happen */
ASSERT(FALSE);
break;
}
}
/* Look for our NetRoot in prefix table */
Container = RxPrefixTableLookupName(PrefixTable, FilePathName, &RemainingName, RxConnectionId);
DPRINT("Container %p for path %wZ\n", Container, FilePathName);
while (TRUE)
{
UNICODE_STRING SrvCallName;
SrvCall = NULL;
NetRoot = NULL;
VNetRoot = NULL;
/* Assume we didn't succeed */
RxContext->Create.pVNetRoot = NULL;
RxContext->Create.pNetRoot = NULL;
RxContext->Create.pSrvCall = NULL;
RxContext->Create.Type = NetRootType;
/* If we found something */
if (Container != NULL)
{
/* A VNetRoot */
if (NodeType(Container) == RDBSS_NTC_V_NETROOT)
{
VNetRoot = Container;
/* Use its NetRoot */
NetRoot = VNetRoot->NetRoot;
/* If it's not stable, wait for it to be stable */
if (NetRoot->Condition == Condition_InTransition)
{
RxReleasePrefixTableLock(PrefixTable);
DPRINT("Waiting for stable condition for: %p\n", NetRoot);
RxWaitForStableNetRoot(NetRoot, RxContext);
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
*LockState = LHS_ExclusiveLockHeld;
/* Now that's it's ok, retry lookup to find what we want */
if (NetRoot->Condition == Condition_Good)
{
goto RetryLookup;
}
}
/* Is the associated netroot good? */
if (NetRoot->Condition == Condition_Good)
{
SrvCall = (PSRV_CALL)NetRoot->pSrvCall;
/* If it is, and SrvCall as well, then, we have our active connection */
if (SrvCall->Condition == Condition_Good &&
SrvCall->RxDeviceObject == RxContext->RxDeviceObject)
{
RxContext->Create.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
RxContext->Create.pNetRoot = (PMRX_NET_ROOT)NetRoot;
RxContext->Create.pSrvCall = (PMRX_SRV_CALL)SrvCall;
Status = STATUS_CONNECTION_ACTIVE;
_SEH2_LEAVE;
}
}
/* If VNetRoot was well constructed, it means the connection is active */
if (VNetRoot->ConstructionStatus == STATUS_SUCCESS)
{
Status = STATUS_CONNECTION_ACTIVE;
}
else
{
Status = VNetRoot->ConstructionStatus;
}
RxDereferenceVNetRoot(VNetRoot, *LockState);
_SEH2_LEAVE;
}
/* Can only be a SrvCall */
else
{
ASSERT(NodeType(Container) == RDBSS_NTC_SRVCALL);
SrvCall = Container;
/* Wait for the SRV_CALL to be stable */
if (SrvCall->Condition == Condition_InTransition)
{
RxReleasePrefixTableLock(PrefixTable);
DPRINT("Waiting for stable condition for: %p\n", SrvCall);
RxWaitForStableSrvCall(SrvCall, RxContext);
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
*LockState = LHS_ExclusiveLockHeld;
/* It went good, loop again to find what we look for */
if (SrvCall->Condition == Condition_Good)
{
goto RetryLookup;
}
}
/* If it's not good... */
if (SrvCall->Condition != Condition_Good)
{
/* But SRV_CALL was well constructed, assume a connection was active */
if (SrvCall->Status == STATUS_SUCCESS)
{
Status = STATUS_CONNECTION_ACTIVE;
}
else
{
Status = SrvCall->Status;
}
RxDereferenceSrvCall(SrvCall, *LockState);
_SEH2_LEAVE;
}
}
}
/* If we found a SRV_CALL not matching our DO, quit */
if (SrvCall != NULL && SrvCall->Condition == Condition_Good &&
SrvCall->RxDeviceObject != RxContext->RxDeviceObject)
{
RxDereferenceSrvCall(SrvCall, *LockState);
Status = STATUS_BAD_NETWORK_NAME;
_SEH2_LEAVE;
}
/* Now, we want exclusive lock */
if (*LockState == LHS_SharedLockHeld)
{
if (!RxAcquirePrefixTableLockExclusive(PrefixTable, FALSE))
{
RxReleasePrefixTableLock(PrefixTable);
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
*LockState = LHS_ExclusiveLockHeld;
goto RetryLookup;
}
RxReleasePrefixTableLock(PrefixTable);
*LockState = LHS_ExclusiveLockHeld;
}
ASSERT(*LockState == LHS_ExclusiveLockHeld);
/* If we reach that point, we found something, no need to create something */
if (Container != NULL)
{
break;
}
/* Get the name for the SRV_CALL */
RxExtractServerName(FilePathName, &SrvCallName, NULL);
DPRINT(" -> SrvCallName: %wZ\n", &SrvCallName);
/* And create the SRV_CALL */
SrvCall = RxCreateSrvCall(RxContext, &SrvCallName, NULL, RxConnectionId);
if (SrvCall == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
_SEH2_LEAVE;
}
/* Reset RX_CONTEXT, so far, connection creation isn't a success */
RxReferenceSrvCall(SrvCall);
RxContext->Create.pVNetRoot = NULL;
RxContext->Create.pNetRoot = NULL;
RxContext->Create.pSrvCall = NULL;
RxContext->Create.Type = NetRootType;
Container = SrvCall;
/* Construct SRV_CALL, ie, use mini-rdr */
Status = RxConstructSrvCall(RxContext, SrvCall, LockState);
ASSERT(Status != STATUS_SUCCESS || RxIsPrefixTableLockAcquired(PrefixTable));
if (Status != STATUS_SUCCESS)
{
DPRINT1("RxConstructSrvCall() = Status: %x\n", Status);
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
RxDereferenceSrvCall(SrvCall, *LockState);
RxReleasePrefixTableLock(PrefixTable);
_SEH2_LEAVE;
}
/* Loop again to make use of SRV_CALL stable condition wait */
}
/* At that point, we have a stable SRV_CALL (either found or constructed) */
ASSERT((NodeType(SrvCall) == RDBSS_NTC_SRVCALL) && (SrvCall->Condition == Condition_Good));
ASSERT(NetRoot == NULL && VNetRoot == NULL);
ASSERT(SrvCall->RxDeviceObject == RxContext->RxDeviceObject);
/* Call mini-rdr to get NetRoot name */
SrvCall->RxDeviceObject->Dispatch->MRxExtractNetRootName(FilePathName, (PMRX_SRV_CALL)SrvCall, &NetRootName, NULL);
/* And create the NetRoot with that name */
NetRoot = RxCreateNetRoot(SrvCall, &NetRootName, 0, RxConnectionId);
if (NetRoot == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
_SEH2_LEAVE;
}
NetRoot->Type = NetRootType;
RxDereferenceSrvCall(SrvCall, *LockState);
/* Finally, create the associated VNetRoot */
VNetRoot = RxCreateVNetRoot(RxContext, NetRoot, CanonicalName, LocalNetRootName, FilePathName, RxConnectionId);
if (VNetRoot == NULL)
{
RxFinalizeNetRoot(NetRoot, TRUE, TRUE);
Status = STATUS_INSUFFICIENT_RESOURCES;
_SEH2_LEAVE;
}
RxReferenceVNetRoot(VNetRoot);
/* We're get closer! */
NetRoot->Condition = Condition_InTransition;
RxContext->Create.pSrvCall = (PMRX_SRV_CALL)SrvCall;
RxContext->Create.pNetRoot = (PMRX_NET_ROOT)NetRoot;
RxContext->Create.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
/* Construct the NetRoot, involving the mini-rdr now that we have our three control structs */
Status = RxConstructNetRoot(RxContext, SrvCall, NetRoot, VNetRoot, LockState);
if (!NT_SUCCESS(Status))
{
RxTransitionVNetRoot(VNetRoot, Condition_Bad);
DPRINT1("RxConstructNetRoot failed Ctxt: %p, VNet: %p, Status: %lx, Condition: %d\n", RxContext, VNetRoot, Status, VNetRoot->Condition);
RxDereferenceVNetRoot(VNetRoot, *LockState);
RxContext->Create.pNetRoot = NULL;
RxContext->Create.pVNetRoot = NULL;
}
else
{
PIO_STACK_LOCATION Stack;
ASSERT(*LockState == LHS_ExclusiveLockHeld);
Stack = RxContext->CurrentIrpSp;
if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_CREATE_TREE_CONNECTION))
{
RxExclusivePrefixTableLockToShared(PrefixTable);
*LockState = LHS_SharedLockHeld;
}
}
}
_SEH2_FINALLY
{
if (Status != STATUS_SUCCESS && Status != STATUS_CONNECTION_ACTIVE)
{
if (*LockState != LHS_LockNotHeld)
{
RxReleasePrefixTableLock(PrefixTable);
*LockState = LHS_LockNotHeld;
}
}
}
_SEH2_END;
DPRINT("RxFindOrCreateConnections() = Status: %x\n", Status);
return Status;
}
/*
* @implemented
*/
VOID
NTAPI
RxFinishFcbInitialization(
IN OUT PMRX_FCB Fcb,
IN RX_FILE_TYPE FileType,
IN PFCB_INIT_PACKET InitPacket OPTIONAL)
{
RX_FILE_TYPE OldType;
PAGED_CODE();
DPRINT("RxFinishFcbInitialization(%p, %x, %p)\n", Fcb, FileType, InitPacket);
OldType = NodeType(Fcb);
NodeType(Fcb) = FileType;
/* If mini-rdr already did the job for mailslot attributes, 0 the rest */
if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_TIME_AND_SIZE_ALREADY_SET) && FileType == RDBSS_NTC_MAILSLOT)
{
FILL_IN_FCB((PFCB)Fcb, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
/* Otherwise, if mini-rdr provided us with an init packet, copy its data */
else if (InitPacket != NULL)
{
FILL_IN_FCB((PFCB)Fcb, *InitPacket->pAttributes, *InitPacket->pNumLinks,
InitPacket->pCreationTime->QuadPart, InitPacket->pLastAccessTime->QuadPart,
InitPacket->pLastWriteTime->QuadPart, InitPacket->pLastChangeTime->QuadPart,
InitPacket->pAllocationSize->QuadPart, InitPacket->pFileSize->QuadPart,
InitPacket->pValidDataLength->QuadPart);
}
if (FileType != RDBSS_NTC_STORAGE_TYPE_UNKNOWN &&
FileType != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)
{
/* If our FCB newly points to a file, initiliaze everything related */
if (FileType == RDBSS_NTC_STORAGE_TYPE_FILE)
{
if (OldType != RDBSS_NTC_STORAGE_TYPE_FILE)
{
RxInitializeLowIoPerFcbInfo(&((PFCB)Fcb)->Specific.Fcb.LowIoPerFcbInfo);
FsRtlInitializeFileLock(&((PFCB)Fcb)->Specific.Fcb.FileLock, RxLockOperationCompletion,
RxUnlockOperation);
((PFCB)Fcb)->BufferedLocks.List = NULL;
((PFCB)Fcb)->BufferedLocks.PendingLockOps = 0;
Fcb->Header.IsFastIoPossible = FastIoIsQuestionable;
}
}
/* If not a file, validate type */
else
{
ASSERT(FileType >= RDBSS_NTC_SPOOLFILE && FileType <= RDBSS_NTC_MAILSLOT);
}
}
}
/*
* @implemented
*/
NTSTATUS
RxFinishSrvCallConstruction(
PMRX_SRVCALLDOWN_STRUCTURE Calldown)
{
NTSTATUS Status;
PSRV_CALL SrvCall;
PRX_CONTEXT Context;
RX_BLOCK_CONDITION Condition;
PRX_PREFIX_TABLE PrefixTable;
DPRINT("RxFinishSrvCallConstruction(%p)\n", Calldown);
SrvCall = (PSRV_CALL)Calldown->SrvCall;
Context = Calldown->RxContext;
PrefixTable = Context->RxDeviceObject->pRxNetNameTable;
/* We have a winner, notify him */
if (Calldown->BestFinisher != NULL)
{
DPRINT("Notify the winner: %p (%wZ)\n", Calldown->BestFinisher, &Calldown->BestFinisher->DeviceName);
ASSERT(SrvCall->RxDeviceObject == Calldown->BestFinisher);
MINIRDR_CALL_THROUGH(Status, Calldown->BestFinisher->Dispatch,
MRxSrvCallWinnerNotify,
((PMRX_SRV_CALL)SrvCall, TRUE,
Calldown->CallbackContexts[Calldown->BestFinisherOrdinal].RecommunicateContext));
if (Status != STATUS_SUCCESS)
{
Condition = Condition_Bad;
}
else
{
Condition = Condition_Good;
}
}
/* Otherwise, just fail our SRV_CALL */
else
{
Status = Calldown->CallbackContexts[0].Status;
Condition = Condition_Bad;
}
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
RxTransitionSrvCall(SrvCall, Condition);
RxFreePoolWithTag(Calldown, RX_SRVCALL_POOLTAG);
/* If async, finish it here, otherwise, caller has already finished the stuff */
if (BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
{
DPRINT("Finishing async call\n");
RxReleasePrefixTableLock(PrefixTable);
/* Make sure we weren't cancelled in-between */
if (BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_CANCELLED))
{
Status = STATUS_CANCELLED;
}
/* In case that was a create, context can be reused */
if (Context->MajorFunction == IRP_MJ_CREATE)
{
RxpPrepareCreateContextForReuse(Context);
}
/* If that's a failure, reset everything and return failure */
if (Status != STATUS_SUCCESS)
{
Context->MajorFunction = Context->CurrentIrpSp->MajorFunction;
if (Context->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
if (Context->Info.Buffer != NULL)
{
RxFreePool(Context->Info.Buffer);
Context->Info.Buffer = NULL;
}
}
Context->CurrentIrp->IoStatus.Information = 0;
Context->CurrentIrp->IoStatus.Status = Status;
RxCompleteRequest(Context, Status);
}
/* Otherwise, call resume routine and done! */
else
{
Status = Context->ResumeRoutine(Context);
if (Status != STATUS_PENDING)
{
RxCompleteRequest(Context, Status);
}
DPRINT("Not completing, pending\n");
}
}
RxDereferenceSrvCall(SrvCall, LHS_LockNotHeld);
return Status;
}
/*
* @implemented
*/
VOID
NTAPI
RxFinishSrvCallConstructionDispatcher(
IN PVOID Context)
{
KIRQL OldIrql;
BOOLEAN Direct, KeepLoop;
DPRINT("RxFinishSrvCallConstructionDispatcher(%p)\n", Context);
/* In case of failure of starting dispatcher, context is not set
* We keep track of it to fail associated SRV_CALL
*/
Direct = (Context == NULL);
/* Separated thread, loop forever */
while (TRUE)
{
PLIST_ENTRY ListEntry;
PMRX_SRVCALLDOWN_STRUCTURE Calldown;
/* If there are no SRV_CALL to finalize left, just finish thread */
KeAcquireSpinLock(&RxStrucSupSpinLock, &OldIrql);
if (IsListEmpty(&RxSrvCalldownList))
{
KeepLoop = FALSE;
RxSrvCallConstructionDispatcherActive = FALSE;
}
/* Otherwise, get the SRV_CALL to finish construction */
else
{
ListEntry = RemoveHeadList(&RxSrvCalldownList);
KeepLoop = TRUE;
}
KeReleaseSpinLock(&RxStrucSupSpinLock, OldIrql);
/* Nothing to do */
if (!KeepLoop)
{
break;
}
/* If direct is set, reset the finisher to avoid electing a winner
* and fail SRV_CALL (see upper comment)
*/
Calldown = CONTAINING_RECORD(ListEntry, MRX_SRVCALLDOWN_STRUCTURE, SrvCalldownList);
if (Direct)
{
Calldown->BestFinisher = NULL;
}
/* Finish SRV_CALL construction */
RxFinishSrvCallConstruction(Calldown);
}
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
NTSTATUS
RxFlushFcbInSystemCache(
IN PFCB Fcb,
IN BOOLEAN SynchronizeWithLazyWriter)
{
IO_STATUS_BLOCK IoStatus;
PAGED_CODE();
/* Deal with Cc */
CcFlushCache(&Fcb->NonPaged->SectionObjectPointers, NULL, 0, &IoStatus);
/* If we're asked to sync with LW, do it in case of success */
if (SynchronizeWithLazyWriter && NT_SUCCESS(IoStatus.Status))
{
RxAcquirePagingIoResource((PRX_CONTEXT)NULL, Fcb);
RxReleasePagingIoResource((PRX_CONTEXT)NULL, Fcb);
}
DPRINT("Flushing for FCB %p returns %lx\n", Fcb, IoStatus.Status);
return IoStatus.Status;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxFreeFcbObject(
PVOID Object)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PAGED_CODE();
DPRINT("Freeing %p\n", Object);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* If that's a FOBX/SRV_OPEN, nothing to do, just free it */
if (NodeType(Object) == RDBSS_NTC_FOBX || NodeType(Object) == RDBSS_NTC_SRVOPEN)
{
RxFreePoolWithTag(Object, RX_FCB_POOLTAG);
}
/* If that's a FCB... */
else if (NodeTypeIsFcb(Object))
{
PFCB Fcb;
PRDBSS_DEVICE_OBJECT DeviceObject;
Fcb = (PFCB)Object;
DeviceObject = Fcb->RxDeviceObject;
/* Delete per stream contexts */
FsRtlTeardownPerStreamContexts(&Fcb->Header);
SetFlag(Fcb->Header.Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH);
/* If there was a non-paged FCB allocated, free it */
if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE))
{
RxFreePoolWithTag(Fcb->NonPaged, RX_NONPAGEDFCB_POOLTAG);
}
/* Free the FCB */
RxFreePool(Fcb);
/* Update statistics */
InterlockedDecrement(&RxNumberOfActiveFcbs);
InterlockedDecrement((volatile long *)&DeviceObject->NumberOfActiveFcbs);
}
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
RxFreeObject(
PVOID pObject)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PAGED_CODE();
/* First, perform a few sanity checks if we're dealing with a SRV_CALL or a NET_ROOT */
if (NodeType(pObject) == RDBSS_NTC_SRVCALL)
{
PSRV_CALL SrvCall;
PRDBSS_DEVICE_OBJECT DeviceObject;
SrvCall = (PSRV_CALL)pObject;
DeviceObject = SrvCall->RxDeviceObject;
if (DeviceObject != NULL)
{
if (!BooleanFlagOn(DeviceObject->Dispatch->MRxFlags, RDBSS_MANAGE_SRV_CALL_EXTENSION))
{
ASSERT(SrvCall->Context == NULL);
}
ASSERT(SrvCall->Context2 == NULL);
SrvCall->RxDeviceObject = NULL;
}
}
else if (NodeType(pObject) == RDBSS_NTC_NETROOT)
{
PNET_ROOT NetRoot;
NetRoot = (PNET_ROOT)pObject;
NetRoot->pSrvCall = NULL;
NetRoot->NodeTypeCode = NodeType(pObject) | 0xF000;
}
/* And just free the object */
RxFreePool(pObject);
}
/*
* @implemented
*/
VOID
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
RxGatherRequestsForSrvOpen(
IN OUT PSRV_CALL SrvCall,
IN PSRV_OPEN SrvOpen,
IN OUT PLIST_ENTRY RequestsListHead)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
KIRQL OldIrql;
LIST_ENTRY Discarded, *Entry;
PCHANGE_BUFFERING_STATE_REQUEST Request;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Dispatch any pending operation first */
RxpDispatchChangeBufferingStateRequests(SrvCall, SrvOpen, &Discarded);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Then, get any entry related to our key and SRV_OPEN */
KeAcquireSpinLock(&SrvCall->BufferingManager.SpinLock, &OldIrql);
Entry = SrvCall->BufferingManager.HandlerList.Flink;
while (Entry != &SrvCall->BufferingManager.HandlerList)
{
Request = CONTAINING_RECORD(Entry, CHANGE_BUFFERING_STATE_REQUEST, ListEntry);
Entry = Entry->Flink;
if (Request->SrvOpenKey == SrvOpen->Key && Request->SrvOpen == SrvOpen)
{
RemoveEntryList(&Request->ListEntry);
InsertTailList(RequestsListHead, &Request->ListEntry);
}
}
KeReleaseSpinLock(&SrvCall->BufferingManager.SpinLock, OldIrql);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Perform the same search in the last change list */
Entry = SrvCall->BufferingManager.LastChanceHandlerList.Flink;
while (Entry != &SrvCall->BufferingManager.LastChanceHandlerList)
{
Request = CONTAINING_RECORD(Entry, CHANGE_BUFFERING_STATE_REQUEST, ListEntry);
Entry = Entry->Flink;
if (Request->SrvOpenKey == SrvOpen->Key && Request->SrvOpen == SrvOpen)
{
RemoveEntryList(&Request->ListEntry);
InsertTailList(RequestsListHead, &Request->ListEntry);
}
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Discard the discarded requests */
RxpDiscardChangeBufferingStateRequests(&Discarded);
}
/*
* @implemented
*/
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PRDBSS_DEVICE_OBJECT
RxGetDeviceObjectOfInstance(
PVOID Instance)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
NODE_TYPE_CODE NodeType;
PRDBSS_DEVICE_OBJECT DeviceObject;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PAGED_CODE();
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* We only handle a few object types */
NodeType = NodeType(Instance);
ASSERT((NodeType == RDBSS_NTC_SRVCALL) || (NodeType == RDBSS_NTC_NETROOT) ||
(NodeType == RDBSS_NTC_V_NETROOT) || (NodeType == RDBSS_NTC_SRVOPEN) || (NodeType == RDBSS_NTC_FOBX));
/* Get the device object depending on the object */
switch (NodeType)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
case RDBSS_NTC_FOBX:
{
PFOBX Fobx;
Fobx = (PFOBX)Instance;
DeviceObject = Fobx->RxDeviceObject;
break;
}
case RDBSS_NTC_SRVCALL:
{
PSRV_CALL SrvCall;
SrvCall = (PSRV_CALL)Instance;
DeviceObject = SrvCall->RxDeviceObject;
break;
}
case RDBSS_NTC_NETROOT:
{
PNET_ROOT NetRoot;
NetRoot = (PNET_ROOT)Instance;
DeviceObject = NetRoot->pSrvCall->RxDeviceObject;
break;
}
case RDBSS_NTC_V_NETROOT:
{
PV_NET_ROOT VNetRoot;
VNetRoot = (PV_NET_ROOT)Instance;
DeviceObject = VNetRoot->pNetRoot->pSrvCall->RxDeviceObject;
break;
}
case RDBSS_NTC_SRVOPEN:
{
PSRV_OPEN SrvOpen;
SrvOpen = (PSRV_OPEN)Instance;
DeviceObject = ((PFCB)SrvOpen->pFcb)->RxDeviceObject;
break;
}
default:
DeviceObject = NULL;
break;
}
/* Job done */
return DeviceObject;
}
/*
* @implemented
*/
VOID
RxGetFileSizeWithLock(
IN PFCB Fcb,
OUT PLONGLONG FileSize)
{
PAGED_CODE();
*FileSize = Fcb->Header.FileSize.QuadPart;
}
/*
* @implemented
*/
PEPROCESS
NTAPI
RxGetRDBSSProcess(
VOID)
{
return RxData.OurProcess;
}
/*
* @implemented
*/
NTSTATUS
RxInitializeBufferingManager(
PSRV_CALL SrvCall)
{
KeInitializeSpinLock(&SrvCall->BufferingManager.SpinLock);
InitializeListHead(&SrvCall->BufferingManager.DispatcherList);
InitializeListHead(&SrvCall->BufferingManager.HandlerList);
InitializeListHead(&SrvCall->BufferingManager.LastChanceHandlerList);
SrvCall->BufferingManager.DispatcherActive = FALSE;
SrvCall->BufferingManager.HandlerInactive = FALSE;
SrvCall->BufferingManager.LastChanceHandlerActive = FALSE;
SrvCall->BufferingManager.NumberOfOutstandingOpens = 0;
InitializeListHead(&SrvCall->BufferingManager.SrvOpenLists[0]);
ExInitializeFastMutex(&SrvCall->BufferingManager.Mutex);
return STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
NTAPI
RxInitializeContext(
IN PIRP Irp,
IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
IN ULONG InitialContextFlags,
IN OUT PRX_CONTEXT RxContext)
{
PIO_STACK_LOCATION Stack;
/* Initialize our various fields */
RxContext->NodeTypeCode = RDBSS_NTC_RX_CONTEXT;
RxContext->NodeByteSize = sizeof(RX_CONTEXT);
RxContext->ReferenceCount = 1;
RxContext->SerialNumber = InterlockedExchangeAdd((volatile LONG *)&RxContextSerialNumberCounter, 1);
RxContext->RxDeviceObject = RxDeviceObject;
KeInitializeEvent(&RxContext->SyncEvent, SynchronizationEvent, FALSE);
RxInitializeScavengerEntry(&RxContext->ScavengerEntry);
InitializeListHead(&RxContext->BlockedOperations);
RxContext->MRxCancelRoutine = NULL;
RxContext->ResumeRoutine = NULL;
RxContext->Flags |= InitialContextFlags;
RxContext->CurrentIrp = Irp;
RxContext->LastExecutionThread = PsGetCurrentThread();
RxContext->OriginalThread = RxContext->LastExecutionThread;
/* If've got no IRP, mark RX_CONTEXT */
if (Irp == NULL)
{
RxContext->CurrentIrpSp = NULL;
RxContext->MajorFunction = IRP_MJ_MAXIMUM_FUNCTION + 1;
RxContext->MinorFunction = 0;
}
else
{
/* Otherwise, first determine whether we are performing async operation */
Stack = IoGetCurrentIrpStackLocation(Irp);
if (Stack->FileObject != NULL)
{
PFCB Fcb;
Fcb = Stack->FileObject->FsContext;
if (!IoIsOperationSynchronous(Irp) ||
((Fcb != NULL && NodeTypeIsFcb(Fcb)) &&
(Stack->MajorFunction == IRP_MJ_READ || Stack->MajorFunction == IRP_MJ_WRITE || Stack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
(Fcb->pNetRoot != NULL && (Fcb->pNetRoot->Type == NET_ROOT_PIPE))))
{
RxContext->Flags |= RX_CONTEXT_FLAG_ASYNC_OPERATION;
}
}
if (Stack->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && Stack->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY)
{
RxContext->Flags |= RX_CONTEXT_FLAG_ASYNC_OPERATION;
}
if (Stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
RxContext->Flags |= RX_CONTEXT_FLAG_ASYNC_OPERATION;
}
/* Set proper flags if TopLevl IRP/Device */
if (!RxIsThisTheTopLevelIrp(Irp))
{
RxContext->Flags |= RX_CONTEXT_FLAG_RECURSIVE_CALL;
}
if (RxGetTopDeviceObjectIfRdbssIrp() == RxDeviceObject)
{
RxContext->Flags |= RX_CONTEXT_FLAG_THIS_DEVICE_TOP_LEVEL;
}
/* Copy stack information */
RxContext->MajorFunction = Stack->MajorFunction;
RxContext->MinorFunction = Stack->MinorFunction;
ASSERT(RxContext->MajorFunction <= IRP_MJ_MAXIMUM_FUNCTION);
RxContext->CurrentIrpSp = Stack;
/* If we have a FO associated, learn for more */
if (Stack->FileObject != NULL)
{
PFCB Fcb;
PFOBX Fobx;
/* Get the FCB and CCB (FOBX) */
Fcb = Stack->FileObject->FsContext;
Fobx = Stack->FileObject->FsContext2;
RxContext->pFcb = (PMRX_FCB)Fcb;
if (Fcb != NULL && NodeTypeIsFcb(Fcb))
{
RxContext->NonPagedFcb = Fcb->NonPaged;
}
/* We have a FOBX, this not a DFS opening, keep track of it */
if (Fobx != NULL && Fobx != UIntToPtr(DFS_OPEN_CONTEXT) && Fobx != UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT))
{
RxContext->pFobx = (PMRX_FOBX)Fobx;
RxContext->pRelevantSrvOpen = Fobx->pSrvOpen;
if (Fobx->NodeTypeCode == RDBSS_NTC_FOBX)
{
RxContext->FobxSerialNumber = InterlockedIncrement((volatile LONG *)&Fobx->FobxSerialNumber);
}
}
else
{
RxContext->pFobx = NULL;
}
/* In case of directory change notification, Fobx may be a VNetRoot, take note of that */
if (RxContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && RxContext->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY &&
Fobx != NULL)
{
PV_NET_ROOT VNetRoot = NULL;
if (Fobx->NodeTypeCode == RDBSS_NTC_FOBX)
{
VNetRoot = Fcb->VNetRoot;
}
else if (Fobx->NodeTypeCode == RDBSS_NTC_V_NETROOT)
{
VNetRoot = (PV_NET_ROOT)Fobx;
}
if (VNetRoot != NULL)
{
RxContext->NotifyChangeDirectory.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
}
}
/* Remember if that's a write through file */
RxContext->RealDevice = Stack->FileObject->DeviceObject;
if (BooleanFlagOn(Stack->FileObject->Flags, FO_WRITE_THROUGH))
{
RxContext->Flags |= RX_CONTEXT_FLAG_WRITE_THROUGH;
}
}
}
if (RxContext->MajorFunction != IRP_MJ_DEVICE_CONTROL)
{
DPRINT("New Ctxt: %p for MN: %d, IRP: %p, THRD: %p, FCB: %p, FOBX:%p #%lx\n",
RxContext, RxContext->MinorFunction, Irp,
PsGetCurrentThread(), RxContext->pFcb, RxContext->pFobx,
RxContext->SerialNumber);
}
}
/*
* @implemented
*/
VOID
NTAPI
RxInitializeDebugSupport(
VOID)
{
/* Nothing to do */
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RxInitializeDispatcher(
VOID)
{
NTSTATUS Status;
HANDLE ThreadHandle;
PAGED_CODE();
RxFileSystemDeviceObject->DispatcherContext.NumberOfWorkerThreads = 0;
RxFileSystemDeviceObject->DispatcherContext.pTearDownEvent = NULL;
/* Set appropriate timeouts: 10s & 60s */
RxWorkQueueWaitInterval[CriticalWorkQueue].QuadPart = -10 * 1000 * 1000 * 10;
RxWorkQueueWaitInterval[DelayedWorkQueue].QuadPart = -10 * 1000 * 1000 * 10;
RxWorkQueueWaitInterval[HyperCriticalWorkQueue].QuadPart = -10 * 1000 * 1000 * 10;
RxSpinUpDispatcherWaitInterval.QuadPart = -60 * 1000 * 1000 * 10;
RxDispatcher.NumberOfProcessors = 1;
RxDispatcher.OwnerProcess = IoGetCurrentProcess();
RxDispatcher.pWorkQueueDispatcher = &RxDispatcherWorkQueues;
/* Initialize our dispatchers */
Status = RxInitializeWorkQueueDispatcher(RxDispatcher.pWorkQueueDispatcher);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = RxInitializeMRxDispatcher(RxFileSystemDeviceObject);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* And start them */
RxDispatcher.State = RxDispatcherActive;
InitializeListHead(&RxDispatcher.SpinUpRequests);
KeInitializeSpinLock(&RxDispatcher.SpinUpRequestsLock);
KeInitializeEvent(&RxDispatcher.SpinUpRequestsEvent, 0, 0);
KeInitializeEvent(&RxDispatcher.SpinUpRequestsTearDownEvent, 0, 0);
Status = PsCreateSystemThread(&ThreadHandle, PROCESS_ALL_ACCESS, NULL,
NULL, NULL, RxSpinUpRequestsDispatcher, &RxDispatcher);
if (NT_SUCCESS(Status))
{
ZwClose(ThreadHandle);
}
return Status;
}
/*
* @implemented
*/
VOID
RxInitializeFcbTable(
IN OUT PRX_FCB_TABLE FcbTable,
IN BOOLEAN CaseInsensitiveMatch)
{
USHORT i;
PAGED_CODE();
FcbTable->NodeTypeCode = RDBSS_NTC_FCB_TABLE;
FcbTable->NodeByteSize = sizeof(RX_FCB_TABLE);
ExInitializeResourceLite(&FcbTable->TableLock);
FcbTable->CaseInsensitiveMatch = CaseInsensitiveMatch;
FcbTable->Version = 0;
FcbTable->TableEntryForNull = NULL;
FcbTable->NumberOfBuckets = RX_FCB_TABLE_NUMBER_OF_HASH_BUCKETS;
for (i = 0; i < FcbTable->NumberOfBuckets; ++i)
{
InitializeListHead(&FcbTable->HashBuckets[i]);
}
FcbTable->Lookups = 0;
FcbTable->FailedLookups = 0;
FcbTable->Compares = 0;
}
/*
* @implemented
*/
VOID
NTAPI
RxInitializeLowIoContext(
OUT PLOWIO_CONTEXT LowIoContext,
IN ULONG Operation)
{
PRX_CONTEXT RxContext;
PIO_STACK_LOCATION Stack;
PAGED_CODE();
RxContext = CONTAINING_RECORD(LowIoContext, RX_CONTEXT, LowIoContext);
ASSERT(LowIoContext == &RxContext->LowIoContext);
Stack = RxContext->CurrentIrpSp;
KeInitializeEvent(&RxContext->SyncEvent, NotificationEvent, FALSE);
RxContext->LowIoContext.ResourceThreadId = (ERESOURCE_THREAD)PsGetCurrentThread();
RxContext->LowIoContext.Operation = Operation;
switch (Operation)
{
case LOWIO_OP_READ:
case LOWIO_OP_WRITE:
/* In case of RW, set a canary, to make sure these fields are properly set
* they will be asserted when lowio request will be submit to mini-rdr
* See LowIoSubmit()
*/
RxContext->LowIoContext.ParamsFor.ReadWrite.ByteOffset = 0xFFFFFFEE;
RxContext->LowIoContext.ParamsFor.ReadWrite.ByteCount = 0xEEEEEEEE;
RxContext->LowIoContext.ParamsFor.ReadWrite.Key = Stack->Parameters.Read.Key;
/* Keep track of paging IOs */
if (BooleanFlagOn(RxContext->CurrentIrp->Flags, IRP_PAGING_IO))
{
RxContext->LowIoContext.ParamsFor.ReadWrite.Flags = LOWIO_READWRITEFLAG_PAGING_IO;
}
else
{
RxContext->LowIoContext.ParamsFor.ReadWrite.Flags = 0;
}
break;
case LOWIO_OP_FSCTL:
case LOWIO_OP_IOCTL:
/* This will be initialized later on with a call to RxLowIoPopulateFsctlInfo() */
RxContext->LowIoContext.ParamsFor.FsCtl.Flags = 0;
RxContext->LowIoContext.ParamsFor.FsCtl.InputBufferLength = 0;
RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = NULL;
RxContext->LowIoContext.ParamsFor.FsCtl.OutputBufferLength = 0;
RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = NULL;
RxContext->LowIoContext.ParamsFor.FsCtl.MinorFunction = 0;
break;
/* Nothing to do for these */
case LOWIO_OP_SHAREDLOCK:
case LOWIO_OP_EXCLUSIVELOCK:
case LOWIO_OP_UNLOCK:
case LOWIO_OP_UNLOCK_MULTIPLE:
case LOWIO_OP_NOTIFY_CHANGE_DIRECTORY:
case LOWIO_OP_CLEAROUT:
break;
default:
/* Should never happen */
ASSERT(FALSE);
break;
}
}
/*
* @implemented
*/
VOID
RxInitializeLowIoPerFcbInfo(
PLOWIO_PER_FCB_INFO LowIoPerFcbInfo)
{
PAGED_CODE();
InitializeListHead(&LowIoPerFcbInfo->PagingIoReadsOutstanding);
InitializeListHead(&LowIoPerFcbInfo->PagingIoWritesOutstanding);
}
/*
* @implemented
*/
NTSTATUS
RxInitializeMRxDispatcher(
IN OUT PRDBSS_DEVICE_OBJECT pMRxDeviceObject)
{
PAGED_CODE();
pMRxDeviceObject->DispatcherContext.NumberOfWorkerThreads = 0;
pMRxDeviceObject->DispatcherContext.pTearDownEvent = NULL;
return STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
RxInitializePrefixTable(
IN OUT PRX_PREFIX_TABLE ThisTable,
IN ULONG TableSize OPTIONAL,
IN BOOLEAN CaseInsensitiveMatch)
{
PAGED_CODE();
if (TableSize == 0)
{
TableSize = RX_PREFIX_TABLE_DEFAULT_LENGTH;
}
ThisTable->NodeTypeCode = RDBSS_NTC_PREFIX_TABLE;
ThisTable->NodeByteSize = sizeof(RX_PREFIX_TABLE);
InitializeListHead(&ThisTable->MemberQueue);
ThisTable->Version = 0;
ThisTable->TableEntryForNull = NULL;
ThisTable->IsNetNameTable = FALSE;
ThisTable->CaseInsensitiveMatch = CaseInsensitiveMatch;
ThisTable->TableSize = TableSize;
if (TableSize > 0)
{
USHORT i;
for (i = 0; i < RX_PREFIX_TABLE_DEFAULT_LENGTH; ++i)
{
InitializeListHead(&ThisTable->HashBuckets[i]);
}
}
}
/*
* @implemented
*/
VOID
RxInitializePurgeSyncronizationContext(
PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext)
{
PAGED_CODE();
InitializeListHead(&PurgeSyncronizationContext->ContextsAwaitingPurgeCompletion);
PurgeSyncronizationContext->PurgeInProgress = FALSE;
}
NTSTATUS
RxInitializeSrvCallParameters(
IN PRX_CONTEXT RxContext,
IN OUT PSRV_CALL SrvCall)
{
PAGED_CODE();
SrvCall->pPrincipalName = NULL;
/* We only have stuff to initialize for file opening from DFS */
if (RxContext->MajorFunction != IRP_MJ_CREATE || RxContext->Create.EaLength == 0)
{
return STATUS_SUCCESS;
}
ASSERT(RxContext->Create.EaBuffer != NULL);
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
NTSTATUS
NTAPI
RxInitializeRxTimer(
VOID)
{
PAGED_CODE();
RxTimerInterval.QuadPart = -550000;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
KeInitializeSpinLock(&RxTimerLock);
InitializeListHead(&RxTimerQueueHead);
InitializeListHead(&RxRecurrentWorkItemsList);
KeInitializeDpc(&RxTimerDpc, RxTimerDispatch, NULL);
KeInitializeTimer(&RxTimer);
RxTimerTickCount = 0;
return STATUS_SUCCESS;
}
NTSTATUS
RxInitializeVNetRootParameters(
PRX_CONTEXT RxContext,
OUT LUID *LogonId,
OUT PULONG SessionId,
OUT PUNICODE_STRING *UserNamePtr,
OUT PUNICODE_STRING *UserDomainNamePtr,
OUT PUNICODE_STRING *PasswordPtr,
OUT PULONG Flags)
{
NTSTATUS Status;
PACCESS_TOKEN Token;
PAGED_CODE();
DPRINT("RxInitializeVNetRootParameters(%p, %p, %p, %p, %p, %p, %p)\n", RxContext,
LogonId, SessionId, UserNamePtr, UserDomainNamePtr, PasswordPtr, Flags);
*UserNamePtr = NULL;
*UserDomainNamePtr = NULL;
*PasswordPtr = NULL;
/* By default, that's not CSC instance */
*Flags &= ~VNETROOT_FLAG_CSCAGENT_INSTANCE;
Token = SeQuerySubjectContextToken(&RxContext->Create.NtCreateParameters.SecurityContext->AccessState->SubjectSecurityContext);
if (SeTokenIsRestricted(Token))
{
return STATUS_ACCESS_DENIED;
}
/* Get LogonId */
Status = SeQueryAuthenticationIdToken(Token, LogonId);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* And SessionId */
Status = SeQuerySessionIdToken(Token, SessionId);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (RxContext->Create.UserName.Buffer != NULL)
{
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
goto Leave;
}
/* Deal with connection credentials */
if (RxContext->Create.UserDomainName.Buffer != NULL)
{
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
goto Leave;
}
if (RxContext->Create.Password.Buffer != NULL)
{
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
goto Leave;
}
Leave:
if (NT_SUCCESS(Status))
{
/* If that's a CSC instance, mark it as such */
if (RxIsThisACscAgentOpen(RxContext))
{
*Flags |= VNETROOT_FLAG_CSCAGENT_INSTANCE;
}
return Status;
}
return Status;
}
/*
* @implemented
*/
VOID
RxInitializeWorkQueue(
PRX_WORK_QUEUE WorkQueue,
WORK_QUEUE_TYPE WorkQueueType,
ULONG MaximumNumberOfWorkerThreads,
ULONG MinimumNumberOfWorkerThreads)
{
PAGED_CODE();
WorkQueue->Type = WorkQueueType;
WorkQueue->MaximumNumberOfWorkerThreads = MaximumNumberOfWorkerThreads;
WorkQueue->MinimumNumberOfWorkerThreads = MinimumNumberOfWorkerThreads;
WorkQueue->State = RxWorkQueueActive;
WorkQueue->SpinUpRequestPending = FALSE;
WorkQueue->pRundownContext = NULL;
WorkQueue->NumberOfWorkItemsDispatched = 0;
WorkQueue->NumberOfWorkItemsToBeDispatched = 0;
WorkQueue->CumulativeQueueLength = 0;
WorkQueue->NumberOfSpinUpRequests = 0;
WorkQueue->NumberOfActiveWorkerThreads = 0;
WorkQueue->NumberOfIdleWorkerThreads = 0;
WorkQueue->NumberOfFailedSpinUpRequests = 0;
WorkQueue->WorkQueueItemForSpinUpWorkerThreadInUse = 0;
WorkQueue->WorkQueueItemForTearDownWorkQueue.List.Flink = NULL;
WorkQueue->WorkQueueItemForTearDownWorkQueue.WorkerRoutine = NULL;
WorkQueue->WorkQueueItemForTearDownWorkQueue.Parameter = NULL;
WorkQueue->WorkQueueItemForTearDownWorkQueue.pDeviceObject = NULL;
WorkQueue->WorkQueueItemForSpinUpWorkerThread.List.Flink = NULL;
WorkQueue->WorkQueueItemForSpinUpWorkerThread.WorkerRoutine = NULL;
WorkQueue->WorkQueueItemForSpinUpWorkerThread.Parameter = NULL;
WorkQueue->WorkQueueItemForSpinUpWorkerThread.pDeviceObject = NULL;
WorkQueue->WorkQueueItemForSpinDownWorkerThread.List.Flink = NULL;
WorkQueue->WorkQueueItemForSpinDownWorkerThread.WorkerRoutine = NULL;
WorkQueue->WorkQueueItemForSpinDownWorkerThread.Parameter = NULL;
WorkQueue->WorkQueueItemForSpinDownWorkerThread.pDeviceObject = NULL;
KeInitializeQueue(&WorkQueue->Queue, MaximumNumberOfWorkerThreads);
KeInitializeSpinLock(&WorkQueue->SpinLock);
}
/*
* @implemented
*/
NTSTATUS
RxInitializeWorkQueueDispatcher(
PRX_WORK_QUEUE_DISPATCHER Dispatcher)
{
NTSTATUS Status;
ULONG MaximumNumberOfWorkerThreads;
PAGED_CODE();
/* Number of threads will depend on system capacity */
if (MmQuerySystemSize() != MmLargeSystem)
{
MaximumNumberOfWorkerThreads = 5;
}
else
{
MaximumNumberOfWorkerThreads = 10;
}
/* Initialize the work queues */
RxInitializeWorkQueue(&Dispatcher->WorkQueue[CriticalWorkQueue], CriticalWorkQueue,
MaximumNumberOfWorkerThreads, 1);
RxInitializeWorkQueue(&Dispatcher->WorkQueue[DelayedWorkQueue], DelayedWorkQueue, 2, 1);
RxInitializeWorkQueue(&Dispatcher->WorkQueue[HyperCriticalWorkQueue], HyperCriticalWorkQueue, 5, 1);
/* And start the worker threads */
Status = RxSpinUpWorkerThread(&Dispatcher->WorkQueue[HyperCriticalWorkQueue],
RxBootstrapWorkerThreadDispatcher,
&Dispatcher->WorkQueue[HyperCriticalWorkQueue]);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = RxSpinUpWorkerThread(&Dispatcher->WorkQueue[CriticalWorkQueue],
RxBootstrapWorkerThreadDispatcher,
&Dispatcher->WorkQueue[CriticalWorkQueue]);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = RxSpinUpWorkerThread(&Dispatcher->WorkQueue[DelayedWorkQueue],
RxBootstrapWorkerThreadDispatcher,
&Dispatcher->WorkQueue[DelayedWorkQueue]);
return Status;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
RxInitiateSrvOpenKeyAssociation(
IN OUT PSRV_OPEN SrvOpen)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PRX_BUFFERING_MANAGER BufferingManager;
PAGED_CODE();
SrvOpen->Key = NULL;
/* Just keep track of the opening request */
BufferingManager = &((PSRV_CALL)((PFCB)SrvOpen->pFcb)->VNetRoot->pNetRoot->pSrvCall)->BufferingManager;
InterlockedIncrement(&BufferingManager->NumberOfOutstandingOpens);
InitializeListHead(&SrvOpen->SrvOpenKeyList);
}
/*
* @implemented
*/
NTSTATUS
RxInsertWorkQueueItem(
PRDBSS_DEVICE_OBJECT pMRxDeviceObject,
WORK_QUEUE_TYPE WorkQueueType,
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PRX_WORK_QUEUE_ITEM WorkQueueItem)
{
KIRQL OldIrql;
NTSTATUS Status;
BOOLEAN SpinUpThreads;
PRX_WORK_QUEUE WorkQueue;
/* No dispatcher, nothing to insert */
if (RxDispatcher.State != RxDispatcherActive)
{
return STATUS_UNSUCCESSFUL;
}
/* Get the work queue */
WorkQueue = &RxDispatcher.pWorkQueueDispatcher->WorkQueue[WorkQueueType];
KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
/* Only insert if the work queue is in decent state */
if (WorkQueue->State != RxWorkQueueActive || pMRxDeviceObject->DispatcherContext.pTearDownEvent != NULL)
{
Status = STATUS_UNSUCCESSFUL;
}
else
{
SpinUpThreads = FALSE;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
WorkQueueItem->pDeviceObject = pMRxDeviceObject;
InterlockedIncrement(&pMRxDeviceObject->DispatcherContext.NumberOfWorkerThreads);
WorkQueue->CumulativeQueueLength += WorkQueue->NumberOfWorkItemsToBeDispatched;
InterlockedIncrement(&WorkQueue->NumberOfWorkItemsToBeDispatched);
/* If required (and possible!), spin up a new worker thread */
if (WorkQueue->NumberOfIdleWorkerThreads < WorkQueue->NumberOfWorkItemsToBeDispatched &&
WorkQueue->NumberOfActiveWorkerThreads < WorkQueue->MaximumNumberOfWorkerThreads &&
!WorkQueue->SpinUpRequestPending)
{
WorkQueue->SpinUpRequestPending = TRUE;
SpinUpThreads = TRUE;
}
Status = STATUS_SUCCESS;
}
KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
/* If we failed, return and still not insert item */
if (!NT_SUCCESS(Status))
{
return Status;
}
/* All fine, insert the item */
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
KeInsertQueue(&WorkQueue->Queue, &WorkQueueItem->List);
/* And start a new worker thread if needed */
if (SpinUpThreads)
{
RxSpinUpWorkerThreads(WorkQueue);
}
return Status;
}
BOOLEAN
RxIsThisACscAgentOpen(
IN PRX_CONTEXT RxContext)
{
BOOLEAN CscAgent;
CscAgent = FALSE;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/* Client Side Caching is DFS stuff - we don't support it */
if (RxContext->Create.EaLength != 0)
{
UNIMPLEMENTED;
}
if (RxContext->Create.NtCreateParameters.DfsNameContext != NULL &&
((PDFS_NAME_CONTEXT)RxContext->Create.NtCreateParameters.DfsNameContext)->NameContextType == 0xAAAAAAAA)
{
CscAgent = TRUE;
}
return CscAgent;
}
VOID
RxLockUserBuffer(
IN PRX_CONTEXT RxContext,
IN LOCK_OPERATION Operation,
IN ULONG BufferLength)
{
PIRP Irp;
PMDL Mdl = NULL;
PAGED_CODE();
_SEH2_TRY
{
Irp = RxContext->CurrentIrp;
/* If we already have a MDL, make sure it's locked */
if (Irp->MdlAddress != NULL)
{
ASSERT(RxLowIoIsMdlLocked(Irp->MdlAddress));
}
else
{
/* That likely means the driver asks for buffered IOs - we don't support it! */
ASSERT(!BooleanFlagOn(Irp->Flags, IRP_INPUT_OPERATION));
/* If we have a real length */
if (BufferLength > 0)
{
/* Allocate a MDL and lock it */
Mdl = IoAllocateMdl(Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp);
if (Mdl == NULL)
{
RxContext->StoredStatus = STATUS_INSUFFICIENT_RESOURCES;
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
}
MmProbeAndLockPages(Mdl, Irp->RequestorMode, Operation);
}
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
NTSTATUS Status;
Status = _SEH2_GetExceptionCode();
/* Free the possible MDL we have allocated */
IoFreeMdl(Mdl);
Irp->MdlAddress = NULL;
RxContext->Flags |= RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT;
/* Fix status */
if (!FsRtlIsNtstatusExpected(Status))
{
Status = STATUS_INVALID_USER_BUFFER;
}
RxContext->IoStatusBlock.Status = Status;
ExRaiseStatus(Status);
}
_SEH2_END;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
NTSTATUS
RxLowIoCompletionTail(
IN PRX_CONTEXT RxContext)
{
NTSTATUS Status;
USHORT Operation;
PAGED_CODE();
DPRINT("RxLowIoCompletionTail(%p)\n", RxContext);
/* Only continue if we're at APC_LEVEL or lower */
if (RxShouldPostCompletion() &&
!BooleanFlagOn(RxContext->LowIoContext.Flags, LOWIO_CONTEXT_FLAG_CAN_COMPLETE_AT_DPC_LEVEL))
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
/* Call the completion routine */
DPRINT("Calling completion routine: %p\n", RxContext->LowIoContext.CompletionRoutine);
Status = RxContext->LowIoContext.CompletionRoutine(RxContext);
if (Status == STATUS_MORE_PROCESSING_REQUIRED || Status == STATUS_RETRY)
{
return Status;
}
/* If it was a RW operation, for a paging file ... */
Operation = RxContext->LowIoContext.Operation;
if (Operation == LOWIO_OP_READ || Operation == LOWIO_OP_WRITE)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Remove ourselves from the list and resume operations */
if (BooleanFlagOn(RxContext->LowIoContext.ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_PAGING_IO))
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
ExAcquireFastMutexUnsafe(&RxLowIoPagingIoSyncMutex);
RemoveEntryList(&RxContext->RxContextSerializationQLinks);
RxContext->RxContextSerializationQLinks.Flink = NULL;
RxContext->RxContextSerializationQLinks.Blink = NULL;
ExReleaseFastMutexUnsafe(&RxLowIoPagingIoSyncMutex);
RxResumeBlockedOperations_ALL(RxContext);
}
}
else
{
/* Sanity check: we had known operation */
ASSERT(Operation < LOWIO_OP_MAXIMUM);
}
/* If not sync operation, complete now. Otherwise, caller has already completed */
if (!BooleanFlagOn(RxContext->LowIoContext.Flags, LOWIO_CONTEXT_FLAG_SYNCCALL))
{
RxCompleteRequest(RxContext, Status);
}
DPRINT("Status: %x\n", Status);
return Status;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RxLowIoPopulateFsctlInfo(
IN PRX_CONTEXT RxContext)
{
PMDL Mdl;
PIRP Irp;
UCHAR Method;
PIO_STACK_LOCATION Stack;
PAGED_CODE();
DPRINT("RxLowIoPopulateFsctlInfo(%p)\n", RxContext);
Irp = RxContext->CurrentIrp;
Stack = RxContext->CurrentIrpSp;
/* Copy stack parameters */
RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode = Stack->Parameters.FileSystemControl.FsControlCode;
RxContext->LowIoContext.ParamsFor.FsCtl.InputBufferLength = Stack->Parameters.FileSystemControl.InputBufferLength;
RxContext->LowIoContext.ParamsFor.FsCtl.OutputBufferLength = Stack->Parameters.FileSystemControl.OutputBufferLength;
RxContext->LowIoContext.ParamsFor.FsCtl.MinorFunction = Stack->MinorFunction;
Method = METHOD_FROM_CTL_CODE(RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode);
/* Same buffer in case of buffered */
if (Method == METHOD_BUFFERED)
{
RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = Irp->AssociatedIrp.SystemBuffer;
return STATUS_SUCCESS;
}
/* Two buffers for neither */
if (Method == METHOD_NEITHER)
{
RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = Stack->Parameters.FileSystemControl.Type3InputBuffer;
RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = Irp->UserBuffer;
return STATUS_SUCCESS;
}
/* Only IN/OUT remain */
ASSERT(Method == METHOD_IN_DIRECT || Method == METHOD_OUT_DIRECT);
/* Use system buffer for input */
RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
/* And MDL for output */
Mdl = Irp->MdlAddress;
if (Mdl != NULL)
{
RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
if (RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = NULL;
}
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RxLowIoSubmit(
IN PRX_CONTEXT RxContext,
IN PLOWIO_COMPLETION_ROUTINE CompletionRoutine)
{
NTSTATUS Status;
USHORT Operation;
BOOLEAN Synchronous;
PLOWIO_CONTEXT LowIoContext;
DPRINT("RxLowIoSubmit(%p, %p)\n", RxContext, CompletionRoutine);
PAGED_CODE();
LowIoContext = &RxContext->LowIoContext;
Synchronous = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
LowIoContext->CompletionRoutine = CompletionRoutine;
Status = STATUS_SUCCESS;
Operation = LowIoContext->Operation;
switch (Operation)
{
case LOWIO_OP_READ:
case LOWIO_OP_WRITE:
/* Check that the parameters were properly set by caller
* See comment in RxInitializeLowIoContext()
*/
ASSERT(LowIoContext->ParamsFor.ReadWrite.ByteOffset != 0xFFFFFFEE);
ASSERT(LowIoContext->ParamsFor.ReadWrite.ByteCount != 0xEEEEEEEE);
/* Lock the buffer */
RxLockUserBuffer(RxContext,
(Operation == LOWIO_OP_READ ? IoWriteAccess : IoReadAccess),
LowIoContext->ParamsFor.ReadWrite.ByteCount);
if (RxNewMapUserBuffer(RxContext) == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
LowIoContext->ParamsFor.ReadWrite.Buffer = RxContext->CurrentIrp->MdlAddress;
/* If that's a paging IO, initialize serial operation */
if (BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_PAGING_IO))
{
PFCB Fcb;
Fcb = (PFCB)RxContext->pFcb;
ExAcquireFastMutexUnsafe(&RxLowIoPagingIoSyncMutex);
RxContext->BlockedOpsMutex = &RxLowIoPagingIoSyncMutex;
if (Operation == LOWIO_OP_READ)
{
InsertTailList(&Fcb->Specific.Fcb.PagingIoReadsOutstanding, &RxContext->RxContextSerializationQLinks);
}
else
{
InsertTailList(&Fcb->Specific.Fcb.PagingIoWritesOutstanding, &RxContext->RxContextSerializationQLinks);
}
ExReleaseFastMutexUnsafe(&RxLowIoPagingIoSyncMutex);
}
break;
case LOWIO_OP_FSCTL:
case LOWIO_OP_IOCTL:
/* Set FSCTL/IOCTL parameters */
Status = RxLowIoPopulateFsctlInfo(RxContext);
/* Check whether we're consistent: a length means a buffer */
if (NT_SUCCESS(Status))
{
if ((LowIoContext->ParamsFor.FsCtl.InputBufferLength > 0 &&
LowIoContext->ParamsFor.FsCtl.pInputBuffer == NULL) ||
(LowIoContext->ParamsFor.FsCtl.OutputBufferLength > 0 &&
LowIoContext->ParamsFor.FsCtl.pOutputBuffer == NULL))
{
Status = STATUS_INVALID_PARAMETER;
}
}
break;
/* Nothing to do */
case LOWIO_OP_SHAREDLOCK:
case LOWIO_OP_EXCLUSIVELOCK:
case LOWIO_OP_UNLOCK:
case LOWIO_OP_UNLOCK_MULTIPLE:
case LOWIO_OP_NOTIFY_CHANGE_DIRECTORY:
case LOWIO_OP_CLEAROUT:
break;
default:
ASSERT(FALSE);
Status = STATUS_INVALID_PARAMETER;
break;
}
/* No need to perform extra init in case of posting */
RxContext->Flags |= RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED;
/* Preflight checks were OK, time to submit */
if (NT_SUCCESS(Status))
{
PMINIRDR_DISPATCH Dispatch;
if (!Synchronous)
{
InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
/* If not synchronous, we're likely to return before the operation is finished */
if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP))
{
IoMarkIrpPending(RxContext->CurrentIrp);
}
}
Dispatch = RxContext->RxDeviceObject->Dispatch;
if (Dispatch != NULL)
{
/* We'll try to execute until the mini-rdr doesn't return pending */
do
{
RxContext->IoStatusBlock.Information = 0;
MINIRDR_CALL(Status, RxContext, Dispatch, MRxLowIOSubmit[Operation], (RxContext));
if (Status == STATUS_PENDING)
{
/* Unless it's not synchronous, caller will be happy with pending op */
if (!Synchronous)
{
return Status;
}
RxWaitSync(RxContext);
Status = RxContext->IoStatusBlock.Status;
}
else
{
if (!Synchronous)
{
/* We had marked the IRP pending, whereas the operation finished, drop that */
if (Status != STATUS_RETRY)
{
if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP))
{
RxContext->CurrentIrpSp->Flags &= ~SL_PENDING_RETURNED;
}
InterlockedDecrement((volatile long *)&RxContext->ReferenceCount);
}
}
}
} while (Status == STATUS_PENDING);
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
/* Call completion and return */
RxContext->IoStatusBlock.Status = Status;
LowIoContext->Flags |= LOWIO_CONTEXT_FLAG_SYNCCALL;
return RxLowIoCompletionTail(RxContext);
}
/*
* @implemented
*/
PVOID
RxMapSystemBuffer(
IN PRX_CONTEXT RxContext)
{
PIRP Irp;
PAGED_CODE();
Irp = RxContext->CurrentIrp;
/* We should have a MDL (buffered IOs are not supported!) */
if (Irp->MdlAddress != NULL)
{
ASSERT(FALSE);
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
/* Just return system buffer */
return Irp->AssociatedIrp.SystemBuffer;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxMarkFobxOnCleanup(
PFOBX pFobx,
PBOOLEAN NeedPurge)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PFCB Fcb;
PFOBX ScavengerFobx;
LARGE_INTEGER TickCount;
PRDBSS_SCAVENGER Scavenger;
PAGED_CODE();
/* No FOBX, nothing to mark */
if (pFobx == NULL)
{
return;
}
/* Query time for close */
KeQueryTickCount(&TickCount);
Fcb = (PFCB)pFobx->pSrvOpen->pFcb;
ASSERT(NodeTypeIsFcb(Fcb));
Scavenger = Fcb->RxDeviceObject->pRdbssScavenger;
RxAcquireScavengerMutex();
ScavengerFobx = NULL;
/* If that's not a file, or even not a disk resource, just mark as dormant */
if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_FILE || Fcb->VNetRoot->pNetRoot->DeviceType != FILE_DEVICE_DISK)
{
SetFlag(pFobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
InitializeListHead(&pFobx->ClosePendingList);
++Scavenger->NumberOfDormantFiles;
}
else
{
ASSERT(Scavenger->NumberOfDormantFiles >= 0);
/* If we're about to reach the maximum dormant of FOBX */
if (Scavenger->NumberOfDormantFiles >= Scavenger->MaximumNumberOfDormantFiles)
{
/* This should never be wrong... */
if (!IsListEmpty(&Scavenger->ClosePendingFobxsList))
{
/* Then, take the first from the list (oldest) and save it for later purge */
ScavengerFobx = CONTAINING_RECORD(Scavenger->ClosePendingFobxsList.Flink, FOBX, ClosePendingList);
if (ScavengerFobx->pSrvOpen != NULL && ScavengerFobx->pSrvOpen->pFcb == RX_GET_MRX_FCB(Fcb))
{
*NeedPurge = TRUE;
ScavengerFobx = NULL;
}
else
{
RxReferenceNetFobx(ScavengerFobx);
}
}
}
/* Mark ourselves as dormant */
SetFlag(pFobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
pFobx->CloseTime.QuadPart = TickCount.QuadPart;
/* And insert us in the list of dormant files */
InsertTailList(&Scavenger->ClosePendingFobxsList, &pFobx->ClosePendingList);
/* If scavenger was inactive, start it */
if (Scavenger->NumberOfDormantFiles++ == 0 && Scavenger->State == RDBSS_SCAVENGER_INACTIVE)
{
Scavenger->State = RDBSS_SCAVENGER_DORMANT;
RxPostOneShotTimerRequest(RxFileSystemDeviceObject, &Scavenger->WorkItem, RxScavengerTimerRoutine,
Fcb->RxDeviceObject, Scavenger->TimeLimit);
}
}
RxReleaseScavengerMutex();
/* If we had reached max */
if (ScavengerFobx != NULL)
{
NTSTATUS Status;
/* Purge the oldest FOBX */
Status = RxPurgeFobxFromCache(ScavengerFobx);
if (Status != STATUS_SUCCESS)
{
*NeedPurge = TRUE;
}
}
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxMarkFobxOnClose(
PFOBX Fobx)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PFCB Fcb;
PRDBSS_SCAVENGER Scavenger;
PAGED_CODE();
/* No FOBX, nothing to mark */
if (Fobx == NULL)
{
return;
}
Fcb = (PFCB)Fobx->pSrvOpen->pFcb;
ASSERT(NodeTypeIsFcb(Fcb));
Scavenger = Fcb->RxDeviceObject->pRdbssScavenger;
RxAcquireScavengerMutex();
/* Only mark it if it was already marked as dormant */
if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT))
{
/* If FCB wasn't already decrement, do it now */
if (!Fobx->fOpenCountDecremented)
{
Fcb = (PFCB)Fobx->pSrvOpen->pFcb;
ASSERT(NodeTypeIsFcb(Fcb));
InterlockedDecrement((volatile long *)&Fcb->OpenCount);
Fobx->fOpenCountDecremented = TRUE;
}
/* We're no longer dormant */
InterlockedDecrement(&Scavenger->NumberOfDormantFiles);
ClearFlag(Fobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
}
/* If we were inserted in the scavenger, drop ourselves out */
if (!IsListEmpty(&Fobx->ClosePendingList))
{
RemoveEntryList(&Fobx->ClosePendingList);
InitializeListHead(&Fobx->ClosePendingList);
}
RxReleaseScavengerMutex();
}
/*
* @implemented
*/
PVOID
RxNewMapUserBuffer(
PRX_CONTEXT RxContext)
{
PIRP Irp;
PAGED_CODE();
Irp = RxContext->CurrentIrp;
if (Irp->MdlAddress != NULL)
{
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
return Irp->UserBuffer;
}
BOOLEAN
NTAPI
RxNoOpAcquire(
IN PVOID Fcb,
IN BOOLEAN Wait)
{
UNIMPLEMENTED;
return FALSE;
}
VOID
NTAPI
RxNoOpRelease(
IN PVOID Fcb)
{
UNIMPLEMENTED;
}
VOID
RxOrphanThisFcb(
PFCB Fcb)
{
UNIMPLEMENTED;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
VOID
RxOrphanSrvOpens(
IN PV_NET_ROOT ThisVNetRoot)
{
PFCB Fcb;
USHORT Bucket;
PNET_ROOT NetRoot;
PRX_FCB_TABLE FcbTable;
PRX_PREFIX_TABLE PrefixTable;
PAGED_CODE();
/* Mailslot won't have any SRV_OPEN (to orphan) */
NetRoot = (PNET_ROOT)ThisVNetRoot->pNetRoot;
if (NetRoot->Type == NET_ROOT_MAILSLOT)
{
return;
}
PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
ASSERT(RxIsPrefixTableLockExclusive(PrefixTable));
FcbTable = &NetRoot->FcbTable;
RxAcquireFcbTableLockExclusive(FcbTable, TRUE);
_SEH2_TRY
{
/* Now, we'll browse all the FCBs attached, and orphan related SRV_OPENs */
for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
{
PLIST_ENTRY BucketList, Entry;
BucketList = &FcbTable->HashBuckets[Bucket];
Entry = BucketList->Flink;
while (Entry != BucketList)
{
Fcb = CONTAINING_RECORD(Entry, FCB, FcbTableEntry.HashLinks);
Entry = Entry->Flink;
ASSERT(NodeTypeIsFcb(Fcb));
RxOrphanSrvOpensForThisFcb(Fcb, ThisVNetRoot, FALSE);
}
}
/* Of course, don't forget about NULL-entry */
if (FcbTable->TableEntryForNull != NULL)
{
Fcb = CONTAINING_RECORD(FcbTable->TableEntryForNull, FCB, FcbTableEntry.HashLinks);
ASSERT(NodeTypeIsFcb(Fcb));
RxOrphanSrvOpensForThisFcb(Fcb, ThisVNetRoot, FALSE);
}
}
_SEH2_FINALLY
{
RxReleaseFcbTableLock(FcbTable);
}
_SEH2_END;
}
VOID
RxOrphanSrvOpensForThisFcb(
IN PFCB Fcb,
IN PV_NET_ROOT ThisVNetRoot,
IN BOOLEAN OrphanAll)
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
BOOLEAN
RxpAcquirePrefixTableLockShared(
PRX_PREFIX_TABLE pTable,
BOOLEAN Wait,
BOOLEAN ProcessBufferingStateChangeRequests)
{
PAGED_CODE();
DPRINT("RxpAcquirePrefixTableLockShared(%p, %d, %d) -> %d\n", pTable, Wait, ProcessBufferingStateChangeRequests,
pTable->TableLock.ActiveEntries);
return ExAcquireResourceSharedLite(&pTable->TableLock, Wait);
}
/*
* @implemented
*/
BOOLEAN
RxpAcquirePrefixTableLockExclusive(
PRX_PREFIX_TABLE pTable,
BOOLEAN Wait,
BOOLEAN ProcessBufferingStateChangeRequests)
{
PAGED_CODE();
DPRINT("RxpAcquirePrefixTableLockExclusive(%p, %d, %d) -> %d\n", pTable, Wait, ProcessBufferingStateChangeRequests,
pTable->TableLock.ActiveEntries);
return ExAcquireResourceExclusiveLite(&pTable->TableLock, Wait);
}
/*
* @implemented
*/
BOOLEAN
RxpDereferenceAndFinalizeNetFcb(
OUT PFCB ThisFcb,
IN PRX_CONTEXT RxContext,
IN BOOLEAN RecursiveFinalize,
IN BOOLEAN ForceFinalize)
{
NTSTATUS Status;
ULONG References;
PNET_ROOT NetRoot;
BOOLEAN ResourceAcquired, NetRootReferenced, Freed;
PAGED_CODE();
ASSERT(!ForceFinalize);
ASSERT(NodeTypeIsFcb(ThisFcb));
ASSERT(RxIsFcbAcquiredExclusive(ThisFcb));
/* Unless we're recursively finalizing, or forcing, if FCB is still in use, quit */
References = InterlockedDecrement((volatile long *)&ThisFcb->NodeReferenceCount);
if (!ForceFinalize && !RecursiveFinalize && (ThisFcb->OpenCount != 0 || ThisFcb->UncleanCount != 0 || References > 1))
{
return FALSE;
}
Freed = FALSE;
Status = STATUS_SUCCESS;
NetRoot = (PNET_ROOT)ThisFcb->VNetRoot->pNetRoot;
ResourceAcquired = FALSE;
NetRootReferenced = FALSE;
/* If FCB isn't orphaned, it still have context attached */
if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_ORPHANED))
{
/* Don't let NetRoot go away before we're done */
RxReferenceNetRoot(NetRoot);
NetRootReferenced = TRUE;
/* Try to acquire the table lock exclusively */
if (!RxIsFcbTableLockExclusive(&NetRoot->FcbTable))
{
RxReferenceNetFcb(ThisFcb);
if (!RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, FALSE))
{
if (RxContext != NULL && RxContext != CHANGE_BUFFERING_STATE_CONTEXT &&
RxContext != CHANGE_BUFFERING_STATE_CONTEXT_WAIT)
{
RxContext->Flags |= RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK;
}
RxReleaseFcb(RxContext, ThisFcb);
RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
Status = RxAcquireExclusiveFcb(RxContext, ThisFcb);
}
References = RxDereferenceNetFcb(ThisFcb);
ResourceAcquired = TRUE;
}
}
/* If locking was OK (or not needed!), attempt finalization */
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
if (Status == STATUS_SUCCESS)
{
Freed = RxFinalizeNetFcb(ThisFcb, RecursiveFinalize, ForceFinalize, References);
}
/* Release table lock if acquired */
if (ResourceAcquired)
{
RxReleaseFcbTableLock(&NetRoot->FcbTable);
}
/* We don't need the NetRoot anylonger */
if (NetRootReferenced)
{
RxDereferenceNetRoot(NetRoot, LHS_LockNotHeld);
}
return Freed;
}
/*
* @implemented
*/
LONG
RxpDereferenceNetFcb(
PFCB Fcb)
{
LONG NewCount;
PAGED_CODE();
ASSERT(NodeTypeIsFcb(Fcb));
NewCount = InterlockedDecrement((volatile long *)&Fcb->NodeReferenceCount);
ASSERT(NewCount >= 0);
PRINT_REF_COUNT(NETFCB, NewCount);
return NewCount;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
NTAPI
RxpDestroySrvCall(
IN PVOID Context)
{
NTSTATUS Status;
PSRV_CALL SrvCall;
BOOLEAN ForceFinalize;
PRX_PREFIX_TABLE PrefixTable;
SrvCall = (PSRV_CALL)Context;
/* At this step, RxFinalizeSrvCall already cleaned some fields */
ASSERT(SrvCall->UpperFinalizationDone);
PrefixTable = SrvCall->RxDeviceObject->pRxNetNameTable;
/* Were we called with ForceFinalize? */
ForceFinalize = BooleanFlagOn(SrvCall->Flags, SRVCALL_FLAG_FORCE_FINALIZED);
/* Notify mini-rdr */
MINIRDR_CALL_THROUGH(Status, SrvCall->RxDeviceObject->Dispatch,
MRxFinalizeSrvCall, ((PMRX_SRV_CALL)SrvCall,
ForceFinalize));
(void)Status;
/* Dereference our extra reference (set before queueing) */
RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
InterlockedDecrement((volatile long *)&SrvCall->NodeReferenceCount);
/* And finalize for real, with the right context */
RxFinalizeSrvCall(SrvCall, FALSE, ForceFinalize);
RxReleasePrefixTableLock(PrefixTable);
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxpDiscardChangeBufferingStateRequests(
_Inout_ PLIST_ENTRY DiscardedRequests)
{
PLIST_ENTRY Entry;
PAGED_CODE();
/* No requests to discard */
if (IsListEmpty(DiscardedRequests))
{
return;
}
/* Free all the discarded requests */
Entry = DiscardedRequests->Flink;
while (Entry != DiscardedRequests)
{
PCHANGE_BUFFERING_STATE_REQUEST Request;
Request = CONTAINING_RECORD(Entry, CHANGE_BUFFERING_STATE_REQUEST, ListEntry);
Entry = Entry->Flink;
DPRINT("Req %p for %p (%p) discarded\n", Request, Request->SrvOpenKey, Request->SrvOpen);
RxPrepareRequestForReuse(Request);
RxFreePool(Request);
}
}
/*
* @implemented
*/
VOID
RxpDispatchChangeBufferingStateRequests(
PSRV_CALL SrvCall,
PSRV_OPEN SrvOpen,
PLIST_ENTRY DiscardedRequests)
{
KIRQL OldIrql;
NTSTATUS Status;
BOOLEAN StartDispatcher;
LIST_ENTRY AcceptedReqs;
LIST_ENTRY DispatcherList;
PRX_BUFFERING_MANAGER BufferingManager;
/* Initialize our lists */
InitializeListHead(&AcceptedReqs);
InitializeListHead(DiscardedRequests);
/* Transfer the requests to dispatch locally */
BufferingManager = &SrvCall->BufferingManager;
KeAcquireSpinLock(&BufferingManager->SpinLock, &OldIrql);
RxTransferList(&DispatcherList, &BufferingManager->DispatcherList);
KeReleaseSpinLock(&BufferingManager->SpinLock, OldIrql);
/* If there were requests */
if (!IsListEmpty(&DispatcherList))
{
PLIST_ENTRY Entry;
/* For each of the entries... */
Entry = DispatcherList.Flink;
while (Entry != &DispatcherList)
{
PCHANGE_BUFFERING_STATE_REQUEST Request;
Request = CONTAINING_RECORD(Entry, CHANGE_BUFFERING_STATE_REQUEST, ListEntry);
Entry = Entry->Flink;
/* If we have been provided a SRV_OPEN, see whether it matches */
if (SrvOpen != NULL)
{
/* Match, the request is accepted */
if (Request->SrvOpenKey == SrvOpen->Key)
{
Request->SrvOpen = SrvOpen;
RxReferenceSrvOpen(SrvOpen);
RemoveEntryList(&Request->ListEntry);
InsertTailList(&AcceptedReqs, &Request->ListEntry);
/* Move to the next entry */
continue;
}
else
{
Status = STATUS_PENDING;
}
}
else
{
/* No SRV_OPEN provided, try to find one */
Status = RxpLookupSrvOpenForRequestLite(SrvCall, Request);
}
/* We found a matching SRV_OPEN, accept the request */
if (Status == STATUS_SUCCESS)
{
RemoveEntryList(&Request->ListEntry);
InsertTailList(&AcceptedReqs, &Request->ListEntry);
}
/* Another run might help handling it, don't discard it */
else if (Status == STATUS_PENDING)
{
continue;
}
/* Otherwise, discard the request */
else
{
ASSERT(Status == STATUS_NOT_FOUND);
RemoveEntryList(&Request->ListEntry);
InsertTailList(DiscardedRequests, &Request->ListEntry);
}
}
}
KeAcquireSpinLock(&BufferingManager->SpinLock, &OldIrql);
/* Nothing to dispatch, no need to start dispatcher */
if (IsListEmpty(&DispatcherList))
{
StartDispatcher = FALSE;
}
else
{
/* Transfer back the list of the not treated entries to the buffering manager */
RxTransferList(&BufferingManager->DispatcherList, &DispatcherList);
StartDispatcher = (BufferingManager->DispatcherActive == FALSE);
/* If the dispatcher isn't active, start it */
if (StartDispatcher)
{
BufferingManager->DispatcherActive = TRUE;
}
}
/* If there were accepted requests, move them to the buffering manager */
if (!IsListEmpty(&AcceptedReqs))
{
RxTransferList(&BufferingManager->HandlerList, &AcceptedReqs);
}
KeReleaseSpinLock(&BufferingManager->SpinLock, OldIrql);
/* If we're to start the dispatcher, do it */
if (StartDispatcher)
{
RxReferenceSrvCall(SrvCall);
DPRINT("Starting dispatcher\n");
RxPostToWorkerThread(RxFileSystemDeviceObject, HyperCriticalWorkQueue,
&BufferingManager->DispatcherWorkItem,
RxDispatchChangeBufferingStateRequests, SrvCall);
}
}
/*
* @implemented
*/
NTSTATUS
RxpLookupSrvOpenForRequestLite(
IN PSRV_CALL SrvCall,
IN OUT PCHANGE_BUFFERING_STATE_REQUEST Request)
{
NTSTATUS Status;
PLIST_ENTRY Entry;
PSRV_OPEN SrvOpen;
PAGED_CODE();
Status = STATUS_SUCCESS;
/* Browse all our associated SRV_OPENs to find the one! */
for (Entry = SrvCall->BufferingManager.SrvOpenLists[0].Flink;
Entry != &SrvCall->BufferingManager.SrvOpenLists[0];
Entry = Entry->Flink)
{
/* Same key, not orphaned, this is ours */
SrvOpen = CONTAINING_RECORD(Entry, SRV_OPEN, SrvOpenKeyList);
if (SrvOpen->Key == Request->SrvOpenKey)
{
if (!BooleanFlagOn(SrvOpen->pFcb->FcbState, FCB_STATE_ORPHANED))
{
RxReferenceSrvOpen(SrvOpen);
break;
}
}
}
/* We didn't manage to find a SRV_OPEN */
if (Entry == &SrvCall->BufferingManager.SrvOpenLists[0])
{
SrvOpen = NULL;
/* The coming open might help, mark as pending for later retry */
if (SrvCall->BufferingManager.NumberOfOutstandingOpens != 0)
{
Status = STATUS_PENDING;
}
/* Else, it's a complete failure */
else
{
Status = STATUS_NOT_FOUND;
}
}
/* Return the (not) found SRV_OPEN */
Request->SrvOpen = SrvOpen;
return Status;
}
/*
* @implemented
*/
VOID
RxpMarkInstanceForScavengedFinalization(
PVOID Instance)
{
NODE_TYPE_CODE NodeType;
PNODE_TYPE_AND_SIZE Node;
PRDBSS_SCAVENGER Scavenger;
PRDBSS_DEVICE_OBJECT DeviceObject;
PLIST_ENTRY ScavengerHead, InstEntry;
PAGED_CODE();
/* If still referenced, don't mark it (broken caller) */
Node = (PNODE_TYPE_AND_SIZE)Instance;
if (Node->NodeReferenceCount > 1)
{
return;
}
DeviceObject = RxGetDeviceObjectOfInstance(Instance);
Scavenger = DeviceObject->pRdbssScavenger;
/* Mark the node */
NodeType = NodeType(Instance);
SetFlag(NodeType(Node), RX_SCAVENGER_MASK);
DPRINT("Node %p has now the scavenger mark!\n", Instance);
/* Increase the count in the scavenger, and queue it */
ScavengerHead = NULL;
switch (NodeType)
{
case RDBSS_NTC_FOBX:
++Scavenger->FobxsToBeFinalized;
ScavengerHead = &Scavenger->FobxFinalizationList;
InstEntry = &((PFOBX)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_SRVCALL:
++Scavenger->SrvCallsToBeFinalized;
ScavengerHead = &Scavenger->SrvCallFinalizationList;
InstEntry = &((PSRV_CALL)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_NETROOT:
++Scavenger->NetRootsToBeFinalized;
ScavengerHead = &Scavenger->NetRootFinalizationList;
InstEntry = &((PNET_ROOT)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_V_NETROOT:
++Scavenger->VNetRootsToBeFinalized;
ScavengerHead = &Scavenger->VNetRootFinalizationList;
InstEntry = &((PV_NET_ROOT)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_SRVOPEN:
++Scavenger->SrvOpensToBeFinalized;
ScavengerHead = &Scavenger->SrvOpenFinalizationList;
InstEntry = &((PSRV_OPEN)Instance)->ScavengerFinalizationList;
break;
}
/* Extra ref for scavenger */
InterlockedIncrement((volatile long *)&Node->NodeReferenceCount);
/* If matching type */
if (ScavengerHead != NULL)
{
/* Insert in the scavenger list */
InsertTailList(ScavengerHead, InstEntry);
/* And if it wasn't started, start it */
if (Scavenger->State == RDBSS_SCAVENGER_INACTIVE)
{
Scavenger->State = RDBSS_SCAVENGER_DORMANT;
RxPostOneShotTimerRequest(RxFileSystemDeviceObject, &Scavenger->WorkItem,
RxScavengerTimerRoutine, DeviceObject, Scavenger->TimeLimit);
}
}
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RxPostOneShotTimerRequest(
IN PRDBSS_DEVICE_OBJECT pDeviceObject,
IN PRX_WORK_ITEM pWorkItem,
IN PRX_WORKERTHREAD_ROUTINE Routine,
IN PVOID pContext,
IN LARGE_INTEGER TimeInterval)
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
KIRQL OldIrql;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
ASSERT(pWorkItem != NULL);
/* Prepare the work item */
ExInitializeWorkItem(&pWorkItem->WorkQueueItem, Routine, pContext);
pWorkItem->WorkQueueItem.pDeviceObject = pDeviceObject;
/* Last tick can be computed with the number of times it was caller (timertickcount)
* and the interval between calls
*/
KeAcquireSpinLock(&RxTimerLock, &OldIrql);
pWorkItem->LastTick = (TimeInterval.QuadPart / 550000) + RxTimerTickCount + 1;
/* Insert in work queue */
InsertTailList(&RxTimerQueueHead, &pWorkItem->WorkQueueItem.List);
KeReleaseSpinLock(&RxTimerLock, OldIrql);
/* If there are queued events, queue an execution */
if (IsListEmpty(&RxTimerQueueHead))
{
KeSetTimer(&RxTimer, RxTimerInterval, &RxTimerDpc);
}
return STATUS_SUCCESS;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
}
/*
* @implemented
*/
NTSTATUS
NTAPI
RxPostToWorkerThread(
_In_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject,
_In_ WORK_QUEUE_TYPE WorkQueueType,
_In_ PRX_WORK_QUEUE_ITEM pWorkQueueItem,
_In_ PRX_WORKERTHREAD_ROUTINE Routine,
_In_ PVOID pContext)
{
/* Initialize work queue item */
pWorkQueueItem->List.Flink = NULL;
pWorkQueueItem->WorkerRoutine = Routine;
pWorkQueueItem->Parameter = pContext;
/* And insert it in the work queue */
return RxInsertWorkQueueItem(pMRxDeviceObject, WorkQueueType, pWorkQueueItem);
}
VOID
RxpProcessChangeBufferingStateRequests(
PSRV_CALL SrvCall,
BOOLEAN UpdateHandlerState)
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
PRX_PREFIX_ENTRY
RxPrefixTableInsertName(
IN OUT PRX_PREFIX_TABLE ThisTable,
IN OUT PRX_PREFIX_ENTRY ThisEntry,
IN PVOID Container,
IN PULONG ContainerRefCount,
IN USHORT CaseInsensitiveLength,
IN PRX_CONNECTION_ID ConnectionId
)
{
PAGED_CODE();
DPRINT("Insert: %wZ\n", &ThisEntry->Prefix);
ASSERT(RxIsPrefixTableLockExclusive(ThisTable));
ASSERT(CaseInsensitiveLength <= ThisEntry->Prefix.Length);
/* Copy parameters and compute hash */
ThisEntry->CaseInsensitiveLength = CaseInsensitiveLength;
ThisEntry->ContainingRecord = Container;
ThisEntry->ContainerRefCount = ContainerRefCount;
InterlockedIncrement((volatile long *)ContainerRefCount);
ThisEntry->SavedHashValue = RxTableComputeHashValue(&ThisEntry->Prefix);
DPRINT("Associated hash: %x\n", ThisEntry->SavedHashValue);
/* If no path length: this is entry for null path */
if (ThisEntry->Prefix.Length == 0)
{
ThisTable->TableEntryForNull = ThisEntry;
}
/* Otherwise, insert in the appropriate bucket */
else
{
InsertTailList(HASH_BUCKET(ThisTable, ThisEntry->SavedHashValue), &ThisEntry->HashLinks);
}
/* If we had a connection ID, keep track of it */
if (ConnectionId != NULL)
{
ThisEntry->ConnectionId.Luid = ConnectionId->Luid;
}
else
{
ThisEntry->ConnectionId.Luid.LowPart = 0;
ThisEntry->ConnectionId.Luid.HighPart = 0;
}
InsertTailList(&ThisTable->MemberQueue, &ThisEntry->MemberQLinks);
/* Reflect the changes */
++ThisTable->Version;
DPRINT("Inserted in bucket: %p\n", HASH_BUCKET(ThisTable, ThisEntry->SavedHashValue));
return ThisEntry;
}
/*
* @implemented
*/
PVOID
RxPrefixTableLookupName(
IN PRX_PREFIX_TABLE ThisTable,
IN PUNICODE_STRING CanonicalName,
OUT PUNICODE_STRING RemainingName,
IN PRX_CONNECTION_ID ConnectionId)
{
PVOID Container;
PAGED_CODE();
ASSERT(RxIsPrefixTableLockAcquired(ThisTable));
ASSERT(CanonicalName->Length > 0);
/* Call the internal helper */
Container = RxTableLookupName(ThisTable, CanonicalName, RemainingName, ConnectionId);
if (Container == NULL)
{
return NULL;
}
/* Reference our container before returning it */
if (RdbssReferenceTracingValue != 0)
{
NODE_TYPE_CODE Type;
Type = (NodeType(Container) & ~RX_SCAVENGER_MASK);
switch (Type)
{
case RDBSS_NTC_SRVCALL:
RxReferenceSrvCall(Container);
break;
case RDBSS_NTC_NETROOT:
RxReferenceNetRoot(Container);
break;
case RDBSS_NTC_V_NETROOT:
RxReferenceVNetRoot(Container);
break;
default:
DPRINT1("Invalid node type: %x\n", Type);
ASSERT(FALSE);
RxReference(Container);
break;
}
}
else
{
RxReference(Container);
}
return Container;
}
/*
* @implemented
*/
LONG
RxpReferenceNetFcb(
PFCB Fcb)
{
LONG NewCount;
PAGED_CODE();
ASSERT(NodeTypeIsFcb(Fcb));
NewCount = InterlockedIncrement((volatile long *)&Fcb->NodeReferenceCount);
PRINT_REF_COUNT(NETFCB, Fcb->NodeReferenceCount);
return NewCount;
}
/*
* @implemented
*/
VOID
RxpReleasePrefixTableLock(
PRX_PREFIX_TABLE pTable,
BOOLEAN ProcessBufferingStateChangeRequests)
{
PAGED_CODE();
DPRINT("RxpReleasePrefixTableLock(%p, %d) -> %d\n", pTable, ProcessBufferingStateChangeRequests,
pTable->TableLock.ActiveEntries);
ExReleaseResourceLite(&pTable->TableLock);
}
/*
* @implemented
*/
VOID
NTAPI
RxPrepareContextForReuse(
IN OUT PRX_CONTEXT RxContext)
{
PAGED_CODE();
/* When we reach that point, make sure mandatory parts are null-ed */
if (RxContext->MajorFunction == IRP_MJ_CREATE)
{
ASSERT(RxContext->Create.CanonicalNameBuffer == NULL);
RxContext->Create.RdrFlags = 0;
}
else if (RxContext->MajorFunction == IRP_MJ_READ || RxContext->MajorFunction == IRP_MJ_WRITE)
{
ASSERT(RxContext->RxContextSerializationQLinks.Flink == NULL);
ASSERT(RxContext->RxContextSerializationQLinks.Blink == NULL);
}
RxContext->ReferenceCount = 0;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxPrepareRequestForReuse(
PCHANGE_BUFFERING_STATE_REQUEST Request)
{
PSRV_OPEN SrvOpen;
PAGED_CODE();
SrvOpen = Request->SrvOpen;
/* If the request was already prepared for service */
if (BooleanFlagOn(Request->Flags, RX_REQUEST_PREPARED_FOR_HANDLING))
{
/* We have to dereference the associated SRV_OPEN depending on the lock */
if (RxIsFcbAcquiredExclusive(SrvOpen->pFcb))
{
RxDereferenceSrvOpen(SrvOpen, LHS_ExclusiveLockHeld);
}
else
{
RxDereferenceSrvOpen(SrvOpen, LHS_LockNotHeld);
}
}
/* Otherwise, just dereference */
else if (SrvOpen != NULL)
{
RxDereferenceSrvOpen(SrvOpen, LHS_LockNotHeld);
}
Request->SrvOpen = NULL;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
NTAPI
RxProcessChangeBufferingStateRequests(
_In_ PVOID SrvCall)
{
/* Call internal routine */
RxUndoScavengerFinalizationMarking(SrvCall);
RxpProcessChangeBufferingStateRequests(SrvCall, TRUE);
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxProcessChangeBufferingStateRequestsForSrvOpen(
PSRV_OPEN SrvOpen)
{
LONG NumberOfBufferingChangeRequests, LockedOldBufferingToken, OldBufferingToken;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Get the current number of change requests */
NumberOfBufferingChangeRequests = ((PSRV_CALL)SrvOpen->pVNetRoot->pNetRoot->pSrvCall)->BufferingManager.CumulativeNumberOfBufferingChangeRequests;
/* Get our old token */
OldBufferingToken = SrvOpen->BufferingToken;
LockedOldBufferingToken = InterlockedCompareExchange(&SrvOpen->BufferingToken,
NumberOfBufferingChangeRequests,
NumberOfBufferingChangeRequests);
/* If buffering state changed in between, process changes */
if (OldBufferingToken != LockedOldBufferingToken)
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
{
PFCB Fcb;
NTSTATUS Status;
/* Acquire the FCB and start processing */
Fcb = (PFCB)SrvOpen->pFcb;
Status = RxAcquireExclusiveFcb(NULL, Fcb);
if (Status == STATUS_SUCCESS)
{
RxProcessFcbChangeBufferingStateRequest(Fcb);
RxReleaseFcb(NULL, Fcb);
}
}
}
VOID
RxProcessFcbChangeBufferingStateRequest(
PFCB Fcb)
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
VOID
RxpScavengeFobxs(
PRDBSS_SCAVENGER Scavenger,
PLIST_ENTRY FobxToScavenge)
{
/* Explore the whole list of FOBX to scavenge */
while (!IsListEmpty(FobxToScavenge))
{
PFCB Fcb;
PFOBX Fobx;
PLIST_ENTRY Entry;
Entry = RemoveHeadList(FobxToScavenge);
Fobx = CONTAINING_RECORD(Entry, FOBX, ScavengerFinalizationList);
Fcb = (PFCB)Fobx->SrvOpen->pFcb;
/* Try to acquire the lock exclusively to perform finalization */
if (RxAcquireExclusiveFcb(NULL, Fcb) != STATUS_SUCCESS)
{
RxDereferenceNetRoot(Fobx, LHS_LockNotHeld);
}
else
{
RxReferenceNetFcb(Fcb);
RxDereferenceNetRoot(Fobx, LHS_ExclusiveLockHeld);
if (!RxDereferenceAndFinalizeNetFcb(Fcb, NULL, FALSE, FALSE))
{
RxReleaseFcb(NULL, Fcb);
}
}
}
}
BOOLEAN
RxpTrackDereference(
_In_ ULONG TraceType,
_In_ PCSTR FileName,
_In_ ULONG Line,
_In_ PVOID Instance)
{
PCSTR InstanceType;
ULONG ReferenceCount;
PAGED_CODE();
if (!BooleanFlagOn(RdbssReferenceTracingValue, TraceType))
{
return TRUE;
}
switch (TraceType)
{
case RDBSS_REF_TRACK_SRVCALL:
InstanceType = "SrvCall";
ReferenceCount = ((PSRV_CALL)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_NETROOT:
InstanceType = "NetRoot";
ReferenceCount = ((PNET_ROOT)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_VNETROOT:
InstanceType = "VNetRoot";
ReferenceCount = ((PV_NET_ROOT)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_NETFOBX:
InstanceType = "NetFobx";
ReferenceCount = ((PFOBX)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_NETFCB:
InstanceType = "NetFcb";
ReferenceCount = ((PFCB)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_SRVOPEN:
InstanceType = "SrvOpen";
ReferenceCount = ((PSRV_OPEN)Instance)->NodeReferenceCount;
break;
default:
DPRINT1("Invalid node type!\n");
return TRUE;
}
if (BooleanFlagOn(RdbssReferenceTracingValue, RX_LOG_REF_TRACKING))
{
UNIMPLEMENTED;
}
if (BooleanFlagOn(RdbssReferenceTracingValue, RX_PRINT_REF_TRACKING))
{
DbgPrint("(%s:%d) %p (%s) dereferenced from %d\n", FileName, Line, Instance, InstanceType, ReferenceCount);
}
return TRUE;
}
VOID
RxpTrackReference(
_In_ ULONG TraceType,
_In_ PCSTR FileName,
_In_ ULONG Line,
_In_ PVOID Instance)
{
PCSTR InstanceType;
ULONG ReferenceCount;
if (!BooleanFlagOn(RdbssReferenceTracingValue, TraceType))
{
return;
}
switch (TraceType)
{
case RDBSS_REF_TRACK_SRVCALL:
InstanceType = "SrvCall";
ReferenceCount = ((PSRV_CALL)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_NETROOT:
InstanceType = "NetRoot";
ReferenceCount = ((PNET_ROOT)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_VNETROOT:
InstanceType = "VNetRoot";
ReferenceCount = ((PV_NET_ROOT)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_NETFOBX:
InstanceType = "NetFobx";
ReferenceCount = ((PFOBX)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_NETFCB:
InstanceType = "NetFcb";
ReferenceCount = ((PFCB)Instance)->NodeReferenceCount;
break;
case RDBSS_REF_TRACK_SRVOPEN:
InstanceType = "SrvOpen";
ReferenceCount = ((PSRV_OPEN)Instance)->NodeReferenceCount;
break;
default:
DPRINT1("Invalid node type!\n");
return;
}
if (BooleanFlagOn(RdbssReferenceTracingValue, RX_LOG_REF_TRACKING))
{
UNIMPLEMENTED;
}
if (BooleanFlagOn(RdbssReferenceTracingValue, RX_PRINT_REF_TRACKING))
{
DbgPrint("(%s:%d) %p (%s) referenced from %d\n", FileName, Line, Instance, InstanceType, ReferenceCount);
}
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxpUndoScavengerFinalizationMarking(
PVOID Instance)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PLIST_ENTRY ListEntry;
PNODE_TYPE_AND_SIZE Node;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
PRDBSS_SCAVENGER Scavenger;
PAGED_CODE();
Node = (PNODE_TYPE_AND_SIZE)Instance;
/* There's no marking - nothing to do */
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
if (!BooleanFlagOn(NodeType(Node), RX_SCAVENGER_MASK))
{
return;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* First of all, remove the mark */
ClearFlag(NodeType(Node), RX_SCAVENGER_MASK);
DPRINT("Node %p no longer has the scavenger mark\n");
/* And now, remove from the scavenger */
Scavenger = RxGetDeviceObjectOfInstance(Instance)->pRdbssScavenger;
switch (NodeType(Node))
{
case RDBSS_NTC_FOBX:
--Scavenger->FobxsToBeFinalized;
ListEntry = &((PFOBX)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_SRVCALL:
--Scavenger->SrvCallsToBeFinalized;
ListEntry = &((PSRV_CALL)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_NETROOT:
--Scavenger->NetRootsToBeFinalized;
ListEntry = &((PNET_ROOT)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_V_NETROOT:
--Scavenger->VNetRootsToBeFinalized;
ListEntry = &((PV_NET_ROOT)Instance)->ScavengerFinalizationList;
break;
case RDBSS_NTC_SRVOPEN:
--Scavenger->SrvOpensToBeFinalized;
ListEntry = &((PSRV_OPEN)Instance)->ScavengerFinalizationList;
break;
default:
return;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
}
/* Also, remove the extra ref from the scavenger */
RemoveEntryList(ListEntry);
InterlockedDecrement((volatile long *)&Node->NodeReferenceCount);
}
/*
* @implemented
*/
VOID
RxPurgeChangeBufferingStateRequestsForSrvOpen(
PSRV_OPEN SrvOpen)
{
PSRV_CALL SrvCall;
LIST_ENTRY Discarded;
PAGED_CODE();
ASSERT(RxIsFcbAcquiredExclusive(SrvOpen->Fcb));
/* Initialize our discarded list */
InitializeListHead(&Discarded);
SrvCall = (PSRV_CALL)SrvOpen->Fcb->VNetRoot->pNetRoot->pSrvCall;
RxAcquireBufferingManagerMutex(&SrvCall->BufferingManager);
/* Set the flag, and get the requests */
InitializeListHead(&SrvOpen->SrvOpenKeyList);
SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_REQUESTS_PURGED);
RxGatherRequestsForSrvOpen(SrvCall, SrvOpen, &Discarded);
RxReleaseBufferingManagerMutex(&SrvCall->BufferingManager);
/* If there were discarded requests */
if (!IsListEmpty(&Discarded))
{
/* And a pending buffering state change */
if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING))
{
/* Clear the flag, and set the associated event - job done */
RxAcquireSerializationMutex();
ClearFlag(SrvOpen->Fcb->FcbState, FCB_STATE_BUFFERING_STATE_CHANGE_PENDING);
if (SrvOpen->Fcb->pBufferingStateChangeCompletedEvent != NULL)
{
KeSetEvent(SrvOpen->Fcb->pBufferingStateChangeCompletedEvent, IO_NETWORK_INCREMENT, FALSE);
}
RxReleaseSerializationMutex();
}
/* Drop the discarded requests */
RxpDiscardChangeBufferingStateRequests(&Discarded);
}
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
RxPurgeFcb(
IN PFCB Fcb)
{
PAGED_CODE();
ASSERT(RxIsFcbAcquiredExclusive(Fcb));
/* Reference our FCB so that it doesn't disappear */
RxReferenceNetFcb(Fcb);
/* Purge Cc if required */
if (Fcb->OpenCount != 0)
{
RxPurgeFcbInSystemCache(Fcb, NULL, 0, TRUE, TRUE);
}
/* If it wasn't freed, release the lock */
if (!RxDereferenceAndFinalizeNetFcb(Fcb, NULL, FALSE, FALSE))
{
RxReleaseFcb(NULL, Fcb);
}
}
/*
* @implemented
*/
NTSTATUS
RxPurgeFcbInSystemCache(
IN PFCB Fcb,
IN PLARGE_INTEGER FileOffset OPTIONAL,
IN ULONG Length,
IN BOOLEAN UninitializeCacheMaps,
IN BOOLEAN FlushFile)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
BOOLEAN Purged;
NTSTATUS Status;
PAGED_CODE();
ASSERT(RxIsFcbAcquiredExclusive(Fcb));
/* Try to flush first, if asked */
if (FlushFile)
{
/* If flushing failed, just make some noise */
Status = RxFlushFcbInSystemCache(Fcb, TRUE);
if (!NT_SUCCESS(Status))
{
PVOID CallersAddress, CallersCaller;
RtlGetCallersAddress(&CallersAddress, &CallersCaller);
DPRINT1("Flush failed with status %lx for FCB %p\n", Status, Fcb);
DPRINT1("Caller was %p %p\n", CallersAddress, CallersCaller);
}
}
/* Deal with Cc for purge */
Purged = CcPurgeCacheSection(&Fcb->NonPaged->SectionObjectPointers, FileOffset,
Length, UninitializeCacheMaps);
/* If purge failed, force section closing */
if (!Purged)
{
MmFlushImageSection(&Fcb->NonPaged->SectionObjectPointers, MmFlushForWrite);
RxReleaseFcb(NULL, Fcb);
Purged = MmForceSectionClosed(&Fcb->NonPaged->SectionObjectPointers, TRUE);
RxAcquireExclusiveFcb(NULL, Fcb);
}
/* Return appropriate status */
Status = (Purged ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
DPRINT("Purge for FCB %p returns %lx\n", Fcb, Status);
return Status;
}
/*
* @implemented
*/
BOOLEAN
RxPurgeFobx(
PFOBX pFobx)
{
NTSTATUS Status;
PFCB FcbToBePurged;
PAGED_CODE();
/* Get the associated FCB */
FcbToBePurged = (PFCB)pFobx->pSrvOpen->pFcb;
Status = RxAcquireExclusiveFcb(NULL, FcbToBePurged);
ASSERT(Status == STATUS_SUCCESS);
/* Purge it */
Status = RxPurgeFcbInSystemCache(FcbToBePurged, NULL, 0, FALSE, TRUE);
if (Status != STATUS_SUCCESS)
{
DPRINT1("Purge failed for %p (%p)\n", FcbToBePurged, pFobx);
return FALSE;
}
/* And flush */
if (!MmFlushImageSection(&FcbToBePurged->NonPaged->SectionObjectPointers, MmFlushForWrite))
{
DPRINT1("Image section flush failed for %p (%p)\n", FcbToBePurged, pFobx);
return FALSE;
}
DPRINT("Purge OK for %p (%p)\n", FcbToBePurged, pFobx);
return TRUE;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
NTSTATUS
RxPurgeFobxFromCache(
PFOBX FobxToBePurged)
{
NTSTATUS Status;
PFCB FcbToBePurged;
PAGED_CODE();
FcbToBePurged = (PFCB)FobxToBePurged->pSrvOpen->pFcb;
ASSERT(FcbToBePurged != NULL);
/* If we cannot have our FCB exclusively, give up */
Status = RxAcquireExclusiveFcb(NULL, FcbToBePurged);
if (Status != STATUS_SUCCESS)
{
RxDereferenceNetFobx(FobxToBePurged, LHS_LockNotHeld);
return Status;
}
/* Don't let the FCB disappear */
RxReferenceNetFcb(FcbToBePurged);
/* If the SRV_OPEN was already closed, or if there are unclean FOBX, give up */
if (BooleanFlagOn(FobxToBePurged->Flags, FOBX_FLAG_SRVOPEN_CLOSED) || FobxToBePurged->pSrvOpen->UncleanFobxCount != 0)
{
DPRINT("FCB purge skipped\n");
}
else
{
Status = RxPurgeFcbInSystemCache(FcbToBePurged, NULL, 0, FALSE, TRUE);
}
RxDereferenceNetFobx(FobxToBePurged, LHS_ExclusiveLockHeld);
/* Drop our extra reference */
if (!RxDereferenceAndFinalizeNetFcb(FcbToBePurged, NULL, FALSE, FALSE))
{
RxReleaseFcb(NULL, FcbToBePurged);
}
return Status;
}
/*
* @implemented
*/
NTSTATUS
RxPurgeRelatedFobxs(
PNET_ROOT NetRoot,
PRX_CONTEXT RxContext,
BOOLEAN AttemptFinalization,
PFCB PurgingFcb)
{
PLIST_ENTRY Entry;
ULONG SuccessfullPurge;
PRDBSS_SCAVENGER Scavenger;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncCtx;
PAGED_CODE();
RxDeviceObject = RxContext->RxDeviceObject;
Scavenger = RxDeviceObject->pRdbssScavenger;
PurgeSyncCtx = &NetRoot->PurgeSyncronizationContext;
RxAcquireScavengerMutex();
/* If there's already a purge in progress */
if (PurgeSyncCtx->PurgeInProgress)
{
/* Add our RX_CONTEXT to the current run */
InsertTailList(&PurgeSyncCtx->ContextsAwaitingPurgeCompletion,
&RxContext->RxContextSerializationQLinks);
/* And wait until it's done */
RxReleaseScavengerMutex();
RxWaitSync(RxContext);
RxAcquireScavengerMutex();
}
/* Start the purge */
PurgeSyncCtx->PurgeInProgress = TRUE;
/* While the purge is still handling our NET_ROOT, do nothing but wait */
while (Scavenger->CurrentNetRootForClosePendingProcessing == NetRoot)
{
RxReleaseScavengerMutex();
KeWaitForSingleObject(&Scavenger->ClosePendingProcessingSyncEvent, Executive,
KernelMode, TRUE, NULL);
RxAcquireScavengerMutex();
}
/* Now, for all the entries */
SuccessfullPurge = 0;
Entry = Scavenger->ClosePendingFobxsList.Flink;
while (Entry != &Scavenger->ClosePendingFobxsList)
{
PFCB Fcb;
PFOBX Fobx;
BOOLEAN Success;
Fobx = CONTAINING_RECORD(Entry, FOBX, ClosePendingList);
DPRINT("Dealing with FOBX: %p\n", Fobx);
Entry = Entry->Flink;
/* If it's not matching our NET_ROOT, ignore */
if (Fobx->pSrvOpen == NULL ||
Fobx->pSrvOpen->pFcb == NULL ||
((PFCB)Fobx->pSrvOpen->pFcb)->VNetRoot == NULL ||
(PNET_ROOT)((PFCB)Fobx->pSrvOpen->pFcb)->VNetRoot->pNetRoot != NetRoot)
{
continue;
}
/* Determine if it matches our FCB */
Fcb = (PFCB)Fobx->pSrvOpen->pFcb;
if (PurgingFcb != NULL && NodeType(PurgingFcb) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY &&
PurgingFcb != Fcb)
{
NTSTATUS Status;
MINIRDR_CALL_THROUGH(Status, RxDeviceObject->Dispatch, MRxAreFilesAliased, (Fcb, PurgingFcb));
if (Status == STATUS_SUCCESS)
{
continue;
}
}
/* Matching, we'll purge it */
RemoveEntryList(&Fobx->ClosePendingList);
/* Reference it so that it doesn't disappear */
RxReferenceNetFobx(Fobx);
RxReleaseScavengerMutex();
/* And purge */
Success = RxPurgeFobx(Fobx);
if (Success)
{
++SuccessfullPurge;
}
/* If we don't have to finalize it (or if we cannot acquire lock exclusively
* Just normally dereference
*/
if ((AttemptFinalization == DONT_ATTEMPT_FINALIZE_ON_PURGE) ||
RxAcquireExclusiveFcb(NULL, Fcb) != STATUS_SUCCESS)
{
RxDereferenceNetFobx(Fobx, LHS_LockNotHeld);
}
/* Otherwise, finalize */
else
{
RxReferenceNetFcb(Fcb);
RxDereferenceNetFobx(Fobx, LHS_ExclusiveLockHeld);
if (!RxDereferenceAndFinalizeNetFcb(Fcb, NULL, FALSE, FALSE))
{
RxReleaseFcb(NULL, Fcb);
}
}
if (!Success)
{
DPRINT1("Failed purging %p (%p)\n", Fcb, Fobx);
}
RxAcquireScavengerMutex();
}
/* If no contexts left, purge is not running */
if (IsListEmpty(&PurgeSyncCtx->ContextsAwaitingPurgeCompletion))
{
PurgeSyncCtx->PurgeInProgress = FALSE;
}
/* Otherwise, notify a waiter it can start */
else
{
PRX_CONTEXT Context;
Entry = RemoveHeadList(&PurgeSyncCtx->ContextsAwaitingPurgeCompletion);
Context = CONTAINING_RECORD(Entry, RX_CONTEXT, RxContextSerializationQLinks);
RxSignalSynchronousWaiter(Context);
}
RxReleaseScavengerMutex();
return (SuccessfullPurge > 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
}
/*
* @implemented
*/
VOID
RxpWorkerThreadDispatcher(
IN PRX_WORK_QUEUE WorkQueue,
IN PLARGE_INTEGER WaitInterval)
{
NTSTATUS Status;
PVOID Parameter;
PETHREAD CurrentThread;
BOOLEAN KillThread, Dereference;
PRX_WORK_QUEUE_ITEM WorkQueueItem;
PWORKER_THREAD_ROUTINE WorkerRoutine;
InterlockedIncrement(&WorkQueue->NumberOfIdleWorkerThreads);
/* Reference ourselves */
CurrentThread = PsGetCurrentThread();
Status = ObReferenceObjectByPointer(CurrentThread, THREAD_ALL_ACCESS, *PsThreadType, KernelMode);
ASSERT(NT_SUCCESS(Status));
/* Infinite loop for worker */
KillThread = FALSE;
Dereference = FALSE;
do
{
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
/* Remove an entry from the work queue */
ListEntry = KeRemoveQueue(&WorkQueue->Queue, KernelMode, WaitInterval);
if ((ULONG_PTR)ListEntry != STATUS_TIMEOUT)
{
PRDBSS_DEVICE_OBJECT DeviceObject;
WorkQueueItem = CONTAINING_RECORD(ListEntry, RX_WORK_QUEUE_ITEM, List);
InterlockedIncrement(&WorkQueue->NumberOfWorkItemsDispatched);
InterlockedDecrement(&WorkQueue->NumberOfWorkItemsToBeDispatched);
InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
/* Get the parameters, and null-them in the struct */
WorkerRoutine = WorkQueueItem->WorkerRoutine;
Parameter = WorkQueueItem->Parameter;
DeviceObject = WorkQueueItem->pDeviceObject;
WorkQueueItem->List.Flink = NULL;
WorkQueueItem->WorkerRoutine = NULL;
WorkQueueItem->Parameter = NULL;
WorkQueueItem->pDeviceObject = NULL;
/* Call the routine */
DPRINT("Calling: %p(%p)\n", WorkerRoutine, Parameter);
WorkerRoutine(Parameter);
/* Are we going down now? */
if (InterlockedDecrement(&DeviceObject->DispatcherContext.NumberOfWorkerThreads) == 0)
{
PKEVENT TearDownEvent;
TearDownEvent = InterlockedExchangePointer((void * volatile*)&DeviceObject->DispatcherContext.pTearDownEvent, NULL);
if (TearDownEvent != NULL)
{
KeSetEvent(TearDownEvent, IO_NO_INCREMENT, FALSE);
}
}
InterlockedIncrement(&WorkQueue->NumberOfIdleWorkerThreads);
}
/* Shall we shutdown... */
KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
switch (WorkQueue->State)
{
/* Our queue is active, kill it if we have no more items to dispatch
* and more threads than the required minimum
*/
case RxWorkQueueActive:
if (WorkQueue->NumberOfWorkItemsToBeDispatched <= 0)
{
ASSERT(WorkQueue->NumberOfActiveWorkerThreads > 0);
if (WorkQueue->NumberOfActiveWorkerThreads > WorkQueue->MinimumNumberOfWorkerThreads)
{
KillThread = TRUE;
Dereference = TRUE;
InterlockedDecrement(&WorkQueue->NumberOfActiveWorkerThreads);
}
if (KillThread)
{
InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
}
}
break;
/* The queue is inactive: kill it we have more threads than the required minimum */
case RxWorkQueueInactive:
ASSERT(WorkQueue->NumberOfActiveWorkerThreads > 0);
if (WorkQueue->NumberOfActiveWorkerThreads > WorkQueue->MinimumNumberOfWorkerThreads)
{
KillThread = TRUE;
Dereference = TRUE;
InterlockedDecrement(&WorkQueue->NumberOfActiveWorkerThreads);
}
if (KillThread)
{
InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
}
break;
/* Rundown in progress..., kill it for sure! */
case RxWorkQueueRundownInProgress:
{
PRX_WORK_QUEUE_RUNDOWN_CONTEXT RundownContext;
ASSERT(WorkQueue->pRundownContext != NULL);
RundownContext = WorkQueue->pRundownContext;
RundownContext->ThreadPointers[RundownContext->NumberOfThreadsSpunDown++] = CurrentThread;
InterlockedDecrement(&WorkQueue->NumberOfActiveWorkerThreads);
KillThread = TRUE;
Dereference = FALSE;
if (WorkQueue->NumberOfActiveWorkerThreads == 0)
{
KeSetEvent(&RundownContext->RundownCompletionEvent, IO_NO_INCREMENT, FALSE);
}
InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
}
break;
default:
break;
}
KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
} while (!KillThread);
DPRINT("Killed worker thread\n");
/* Do we have to dereference ourselves? */
if (Dereference)
{
ObDereferenceObject(CurrentThread);
}
/* Dump last executed routine */
if (DumpDispatchRoutine)
{
DPRINT("Dispatch routine %p(%p) taken from %p\n", WorkerRoutine, Parameter, WorkQueueItem);
}
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID
RxReference(
IN OUT PVOID Instance)
{
NODE_TYPE_CODE NodeType;
PNODE_TYPE_AND_SIZE Node;
PAGED_CODE();
RxAcquireScavengerMutex();
/* We can only reference a few structs */
NodeType = NodeType(Instance) & ~RX_SCAVENGER_MASK;
ASSERT((NodeType == RDBSS_NTC_SRVCALL) || (NodeType == RDBSS_NTC_NETROOT) ||
(NodeType == RDBSS_NTC_V_NETROOT) || (NodeType == RDBSS_NTC_SRVOPEN) ||
(NodeType == RDBSS_NTC_FOBX));
Node = (PNODE_TYPE_AND_SIZE)Instance;
InterlockedIncrement((volatile long *)&Node->NodeReferenceCount);
/* Trace refcount if asked */
switch (NodeType)
{
case RDBSS_NTC_SRVCALL:
PRINT_REF_COUNT(SRVCALL, Node->NodeReferenceCount);
break;
case RDBSS_NTC_NETROOT:
PRINT_REF_COUNT(NETROOT, Node->NodeReferenceCount);
break;
case RDBSS_NTC_V_NETROOT:
PRINT_REF_COUNT(VNETROOT, Node->NodeReferenceCount);
break;
case RDBSS_NTC_SRVOPEN:
PRINT_REF_COUNT(SRVOPEN, Node->NodeReferenceCount);
break;
case RDBSS_NTC_FOBX:
PRINT_REF_COUNT(NETFOBX, Node->NodeReferenceCount);
break;
default:
ASSERT(FALSE);
break;
}
RxpUndoScavengerFinalizationMarking(Instance);
RxReleaseScavengerMutex();
}
/*
* @implemented
*/
VOID
NTAPI
RxReinitializeContext(
IN OUT PRX_CONTEXT RxContext)
{
PIRP Irp;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
ULONG InitialContextFlags, SavedFlags;
PAGED_CODE();
/* Backup a few flags */
Irp = RxContext->CurrentIrp;
RxDeviceObject = RxContext->RxDeviceObject;
SavedFlags = RxContext->Flags & RX_CONTEXT_PRESERVED_FLAGS;
InitialContextFlags = RxContext->Flags & RX_CONTEXT_INITIALIZATION_FLAGS;
/* Reset our context */
RxPrepareContextForReuse(RxContext);
/* Zero everything */
RtlZeroMemory(&RxContext->MajorFunction, sizeof(RX_CONTEXT) - FIELD_OFFSET(RX_CONTEXT, MajorFunction));
/* Restore saved flags */
RxContext->Flags = SavedFlags;
/* And reinit the context */
RxInitializeContext(Irp, RxDeviceObject, InitialContextFlags, RxContext);
}
/*
* @implemented
*/
VOID
NTAPI
RxReleaseFcbFromLazyWrite(
PVOID Context)
{
PFCB Fcb;
PAGED_CODE();
Fcb = Context;
/* The received context is a FCB */
ASSERT(NodeType(Fcb) == RDBSS_NTC_FCB);
ASSERT_CORRECT_FCB_STRUCTURE(Fcb);
/* Lazy writer is releasing lock, so forget about it */
Fcb->Specific.Fcb.LazyWriteThread = NULL;
/* If we were top level IRP, unwind */
if (RxGetTopIrpIfRdbssIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
{
RxUnwindTopLevelIrp(NULL);
}
/* And finally, release the lock */
Fcb->PagingIoResourceFile = NULL;
Fcb->PagingIoResourceLine = 0;
ExReleaseResourceLite(Fcb->Header.PagingIoResource);
}
/*
* @implemented
*/
VOID
NTAPI
RxReleaseFcbFromReadAhead(
PVOID Context)
{
PFCB Fcb;
PAGED_CODE();
Fcb = Context;
/* The received context is a FCB */
ASSERT(NodeType(Fcb) == RDBSS_NTC_FCB);
ASSERT_CORRECT_FCB_STRUCTURE(Fcb);
/* Top Level IRP is CC */
ASSERT(RxGetTopIrpIfRdbssIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
RxUnwindTopLevelIrp(NULL);
ExReleaseResourceLite(Fcb->Header.Resource);
}
VOID
NTAPI
RxReleaseFileForNtCreateSection(
PFILE_OBJECT FileObject)
{
UNIMPLEMENTED;
}
NTSTATUS
NTAPI
RxReleaseForCcFlush(
PFILE_OBJECT FileObject,
PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
RxRemoveNameNetFcb(
OUT PFCB ThisFcb)
{
PNET_ROOT NetRoot;
PAGED_CODE();
ASSERT(NodeTypeIsFcb(ThisFcb));
/* Just remove the entry from the FCB_TABLE */
NetRoot = (PNET_ROOT)ThisFcb->VNetRoot->pNetRoot;
ASSERT(RxIsFcbTableLockExclusive(&NetRoot->FcbTable));
ASSERT(RxIsFcbAcquiredExclusive(ThisFcb));
#ifdef __REACTOS__
if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_NAME_ALREADY_REMOVED))
{
#endif
RxFcbTableRemoveFcb(&NetRoot->FcbTable, ThisFcb);
DPRINT("FCB (%p) %wZ removed\n", ThisFcb, &ThisFcb->FcbTableEntry.Path);
/* Mark, so that we don't try to do it twice */
SetFlag(ThisFcb->FcbState, FCB_STATE_NAME_ALREADY_REMOVED);
#ifdef __REACTOS__
}
#endif
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
}
/*
* @implemented
*/
VOID
RxRemoveOperationFromBlockingQueue(
IN OUT PRX_CONTEXT RxContext)
{
/* Acquire the pipe mutex */
ExAcquireFastMutex(&RxContextPerFileSerializationMutex);
/* Is that a blocking serial operation? */
if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
{
/* Clear it! */
ClearFlag(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION);
/* Drop it off the list */
RemoveEntryList(&RxContext->RxContextSerializationQLinks);
RxContext->RxContextSerializationQLinks.Flink = NULL;
RxContext->RxContextSerializationQLinks.Blink = NULL;
}
/* Done */
ExReleaseFastMutex(&RxContextPerFileSerializationMutex);
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
RxRemovePrefixTableEntry(
IN OUT PRX_PREFIX_TABLE ThisTable,
IN OUT PRX_PREFIX_ENTRY Entry)
{
PAGED_CODE();
ASSERT(NodeType(Entry) == RDBSS_NTC_PREFIX_ENTRY);
ASSERT(RxIsPrefixTableLockExclusive(ThisTable));
/* Check whether we're asked to remove null entry */
if (Entry->Prefix.Length == 0)
{
ThisTable->TableEntryForNull = NULL;
}
else
{
RemoveEntryList(&Entry->HashLinks);
}
Entry->ContainingRecord = NULL;
/* Also remove it from global list */
RemoveEntryList(&Entry->MemberQLinks);
++ThisTable->Version;
}
/*
* @implemented
*/
VOID
RxRemoveVirtualNetRootFromNetRoot(
PNET_ROOT NetRoot,
PV_NET_ROOT VNetRoot)
{
PRX_PREFIX_TABLE PrefixTable;
PAGED_CODE();
PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
/* Remove the VNetRoot from the list in the NetRoot */
--NetRoot->NumberOfVirtualNetRoots;
RemoveEntryList(&VNetRoot->NetRootListEntry);
/* Fix the NetRoot if we were the default VNetRoot */
if (NetRoot->DefaultVNetRoot == VNetRoot)
{
/* Put the first one available */
if (!IsListEmpty(&NetRoot->VirtualNetRoots))
{
NetRoot->DefaultVNetRoot = CONTAINING_RECORD(NetRoot->VirtualNetRoots.Flink, V_NET_ROOT, NetRootListEntry);
}
/* Otherwise, none */
else
{
NetRoot->DefaultVNetRoot = NULL;
}
}
/* If there are still other VNetRoot available, we're done */
if (!IsListEmpty(&NetRoot->VirtualNetRoots))
{
return;
}
/* Otherwise, initiate NetRoot finalization */
if (!BooleanFlagOn(NetRoot->Flags, NETROOT_FLAG_NAME_ALREADY_REMOVED))
{
RxRemovePrefixTableEntry(PrefixTable, &NetRoot->PrefixEntry);
SetFlag(NetRoot->Flags, NETROOT_FLAG_NAME_ALREADY_REMOVED);
}
/* Notify mini-rdr */
if (NetRoot->pSrvCall != NULL && NetRoot->pSrvCall->RxDeviceObject != NULL)
{
NTSTATUS Status;
MINIRDR_CALL_THROUGH(Status, NetRoot->pSrvCall->RxDeviceObject->Dispatch,
MRxFinalizeNetRoot, ((PMRX_NET_ROOT)NetRoot, FALSE));
(void)Status;
}
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
VOID
RxResumeBlockedOperations_ALL(
IN OUT PRX_CONTEXT RxContext)
{
LIST_ENTRY BlockedOps;
PAGED_CODE();
/* Get the blocked operations */
RxTransferListWithMutex(&BlockedOps, &RxContext->BlockedOperations, RxContext->BlockedOpsMutex);
if (!IsListEmpty(&BlockedOps))
{
UNIMPLEMENTED;
}
}
VOID
NTAPI
RxResumeBlockedOperations_Serially(
IN OUT PRX_CONTEXT RxContext,
IN OUT PLIST_ENTRY BlockingIoQ)
{
PAGED_CODE();
RxAcquireSerializationMutex();
/* This can only happen on pipes */
if (!BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
{
RxReleaseSerializationMutex();
return;
}
UNIMPLEMENTED;
RxReleaseSerializationMutex();
}
/*
* @implemented
*/
VOID
RxSetFileSizeWithLock(
IN OUT PFCB Fcb,
IN PLONGLONG FileSize)
{
PAGED_CODE();
/* Set attribute and increase version */
Fcb->Header.FileSize.QuadPart = *FileSize;
++Fcb->ulFileSizeVersion;
}
/*
* @implemented
*/
VOID
RxScavengeFobxsForNetRoot(
PNET_ROOT NetRoot,
PFCB PurgingFcb,
BOOLEAN SynchronizeWithScavenger)
{
PRDBSS_SCAVENGER Scavenger;
PRDBSS_DEVICE_OBJECT RxDeviceObject;
PAGED_CODE();
RxDeviceObject = NetRoot->pSrvCall->RxDeviceObject;
Scavenger = RxDeviceObject->pRdbssScavenger;
/* Wait for the scavenger, if asked to */
if (SynchronizeWithScavenger)
{
KeWaitForSingleObject(&Scavenger->ScavengeEvent, Executive, KernelMode, FALSE, NULL);
}
RxAcquireScavengerMutex();
/* If there's nothing left to do... */
if (Scavenger->FobxsToBeFinalized <= 0)
{
RxReleaseScavengerMutex();
}
else
{
PLIST_ENTRY Entry;
LIST_ENTRY FobxToScavenge;
InitializeListHead(&FobxToScavenge);
/* Browse all the FOBXs to finalize */
Entry = Scavenger->FobxFinalizationList.Flink;
while (Entry != &Scavenger->FobxFinalizationList)
{
PFOBX Fobx;
Fobx = CONTAINING_RECORD(Entry, FOBX, ScavengerFinalizationList);
Entry = Entry->Flink;
if (Fobx->SrvOpen != NULL)
{
PFCB Fcb;
Fcb = (PFCB)Fobx->SrvOpen->pFcb;
/* If it matches our NET_ROOT */
if ((PNET_ROOT)Fcb->pNetRoot == NetRoot)
{
NTSTATUS Status;
/* Check whether it matches our FCB */
Status = STATUS_MORE_PROCESSING_REQUIRED;
if (PurgingFcb != NULL && PurgingFcb != Fcb)
{
MINIRDR_CALL_THROUGH(Status, RxDeviceObject->Dispatch, MRxAreFilesAliased, (Fcb, PurgingFcb));
}
/* If so, add it to the list of the FOBXs to scavenge */
if (Status != STATUS_SUCCESS)
{
RxReferenceNetFobx(Fobx);
ASSERT(NodeType(Fobx) == RDBSS_NTC_FOBX);
RemoveEntryList(&Fobx->ScavengerFinalizationList);
InsertTailList(&FobxToScavenge, &Fobx->ScavengerFinalizationList);
}
}
}
}
RxReleaseScavengerMutex();
/* Now, scavenge all the extracted FOBX */
RxpScavengeFobxs(Scavenger, &FobxToScavenge);
}
if (SynchronizeWithScavenger)
{
KeSetEvent(&Scavenger->ScavengeEvent, IO_NO_INCREMENT, FALSE);
}
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
BOOLEAN
RxScavengeRelatedFobxs(
PFCB Fcb)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PFOBX Fobx;
LIST_ENTRY LocalList;
PLIST_ENTRY NextEntry;
PRDBSS_SCAVENGER Scavenger;
PAGED_CODE();
/* First of all, check whether there are FOBX to scavenge */
Scavenger = Fcb->RxDeviceObject->pRdbssScavenger;
RxAcquireScavengerMutex();
if (Scavenger->FobxsToBeFinalized <= 0)
{
RxReleaseScavengerMutex();
return FALSE;
}
/* Initialize our local list which will hold all the FOBX to scavenge so
* that we don't acquire the scavenger mutex too long
*/
InitializeListHead(&LocalList);
/* Technically, that condition should all be true... */
if (!IsListEmpty(&Scavenger->FobxFinalizationList))
{
PLIST_ENTRY NextEntry, LastEntry;
/* Browse all the FCBs to find the matching ones */
NextEntry = Scavenger->FobxFinalizationList.Flink;
LastEntry = &Scavenger->FobxFinalizationList;
while (NextEntry != LastEntry)
{
Fobx = CONTAINING_RECORD(NextEntry, FOBX, ScavengerFinalizationList);
NextEntry = NextEntry->Flink;
/* Matching our FCB? Let's finalize it */
if (Fobx->pSrvOpen != NULL && Fobx->pSrvOpen->pFcb == RX_GET_MRX_FCB(Fcb))
{
RxpUndoScavengerFinalizationMarking(Fobx);
ASSERT(NodeType(Fobx) == RDBSS_NTC_FOBX);
InsertTailList(&LocalList, &Fobx->ScavengerFinalizationList);
}
}
}
RxReleaseScavengerMutex();
/* Nothing to scavenge? Quit */
if (IsListEmpty(&LocalList))
{
return FALSE;
}
/* Now, finalize all the extracted FOBX */
while (!IsListEmpty(&LocalList))
{
NextEntry = RemoveHeadList(&LocalList);
Fobx = CONTAINING_RECORD(NextEntry, FOBX, ScavengerFinalizationList);
RxFinalizeNetFobx(Fobx, TRUE, TRUE);
}
return TRUE;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
VOID
RxScavengerFinalizeEntries(
PRDBSS_DEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
VOID
NTAPI
RxScavengerTimerRoutine(
PVOID Context)
{
BOOLEAN Requeue;
PRDBSS_DEVICE_OBJECT DeviceObject;
PRDBSS_SCAVENGER Scavenger;
PAGED_CODE();
DeviceObject = Context;
Scavenger = DeviceObject->pRdbssScavenger;
Requeue = FALSE;
RxAcquireScavengerMutex();
/* If the scavenger was dormant, wake it up! */
if (Scavenger->State == RDBSS_SCAVENGER_DORMANT)
{
/* Done */
Scavenger->State = RDBSS_SCAVENGER_ACTIVE;
KeClearEvent(&Scavenger->ScavengeEvent);
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Scavenger the entries */
RxReleaseScavengerMutex();
RxScavengerFinalizeEntries(DeviceObject);
RxAcquireScavengerMutex();
/* If we're still active (race) */
if (Scavenger->State == RDBSS_SCAVENGER_ACTIVE)
{
/* If there are new entries to scavenge, stay dormant and requeue a run */
if (Scavenger->NumberOfDormantFiles + Scavenger->SrvCallsToBeFinalized +
Scavenger->NetRootsToBeFinalized + Scavenger->VNetRootsToBeFinalized +
Scavenger->FcbsToBeFinalized + Scavenger->SrvOpensToBeFinalized +
Scavenger->FobxsToBeFinalized != 0)
{
Requeue = TRUE;
Scavenger->State = RDBSS_SCAVENGER_DORMANT;
}
/* Otherwise, we're inactive again */
else
{
Scavenger->State = RDBSS_SCAVENGER_INACTIVE;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
}
}
RxReleaseScavengerMutex();
/* Requeue an execution */
if (Requeue)
{
RxPostOneShotTimerRequest(RxFileSystemDeviceObject, &Scavenger->WorkItem,
RxScavengerTimerRoutine, DeviceObject, Scavenger->TimeLimit);
}
}
else
{
RxReleaseScavengerMutex();
}
KeSetEvent(&Scavenger->ScavengeEvent, IO_NO_INCREMENT, FALSE);
}
BOOLEAN
RxScavengeVNetRoots(
PRDBSS_DEVICE_OBJECT RxDeviceObject)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @implemented
*/
VOID
NTAPI
RxSpinUpRequestsDispatcher(
PVOID Dispatcher)
{
NTSTATUS Status;
PRX_DISPATCHER RxDispatcher;
Status = ObReferenceObjectByPointer(PsGetCurrentThread(), THREAD_ALL_ACCESS, *PsThreadType, KernelMode);
if (!NT_SUCCESS(Status))
{
PsTerminateSystemThread(STATUS_SUCCESS);
}
RxDispatcher = Dispatcher;
do
{
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
Status = KeWaitForSingleObject(&RxDispatcher->SpinUpRequestsEvent, Executive,
KernelMode, FALSE, &RxSpinUpDispatcherWaitInterval);
ASSERT((Status == STATUS_SUCCESS) || (Status == STATUS_TIMEOUT));
KeAcquireSpinLock(&RxDispatcher->SpinUpRequestsLock, &OldIrql);
if (!IsListEmpty(&RxDispatcher->SpinUpRequests))
{
ListEntry = RemoveHeadList(&RxDispatcher->SpinUpRequests);
}
else
{
ListEntry = &RxDispatcher->SpinUpRequests;
}
KeClearEvent(&RxDispatcher->SpinUpRequestsEvent);
KeReleaseSpinLock(&RxDispatcher->SpinUpRequestsLock, OldIrql);
while (ListEntry != &RxDispatcher->SpinUpRequests)
{
PWORK_QUEUE_ITEM WorkItem;
PRX_WORK_QUEUE WorkQueue;
WorkItem = CONTAINING_RECORD(ListEntry, WORK_QUEUE_ITEM, List);
WorkQueue = WorkItem->Parameter;
InterlockedDecrement(&WorkQueue->WorkQueueItemForSpinUpWorkerThreadInUse);
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
DPRINT("Workqueue: calling %p(%p)\n", WorkItem->WorkerRoutine, WorkItem->Parameter);
WorkItem->WorkerRoutine(WorkItem->Parameter);
}
} while (RxDispatcher->State == RxDispatcherActive);
KeSetEvent(&RxDispatcher->SpinUpRequestsTearDownEvent, IO_NO_INCREMENT, FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
}
/*
* @implemented
*/
NTSTATUS
RxSpinUpWorkerThread(
PRX_WORK_QUEUE WorkQueue,
PRX_WORKERTHREAD_ROUTINE Routine,
PVOID Parameter)
{
KIRQL OldIrql;
NTSTATUS Status;
HANDLE ThreadHandle;
PAGED_CODE();
/* If work queue is inactive, that cannot work */
KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
if (WorkQueue->State != RxWorkQueueActive)
{
Status = STATUS_UNSUCCESSFUL;
DPRINT("Workqueue not active! WorkQ: %p, State: %d, Active: %d\n", WorkQueue, WorkQueue->State, WorkQueue->NumberOfActiveWorkerThreads);
}
else
{
++WorkQueue->NumberOfActiveWorkerThreads;
Status = STATUS_SUCCESS;
}
KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
/* Quit on failure */
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Spin up the worker thread */
Status = PsCreateSystemThread(&ThreadHandle, PROCESS_ALL_ACCESS, NULL, NULL, NULL, Routine, Parameter);
if (NT_SUCCESS(Status))
{
ZwClose(ThreadHandle);
return Status;
}
/* Read well: we reached that point because it failed! */
DPRINT("WorkQ: %p, Status: %lx\n", WorkQueue, Status);
KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
--WorkQueue->NumberOfActiveWorkerThreads;
++WorkQueue->NumberOfFailedSpinUpRequests;
/* Rundown, no more active threads, set the event! */
if (WorkQueue->NumberOfActiveWorkerThreads == 0 &&
WorkQueue->State == RxWorkQueueRundownInProgress)
{
KeSetEvent(&WorkQueue->pRundownContext->RundownCompletionEvent, IO_NO_INCREMENT, FALSE);
}
DPRINT("Workqueue not active! WorkQ: %p, State: %d, Active: %d\n", WorkQueue, WorkQueue->State, WorkQueue->NumberOfActiveWorkerThreads);
KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
return Status;
}
VOID
RxSpinUpWorkerThreads(
PRX_WORK_QUEUE WorkQueue)
{
UNIMPLEMENTED;
}
VOID
RxSynchronizeWithScavenger(
IN PRX_CONTEXT RxContext)
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
ULONG
RxTableComputeHashValue(
IN PUNICODE_STRING Name)
{
ULONG Hash;
SHORT Loops[8];
USHORT MaxChar, i;
PAGED_CODE();
MaxChar = Name->Length / sizeof(WCHAR);
Loops[0] = 1;
Loops[1] = MaxChar - 1;
Loops[2] = MaxChar - 2;
Loops[3] = MaxChar - 3;
Loops[4] = MaxChar - 4;
Loops[5] = MaxChar / 4;
Loops[6] = 2 * MaxChar / 4;
Loops[7] = 3 * MaxChar / 4;
Hash = 0;
for (i = 0; i < 8; ++i)
{
SHORT Idx;
Idx = Loops[i];
if (Idx >= 0 && Idx < MaxChar)
{
Hash = RtlUpcaseUnicodeChar(Name->Buffer[Idx]) + 8 * Hash;
}
}
return Hash;
}
/*
* @implemented
*/
ULONG
RxTableComputePathHashValue(
IN PUNICODE_STRING Name)
{
ULONG Hash;
SHORT Loops[8];
USHORT MaxChar, i;
PAGED_CODE();
MaxChar = Name->Length / sizeof(WCHAR);
Loops[0] = 1;
Loops[1] = MaxChar - 1;
Loops[2] = MaxChar - 2;
Loops[3] = MaxChar - 3;
Loops[4] = MaxChar - 4;
Loops[5] = MaxChar / 4;
Loops[6] = 2 * MaxChar / 4;
Loops[7] = 3 * MaxChar / 4;
Hash = 0;
for (i = 0; i < 8; ++i)
{
SHORT Idx;
Idx = Loops[i];
if (Idx >= 0 && Idx < MaxChar)
{
Hash = RtlUpcaseUnicodeChar(Name->Buffer[Idx]) + 8 * Hash;
}
}
return Hash;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
PVOID
RxTableLookupName(
IN PRX_PREFIX_TABLE ThisTable,
IN PUNICODE_STRING Name,
OUT PUNICODE_STRING RemainingName,
IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
{
PVOID Container;
USHORT i, MaxChar;
PRX_PREFIX_ENTRY Entry;
RX_CONNECTION_ID NullId;
UNICODE_STRING LookupString;
PAGED_CODE();
/* If caller didn't provide a connection ID, setup one */
if (ThisTable->IsNetNameTable && RxConnectionId == NULL)
{
NullId.Luid.LowPart = 0;
NullId.Luid.HighPart = 0;
RxConnectionId = &NullId;
}
/* Validate name */
ASSERT(Name->Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
Entry = NULL;
Container = NULL;
LookupString.Buffer = Name->Buffer;
MaxChar = Name->Length / sizeof(WCHAR);
/* We'll perform the lookup, path component after another */
for (i = 1; i < MaxChar; ++i)
{
ULONG Hash;
PRX_PREFIX_ENTRY CurEntry;
/* Don't cut in the middle of a path element */
if (Name->Buffer[i] != OBJ_NAME_PATH_SEPARATOR && Name->Buffer[i] != ':')
{
continue;
}
/* Perform lookup in the table */
LookupString.Length = i * sizeof(WCHAR);
Hash = RxTableComputeHashValue(&LookupString);
CurEntry = RxTableLookupName_ExactLengthMatch(ThisTable, &LookupString, Hash, RxConnectionId);
#if DBG
++ThisTable->Lookups;
#endif
/* Entry not found, move to the next component */
if (CurEntry == NULL)
{
#if DBG
++ThisTable->FailedLookups;
#endif
continue;
}
Entry = CurEntry;
ASSERT(Entry->ContainingRecord != NULL);
Container = Entry->ContainingRecord;
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/* If we have a NET_ROOT, let's return a V_NET_ROOT */
if ((NodeType(Entry->ContainingRecord) & ~RX_SCAVENGER_MASK) == RDBSS_NTC_NETROOT)
{
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
PNET_ROOT NetRoot;
NetRoot = (PNET_ROOT)Entry->ContainingRecord;
/* If there's a default one, perfect, that's a match */
if (NetRoot->DefaultVNetRoot != NULL)
{
Container = NetRoot->DefaultVNetRoot;
}
/* If none (that shouldn't happen!), try to find one */
else
{
/* Use the first one in the list */
if (!IsListEmpty(&NetRoot->VirtualNetRoots))
{
Container = CONTAINING_RECORD(NetRoot->VirtualNetRoots.Flink, V_NET_ROOT, NetRootListEntry);
}
/* Really, really, shouldn't happen */
else
{
ASSERT(FALSE);
Entry = NULL;
Container = NULL;
}
}
break;
}
else if ((NodeType(Entry->ContainingRecord) & ~RX_SCAVENGER_MASK) == RDBSS_NTC_V_NETROOT)
{
break;
}
else
{
ASSERT((NodeType(Entry->ContainingRecord) & ~RX_SCAVENGER_MASK) == RDBSS_NTC_SRVCALL);
}
}
/* Entry was found */
if (Entry != NULL)
{
DPRINT("Found\n");
ASSERT(Name->Length >= Entry->Prefix.Length);
/* Setup remaining name */
RemainingName->Buffer = Add2Ptr(Name->Buffer, Entry->Prefix.Length);
RemainingName->Length = Name->Length - Entry->Prefix.Length;
RemainingName->MaximumLength = Name->Length - Entry->Prefix.Length;
}
else
{
/* Otherwise, that's the whole name */
RemainingName = Name;
}
return Container;
}
/*
* @implemented
*/
PRX_PREFIX_ENTRY
RxTableLookupName_ExactLengthMatch(
IN PRX_PREFIX_TABLE ThisTable,
IN PUNICODE_STRING Name,
IN ULONG HashValue,
IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
{
PLIST_ENTRY ListEntry, HashBucket;
PAGED_CODE();
ASSERT(RxConnectionId != NULL);
/* Select the right bucket */
HashBucket = HASH_BUCKET(ThisTable, HashValue);
DPRINT("Looking in bucket: %p for %x\n", HashBucket, HashValue);
/* If bucket is empty, no match */
if (IsListEmpty(HashBucket))
{
return NULL;
}
/* Browse all the entries in the bucket */
for (ListEntry = HashBucket->Flink;
ListEntry != HashBucket;
ListEntry = ListEntry->Flink)
{
PVOID Container;
PRX_PREFIX_ENTRY Entry;
BOOLEAN CaseInsensitive;
PUNICODE_STRING CmpName, CmpPrefix;
UNICODE_STRING InsensitiveName, InsensitivePrefix;
Entry = CONTAINING_RECORD(ListEntry, RX_PREFIX_ENTRY, HashLinks);
#if DBG
++ThisTable->Considers;
#endif
ASSERT(HashBucket == HASH_BUCKET(ThisTable, Entry->SavedHashValue));
Container = Entry->ContainingRecord;
ASSERT(Container != NULL);
/* Not the same hash, not the same length, move on */
if (Entry->SavedHashValue != HashValue || Entry->Prefix.Length != Name->Length)
{
continue;
}
#if DBG
++ThisTable->Compares;
#endif
/* If we have to perform a case insensitive compare on a portion... */
if (Entry->CaseInsensitiveLength != 0)
{
ASSERT(Entry->CaseInsensitiveLength <= Name->Length);
/* Perform the case insensitive check on the asked length */
InsensitiveName.Buffer = Name->Buffer;
InsensitivePrefix.Buffer = Entry->Prefix.Buffer;
InsensitiveName.Length = Entry->CaseInsensitiveLength;
InsensitivePrefix.Length = Entry->CaseInsensitiveLength;
/* No match, move to the next entry */
if (!RtlEqualUnicodeString(&InsensitiveName, &InsensitivePrefix, TRUE))
{
continue;
}
/* Was the case insensitive covering the whole name? */
if (Name->Length == Entry->CaseInsensitiveLength)
{
/* If connection ID also matches, that a complete match! */
if (!ThisTable->IsNetNameTable || RxEqualConnectionId(RxConnectionId, &Entry->ConnectionId))
{
return Entry;
}
}
/* Otherwise, we have to continue with the sensitive match.... */
InsensitiveName.Buffer = Add2Ptr(InsensitiveName.Buffer, Entry->CaseInsensitiveLength);
InsensitivePrefix.Buffer = Add2Ptr(InsensitivePrefix.Buffer, Entry->CaseInsensitiveLength);
InsensitiveName.Length = Name->Length - Entry->CaseInsensitiveLength;
InsensitivePrefix.Length = Entry->Prefix.Length - Entry->CaseInsensitiveLength;
CmpName = &InsensitiveName;
CmpPrefix = &InsensitivePrefix;
CaseInsensitive = FALSE;
}
else
{
CmpName = Name;
CmpPrefix = &Entry->Prefix;
CaseInsensitive = ThisTable->CaseInsensitiveMatch;
}
/* Perform the compare, if there's a match, also check for connection ID */
if (RtlEqualUnicodeString(CmpName, CmpPrefix, CaseInsensitive))
{
if (!ThisTable->IsNetNameTable || RxEqualConnectionId(RxConnectionId, &Entry->ConnectionId))
{
return Entry;
}
}
}
return NULL;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
NTSTATUS
RxTearDownBufferingManager(
PSRV_CALL SrvCall)
{
PAGED_CODE();
/* Nothing to do */
return STATUS_SUCCESS;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/*
* @implemented
*/
VOID
NTAPI
RxTimerDispatch(
_In_ struct _KDPC *Dpc,
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2)
{
BOOLEAN Set;
LIST_ENTRY LocalList;
PLIST_ENTRY ListEntry;
PRX_WORK_ITEM WorkItem;
InitializeListHead(&LocalList);
KeAcquireSpinLockAtDpcLevel(&RxTimerLock);
++RxTimerTickCount;
/* Find any entry matching */
if (!IsListEmpty(&RxTimerQueueHead))
{
ListEntry = RxTimerQueueHead.Flink;
do
{
WorkItem = CONTAINING_RECORD(ListEntry, RX_WORK_ITEM, WorkQueueItem.List);
if (WorkItem->LastTick == RxTimerTickCount)
{
ListEntry = ListEntry->Flink;
RemoveEntryList(&WorkItem->WorkQueueItem.List);
InsertTailList(&LocalList, &WorkItem->WorkQueueItem.List);
}
else
{
ListEntry = ListEntry->Flink;
}
} while (ListEntry != &RxTimerQueueHead);
}
/* Do we have to requeue a later execution? */
Set = !IsListEmpty(&RxTimerQueueHead);
KeReleaseSpinLockFromDpcLevel(&RxTimerLock);
/* Requeue if list wasn't empty */
if (Set)
{
KeSetTimer(&RxTimer, RxTimerInterval, &RxTimerDpc);
}
/* If we had matching entries */
if (!IsListEmpty(&LocalList))
{
/* Post them, one after another */
ListEntry = LocalList.Flink;
do
{
WorkItem = CONTAINING_RECORD(ListEntry, RX_WORK_ITEM, WorkQueueItem.List);
ListEntry = ListEntry->Flink;
WorkItem->WorkQueueItem.List.Flink = NULL;
WorkItem->WorkQueueItem.List.Blink = NULL;
RxPostToWorkerThread(WorkItem->WorkQueueItem.pDeviceObject, CriticalWorkQueue,
&WorkItem->WorkQueueItem, WorkItem->WorkQueueItem.WorkerRoutine,
WorkItem->WorkQueueItem.Parameter);
}
while (ListEntry != &LocalList);
}
}
#ifdef RDBSS_TRACKER
/*
* @implemented
*/
VOID
RxTrackerUpdateHistory(
_Inout_opt_ PRX_CONTEXT RxContext,
_Inout_ PMRX_FCB MrxFcb,
_In_ ULONG Operation,
_In_ ULONG LineNumber,
_In_ PCSTR FileName,
_In_ ULONG SerialNumber)
{
PFCB Fcb;
RX_FCBTRACKER_CASES Case;
/* Check for null or special context */
if (RxContext == NULL)
{
Case = RX_FCBTRACKER_CASE_NULLCONTEXT;
}
else if (RxContext == CHANGE_BUFFERING_STATE_CONTEXT)
{
Case = RX_FCBTRACKER_CASE_CBS_CONTEXT;
}
else if (RxContext == CHANGE_BUFFERING_STATE_CONTEXT_WAIT)
{
Case = RX_FCBTRACKER_CASE_CBS_WAIT_CONTEXT;
}
else
{
ASSERT(NodeType(RxContext) == RDBSS_NTC_RX_CONTEXT);
Case = RX_FCBTRACKER_CASE_NORMAL;
}
/* If caller provided a FCB, update its history */
if (MrxFcb != NULL)
{
Fcb = (PFCB)MrxFcb;
ASSERT(NodeTypeIsFcb(Fcb));
/* Only one acquire operation, so many release operations... */
if (Operation == TRACKER_ACQUIRE_FCB)
{
++Fcb->FcbAcquires[Case];
}
else
{
++Fcb->FcbReleases[Case];
}
}
/* If we have a normal context, update its history about this function calls */
if (Case == RX_FCBTRACKER_CASE_NORMAL)
{
ULONG TrackerHistoryPointer;
/* Only one acquire operation, so many release operations... */
if (Operation == TRACKER_ACQUIRE_FCB)
{
InterlockedIncrement(&RxContext->AcquireReleaseFcbTrackerX);
}
else
{
InterlockedDecrement(&RxContext->AcquireReleaseFcbTrackerX);
}
/* We only keep track of the 32 first calls */
TrackerHistoryPointer = InterlockedExchangeAdd((volatile long *)&RxContext->TrackerHistoryPointer, 1);
if (TrackerHistoryPointer < RDBSS_TRACKER_HISTORY_SIZE)
{
RxContext->TrackerHistory[TrackerHistoryPointer].AcquireRelease = Operation;
RxContext->TrackerHistory[TrackerHistoryPointer].LineNumber = LineNumber;
RxContext->TrackerHistory[TrackerHistoryPointer].FileName = (PSZ)FileName;
RxContext->TrackerHistory[TrackerHistoryPointer].SavedTrackerValue = RxContext->AcquireReleaseFcbTrackerX;
RxContext->TrackerHistory[TrackerHistoryPointer].Flags = RxContext->Flags;
}
/* If it's negative, then we released once more than we acquired it?! */
ASSERT(RxContext->AcquireReleaseFcbTrackerX >= 0);
}
}
#endif
VOID
RxTrackPagingIoResource(
_Inout_ PVOID Instance,
_In_ ULONG Type,
_In_ ULONG Line,
_In_ PCSTR File)
{
UNIMPLEMENTED;
}
[RXCE] - Implemented RxCompleteSrvOpenKeyAssociation(), RxInitiateSrvOpenKeyAssociation(), RxProcessChangeBufferingStateRequests() - Implemented RxFinalizeFcbTable(), RxFinalizeNetFobx(), RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), RxFreeObject(), RxpDestroySrvCall(), RxRemovePrefixTableEntry(), RxRemoveVirtualNetRootFromNetRoot(), RxScavengeRelatedFobxs(), RxTearDownBufferingManager(), RxUndoScavengerFinalizationMarking() - Implemented RxPostToWorkerThread() - Implemented RxFlushFcbInSystemCache(), RxPurgeFcb(), RxPurgeFcbInSystemCache() - Stubbed RxOrphanSrvOpens(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpProcessChangeBufferingStateRequests() - Continued implementation of RxDereference() so that it supports more objects than just SRV_CALL - Reworked RxInsertWorkQueueItem() implementation so that it accepts any work item, and not just dispatch work items - Finished implementation of RxTableLookupName() so that it properly returns a V_NET_ROOT on NET_ROOT match Notable effects of this commit are: - RXCE/RDBSS leak less memory; now objects without references are properly deleted from the system - This means that stale objects are also deleted; this fixes CORE-13483 were same stale SRV_CALL was used again and again - Because in prefix table NET_ROOT are correctly handled, it's now possible to mount several path from the same prefix; this fixes CORE-13482 CORE-8204 CORE-11327 CORE-13482 CORE-13483 svn path=/trunk/; revision=75195
2017-06-25 11:55:37 +00:00
/*
* @implemented
*/
VOID
RxUndoScavengerFinalizationMarking(
PVOID Instance)
{
/* Just call internal routine with mutex held */
RxAcquireScavengerMutex();
RxpUndoScavengerFinalizationMarking(Instance);
RxReleaseScavengerMutex();
}
/*
* @implemented
*/
VOID
RxUninitializeVNetRootParameters(
IN PUNICODE_STRING UserName,
IN PUNICODE_STRING UserDomainName,
IN PUNICODE_STRING Password,
OUT PULONG Flags)
{
PAGED_CODE();
/* Only free what could have been allocated */
if (UserName != NULL)
{
RxFreePool(UserName);
}
if (UserDomainName != NULL)
{
RxFreePool(UserDomainName);
}
if (Password != NULL)
{
RxFreePool(Password);
}
/* And remove the possibly set CSC agent flag */
if (Flags != NULL)
{
(*Flags) &= ~VNETROOT_FLAG_CSCAGENT_INSTANCE;
}
}
/*
* @implemented
*/
VOID
RxUpdateCondition(
IN RX_BLOCK_CONDITION NewConditionValue,
OUT PRX_BLOCK_CONDITION Condition,
IN OUT PLIST_ENTRY TransitionWaitList)
{
PRX_CONTEXT Context;
LIST_ENTRY SerializationQueue;
PAGED_CODE();
DPRINT("RxUpdateCondition(%d, %p, %p)\n", NewConditionValue, Condition, TransitionWaitList);
/* Set the new condition */
RxAcquireSerializationMutex();
ASSERT(NewConditionValue != Condition_InTransition);
*Condition = NewConditionValue;
/* And get the serialization queue for treatment */
RxTransferList(&SerializationQueue, TransitionWaitList);
RxReleaseSerializationMutex();
/* Handle the serialization queue */
Context = RxRemoveFirstContextFromSerializationQueue(&SerializationQueue);
while (Context != NULL)
{
/* If the caller asked for post, post the request */
if (BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION))
{
Context->Flags &= ~RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION;
RxFsdPostRequest(Context);
}
/* Otherwise, wake up sleeping waiters */
else
{
RxSignalSynchronousWaiter(Context);
}
Context = RxRemoveFirstContextFromSerializationQueue(&SerializationQueue);
}
}
/*
* @implemented
*/
VOID
RxVerifyOperationIsLegal(
IN PRX_CONTEXT RxContext)
{
PIRP Irp;
PMRX_FOBX Fobx;
BOOLEAN FlagSet;
PFILE_OBJECT FileObject;
PIO_STACK_LOCATION Stack;
PAGED_CODE();
Irp = RxContext->CurrentIrp;
Stack = RxContext->CurrentIrpSp;
FileObject = Stack->FileObject;
/* We'll only check stuff on opened files, this requires an IRP and a FO */
if (Irp == NULL || FileObject == NULL)
{
return;
}
/* Set no exception for breakpoint - remember whether is was already set */
FlagSet = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
/* If we have a CCB, perform a few checks on opened file */
Fobx = RxContext->pFobx;
if (Fobx != NULL)
{
PMRX_SRV_OPEN SrvOpen;
SrvOpen = Fobx->pSrvOpen;
if (SrvOpen != NULL)
{
UCHAR MajorFunction;
MajorFunction = RxContext->MajorFunction;
/* Only allow closing/cleanup operations on renamed files */
if (MajorFunction != IRP_MJ_CLEANUP && MajorFunction != IRP_MJ_CLOSE &&
BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED))
{
RxContext->IoStatusBlock.Status = STATUS_FILE_RENAMED;
ExRaiseStatus(STATUS_FILE_RENAMED);
}
/* Only allow closing/cleanup operations on deleted files */
if (MajorFunction != IRP_MJ_CLEANUP && MajorFunction != IRP_MJ_CLOSE &&
BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED))
{
RxContext->IoStatusBlock.Status = STATUS_FILE_DELETED;
ExRaiseStatus(STATUS_FILE_DELETED);
}
}
}
/* If that's an open operation */
if (RxContext->MajorFunction == IRP_MJ_CREATE)
{
PFILE_OBJECT RelatedFileObject;
/* We won't allow an open operation relative to a file to be deleted */
RelatedFileObject = FileObject->RelatedFileObject;
if (RelatedFileObject != NULL)
{
PMRX_FCB Fcb;
Fcb = RelatedFileObject->FsContext;
if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE))
{
RxContext->IoStatusBlock.Status = STATUS_DELETE_PENDING;
ExRaiseStatus(STATUS_DELETE_PENDING);
}
}
}
/* If cleanup was completed */
if (BooleanFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE))
{
if (!BooleanFlagOn(Irp->Flags, IRP_PAGING_IO))
{
UCHAR MajorFunction;
/* We only allow a subset of operations (see FatVerifyOperationIsLegal for instance) */
MajorFunction = Stack->MajorFunction;
if (MajorFunction != IRP_MJ_CLOSE && MajorFunction != IRP_MJ_QUERY_INFORMATION &&
MajorFunction != IRP_MJ_SET_INFORMATION)
{
if ((MajorFunction != IRP_MJ_READ && MajorFunction != IRP_MJ_WRITE) ||
!BooleanFlagOn(Stack->MinorFunction, IRP_MN_COMPLETE))
{
RxContext->IoStatusBlock.Status = STATUS_FILE_CLOSED;
ExRaiseStatus(STATUS_FILE_CLOSED);
}
}
}
}
/* If flag was already set, don't clear it */
if (!FlagSet)
{
ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
}
}
/*
* @implemented
*/
VOID
RxWaitForStableCondition(
IN PRX_BLOCK_CONDITION Condition,
IN OUT PLIST_ENTRY TransitionWaitList,
IN OUT PRX_CONTEXT RxContext,
OUT NTSTATUS *AsyncStatus OPTIONAL)
{
BOOLEAN Wait;
NTSTATUS LocalStatus;
PAGED_CODE();
/* Make sure to always get status */
if (AsyncStatus == NULL)
{
AsyncStatus = &LocalStatus;
}
/* By default, it's a success */
*AsyncStatus = STATUS_SUCCESS;
Wait = FALSE;
/* If it's not stable, we've to wait */
if (!StableCondition(*Condition))
{
/* Lock the mutex */
RxAcquireSerializationMutex();
/* Still not stable? */
if (!StableCondition(*Condition))
{
/* Insert us in the wait list for processing on stable condition */
RxInsertContextInSerializationQueue(TransitionWaitList, RxContext);
/* If we're asked to post on stable, don't wait, and just return pending */
if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION))
{
*AsyncStatus = STATUS_PENDING;
}
else
{
Wait = TRUE;
}
}
RxReleaseSerializationMutex();
/* We don't post on stable, so, just wait... */
if (Wait)
{
RxWaitSync(RxContext);
}
}
}
/*
* @implemented
*/
VOID
NTAPI
RxWorkItemDispatcher(
PVOID Context)
{
PRX_WORK_DISPATCH_ITEM DispatchItem = Context;
DPRINT("Calling: %p, %p\n", DispatchItem->DispatchRoutine, DispatchItem->DispatchRoutineParameter);
DispatchItem->DispatchRoutine(DispatchItem->DispatchRoutineParameter);
RxFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
}
/*
* @implemented
*/
PVOID
NTAPI
_RxAllocatePoolWithTag(
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Tag)
{
return ExAllocatePoolWithTagPriority(PoolType, NumberOfBytes, Tag, LowPoolPriority);
}
/*
* @implemented
*/
VOID
NTAPI
_RxFreePool(
_In_ PVOID Buffer)
{
ExFreePoolWithTag(Buffer, 0);
}
/*
* @implemented
*/
VOID
NTAPI
_RxFreePoolWithTag(
_In_ PVOID Buffer,
_In_ ULONG Tag)
{
ExFreePoolWithTag(Buffer, Tag);
}
NTSTATUS
__RxAcquireFcb(
_Inout_ PFCB Fcb,
_Inout_opt_ PRX_CONTEXT RxContext OPTIONAL,
_In_ ULONG Mode
#ifdef RDBSS_TRACKER
,
_In_ ULONG LineNumber,
_In_ PCSTR FileName,
_In_ ULONG SerialNumber
#endif
)
{
NTSTATUS Status;
BOOLEAN SpecialContext, CanWait, Acquired, ContextIsPresent;
PAGED_CODE();
DPRINT("__RxAcquireFcb(%p, %p, %d, %d, %s, %d)\n", Fcb, RxContext, Mode, LineNumber, FileName, SerialNumber);
SpecialContext = FALSE;
ContextIsPresent = FALSE;
/* Check for special context */
if (RxContext == CHANGE_BUFFERING_STATE_CONTEXT || RxContext == CHANGE_BUFFERING_STATE_CONTEXT_WAIT)
{
SpecialContext = TRUE;
}
/* We don't handle buffering state change yet... */
if (!RxIsFcbAcquired(Fcb) && !SpecialContext &&
BooleanFlagOn(Fcb->FcbState, FCB_STATE_BUFFERING_STATE_CHANGE_PENDING))
{
UNIMPLEMENTED;
}
/* Nor special contexts */
if (SpecialContext)
{
UNIMPLEMENTED;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* If we don't have a context, assume we can wait! */
if (RxContext == NULL)
{
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
CanWait = TRUE;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
else
{
/* That said: we have a real context! */
ContextIsPresent = TRUE;
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* If we've been cancelled in between, give up */
Status = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_CANCELLED) ? STATUS_CANCELLED : STATUS_SUCCESS;
if (!NT_SUCCESS(Status))
{
return Status;
}
[RDBSS] - Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
2017-07-02 17:00:11 +00:00
/* Can we wait? */
CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
}
while (TRUE)
{
/* Assume we cannot lock */
Status = STATUS_LOCK_NOT_GRANTED;
/* Lock according to what the caller asked */
switch (Mode)
{
case FCB_MODE_EXCLUSIVE:
Acquired = ExAcquireResourceExclusiveLite(Fcb->Header.Resource, CanWait);
break;
case FCB_MODE_SHARED:
Acquired = ExAcquireResourceSharedLite(Fcb->Header.Resource, CanWait);
break;
case FCB_MODE_SHARED_WAIT_FOR_EXCLUSIVE:
Acquired = ExAcquireSharedWaitForExclusive(Fcb->Header.Resource, CanWait);
break;
default:
ASSERT(Mode == FCB_MODE_SHARED_STARVE_EXCLUSIVE);
Acquired = ExAcquireSharedStarveExclusive(Fcb->Header.Resource, CanWait);
break;
}
/* Lock granted! */
if (Acquired)
{
Status = STATUS_SUCCESS;
ASSERT_CORRECT_FCB_STRUCTURE(Fcb);
/* Handle paging write - not implemented */
if (Fcb->NonPaged->OutstandingAsyncWrites != 0)
{
UNIMPLEMENTED;
}
}
/* And break, that cool! */
if (Acquired)
{
break;
}
/* If it failed, return immediately */
if (!NT_SUCCESS(Status))
{
return Status;
}
}
/* If we don't have to check for valid operation, job done, nothing more to do */
if (!ContextIsPresent || BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK))
{
if (NT_SUCCESS(Status))
{
RxTrackerUpdateHistory(RxContext, RX_GET_MRX_FCB(Fcb), TRACKER_ACQUIRE_FCB, LineNumber, FileName, SerialNumber);
}
return Status;
}
/* Verify operation */
_SEH2_TRY
{
RxVerifyOperationIsLegal(RxContext);
}
_SEH2_FINALLY
{
/* If it failed, release lock and fail */
if (_SEH2_AbnormalTermination())
{
ExReleaseResourceLite(Fcb->Header.Resource);
Status = STATUS_LOCK_NOT_GRANTED;
}
}
_SEH2_END;
if (NT_SUCCESS(Status))
{
RxTrackerUpdateHistory(RxContext, RX_GET_MRX_FCB(Fcb), TRACKER_ACQUIRE_FCB, LineNumber, FileName, SerialNumber);
}
DPRINT("Status: %x\n", Status);
return Status;
}
/*
* @implemented
*/
VOID
__RxItsTheSameContext(
_In_ PRX_CONTEXT RxContext,
_In_ ULONG CapturedRxContextSerialNumber,
_In_ ULONG Line,
_In_ PCSTR File)
{
/* Check we have a context with the same serial number */
if (NodeType(RxContext) != RDBSS_NTC_RX_CONTEXT ||
RxContext->SerialNumber != CapturedRxContextSerialNumber)
{
/* Just be noisy */
DPRINT1("Context %p has changed at line %d in file %s\n", RxContext, Line, File);
}
}
VOID
__RxReleaseFcb(
_Inout_opt_ PRX_CONTEXT RxContext,
_Inout_ PMRX_FCB MrxFcb
#ifdef RDBSS_TRACKER
,
_In_ ULONG LineNumber,
_In_ PCSTR FileName,
_In_ ULONG SerialNumber
#endif
)
{
BOOLEAN IsExclusive, BufferingPending;
RxAcquireSerializationMutex();
BufferingPending = BooleanFlagOn(MrxFcb->FcbState, FCB_STATE_BUFFERING_STATE_CHANGE_PENDING);
IsExclusive = !!RxIsResourceOwnershipStateExclusive(MrxFcb->Header.Resource);
/* If no buffering pending, or no exclusive lock (we can only handle with an exclusive lock),
* then just release the FCB
*/
if (!BufferingPending || !IsExclusive)
{
RxTrackerUpdateHistory(RxContext, MrxFcb, (!BufferingPending ? TRACKER_RELEASE_FCB_NO_BUFF_PENDING : TRACKER_RELEASE_NON_EXCL_FCB_BUFF_PENDING),
LineNumber, FileName, SerialNumber);
ExReleaseResourceLite(MrxFcb->Header.Resource);
}
RxReleaseSerializationMutex();
/* And finally leave */
if (!BufferingPending || !IsExclusive)
{
return;
}
ASSERT(RxIsFcbAcquiredExclusive(MrxFcb));
/* Otherwise, handle buffering state and release */
RxProcessFcbChangeBufferingStateRequest((PFCB)MrxFcb);
RxTrackerUpdateHistory(RxContext, MrxFcb, TRACKER_RELEASE_EXCL_FCB_BUFF_PENDING, LineNumber, FileName, SerialNumber);
ExReleaseResourceLite(MrxFcb->Header.Resource);
}
VOID
__RxReleaseFcbForThread(
_Inout_opt_ PRX_CONTEXT RxContext,
_Inout_ PMRX_FCB MrxFcb,
_In_ ERESOURCE_THREAD ResourceThreadId
#ifdef RDBSS_TRACKER
,
_In_ ULONG LineNumber,
_In_ PCSTR FileName,
_In_ ULONG SerialNumber
#endif
)
{
BOOLEAN IsExclusive, BufferingPending;
RxAcquireSerializationMutex();
BufferingPending = BooleanFlagOn(MrxFcb->FcbState, FCB_STATE_BUFFERING_STATE_CHANGE_PENDING);
IsExclusive = !!RxIsResourceOwnershipStateExclusive(MrxFcb->Header.Resource);
/* If no buffering pending, or no exclusive lock (we can only handle with an exclusive lock),
* then just release the FCB
*/
if (!BufferingPending || !IsExclusive)
{
RxTrackerUpdateHistory(RxContext, MrxFcb,
(!BufferingPending ? TRACKER_RELEASE_FCB_FOR_THRD_NO_BUFF_PENDING : TRACKER_RELEASE_NON_EXCL_FCB_FOR_THRD_BUFF_PENDING),
LineNumber, FileName, SerialNumber);
ExReleaseResourceForThreadLite(MrxFcb->Header.Resource, ResourceThreadId);
}
RxReleaseSerializationMutex();
/* And finally leave */
if (!BufferingPending || !IsExclusive)
{
return;
}
/* Otherwise, handle buffering state and release */
RxTrackerUpdateHistory(RxContext, MrxFcb, TRACKER_RELEASE_EXCL_FCB_FOR_THRD_BUFF_PENDING, LineNumber, FileName, SerialNumber);
RxProcessFcbChangeBufferingStateRequest((PFCB)MrxFcb);
ExReleaseResourceForThreadLite(MrxFcb->Header.Resource, ResourceThreadId);
}