USHORT PvfsIrpContextConditionalSetFlag( PPVFS_IRP_CONTEXT pIrpContext, USHORT BitToCheck, USHORT BitToSetOnTrue, USHORT BitToSetOnFalse ) { BOOLEAN bLocked = FALSE; USHORT FlagWasSet = 0; LWIO_LOCK_MUTEX(bLocked, &pIrpContext->Mutex); if (IsSetFlag(pIrpContext->Flags, BitToCheck)) { SetFlag(pIrpContext->Flags, BitToSetOnTrue); FlagWasSet = BitToSetOnTrue; } else { SetFlag(pIrpContext->Flags, BitToSetOnFalse); FlagWasSet = BitToSetOnFalse; } LWIO_UNLOCK_MUTEX(bLocked, &pIrpContext->Mutex); return FlagWasSet; }
static VOID SrvExecuteCheckdirAsyncCB( PVOID pContext ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSRV_EXEC_CONTEXT pExecContext = (PSRV_EXEC_CONTEXT)pContext; PSRV_PROTOCOL_EXEC_CONTEXT pProtocolContext = pExecContext->pProtocolContext; PSRV_CHECKDIR_STATE_SMB_V1 pCheckdirState = NULL; BOOLEAN bInLock = FALSE; pCheckdirState = (PSRV_CHECKDIR_STATE_SMB_V1)pProtocolContext->pSmb1Context->hState; LWIO_LOCK_MUTEX(bInLock, &pCheckdirState->mutex); if (pCheckdirState->pAcb && pCheckdirState->pAcb->AsyncCancelContext) { IoDereferenceAsyncCancelContext( &pCheckdirState->pAcb->AsyncCancelContext); } pCheckdirState->pAcb = NULL; LWIO_UNLOCK_MUTEX(bInLock, &pCheckdirState->mutex); ntStatus = SrvProtocolExecute(pExecContext); // (!NT_SUCCESS(ntStatus)) - Error has already been logged SrvReleaseExecContext(pExecContext); return; }
static VOID SrvExecuteOpenAsyncCB( PVOID pContext ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSRV_EXEC_CONTEXT pExecContext = (PSRV_EXEC_CONTEXT)pContext; PSRV_PROTOCOL_EXEC_CONTEXT pProtocolContext = pExecContext->pProtocolContext; PSRV_OPEN_STATE_SMB_V1 pOpenState = NULL; BOOLEAN bInLock = FALSE; pOpenState = (PSRV_OPEN_STATE_SMB_V1)pProtocolContext->pSmb1Context->hState; LWIO_LOCK_MUTEX(bInLock, &pOpenState->mutex); if (pOpenState->pAcb->AsyncCancelContext) { IoDereferenceAsyncCancelContext( &pOpenState->pAcb->AsyncCancelContext); } pOpenState->pAcb = NULL; LWIO_UNLOCK_MUTEX(bInLock, &pOpenState->mutex); ntStatus = SrvProdConsEnqueue(gProtocolGlobals_SMB_V1.pWorkQueue, pContext); if (ntStatus != STATUS_SUCCESS) { LWIO_LOG_ERROR("Failed to enqueue execution context [status:0x%x]", ntStatus); SrvReleaseExecContext(pExecContext); } }
static NTSTATUS PvfsNotifyAddFilter( PPVFS_FCB pFcb, PPVFS_IRP_CONTEXT pIrpContext, PPVFS_CCB pCcb, FILE_NOTIFY_CHANGE NotifyFilter, BOOLEAN bWatchTree, PULONG pMaxBufferSize ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_NOTIFY_FILTER_RECORD pFilter = NULL; BOOLEAN bLocked = FALSE; BAIL_ON_INVALID_PTR(pFcb, ntError); ntError = PvfsNotifyAllocateFilter( &pFilter, pIrpContext, pCcb, NotifyFilter, bWatchTree); BAIL_ON_NT_STATUS(ntError); /* Add a buffer log to this filter if specified. We'll move the record to the buffer list after first processing the Irp */ if (pMaxBufferSize && (*pMaxBufferSize > 0)) { ntError = PvfsNotifyAllocateChangeBuffer( &pFilter->Buffer, *pMaxBufferSize); BAIL_ON_NT_STATUS(ntError); } LWIO_LOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); ntError = PvfsListAddTail( pFcb->pNotifyListIrp, &pFilter->NotifyList); LWIO_UNLOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); BAIL_ON_NT_STATUS(ntError); cleanup: return ntError; error: if (pFilter) { PvfsFreeNotifyRecord(&pFilter); } goto cleanup; }
VOID RdrSetShutdown( VOID ) { BOOLEAN bLocked = FALSE; LWIO_LOCK_MUTEX(bLocked, &gRdrRuntime.Lock); gRdrRuntime.bShutdown = TRUE; LWIO_UNLOCK_MUTEX(bLocked, &gRdrRuntime.Lock); }
VOID PvfsFcbSetPendingDelete( PPVFS_FCB pFcb, BOOLEAN bPendingDelete ) { BOOLEAN bIsLocked = FALSE; LWIO_LOCK_MUTEX(bIsLocked, &pFcb->BaseControlBlock.Mutex); pFcb->bDeleteOnClose = bPendingDelete; LWIO_UNLOCK_MUTEX(bIsLocked, &pFcb->BaseControlBlock.Mutex); }
NTSTATUS PvfsSaveFileDeviceInfo( PPVFS_CCB pCcb ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PVFS_STAT Stat = {0}; PPVFS_SCB pScb = pCcb->pScb; PPVFS_FCB pFcb = pCcb->pScb->pOwnerFcb; BOOLEAN scbLocked = FALSE; BOOLEAN fcbLocked = FALSE; ntError = PvfsSysFstat(pCcb->fd, &Stat); BAIL_ON_NT_STATUS(ntError); pCcb->FileId.Device = Stat.s_dev; pCcb->FileId.Inode = Stat.s_ino; pCcb->FileSize = Stat.s_size; LWIO_LOCK_MUTEX(scbLocked, &pScb->BaseControlBlock.Mutex); // Have to set the FileID on the Stream Block pScb->FileId = pCcb->FileId; if (PvfsIsDefaultStream(pScb)) { // Push the FIleId through to the File Block if unset LWIO_LOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex); pFcb->FileId = pScb->FileId; LWIO_UNLOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex); } LWIO_UNLOCK_MUTEX(scbLocked, &pScb->BaseControlBlock.Mutex); error: return ntError; }
VOID DfsIrpContextSetFlag( PDFS_IRP_CONTEXT pIrpContext, USHORT BitToSet ) { BOOLEAN bLocked = FALSE; LWIO_LOCK_MUTEX(bLocked, &pIrpContext->Mutex); SetFlag(pIrpContext->Flags, BitToSet); LWIO_UNLOCK_MUTEX(bLocked, &pIrpContext->Mutex); return; }
BOOLEAN PvfsFcbIsPendingDelete( PPVFS_FCB pFcb ) { BOOLEAN bPendingDelete = FALSE; BOOLEAN bIsLocked = FALSE; LWIO_LOCK_MUTEX(bIsLocked, &pFcb->BaseControlBlock.Mutex); bPendingDelete = pFcb->bDeleteOnClose; LWIO_UNLOCK_MUTEX(bIsLocked, &pFcb->BaseControlBlock.Mutex); return bPendingDelete; }
VOID PvfsIrpContextClearFlag( PPVFS_IRP_CONTEXT pIrpContext, USHORT BitToClear ) { BOOLEAN bLocked = FALSE; LWIO_LOCK_MUTEX(bLocked, &pIrpContext->Mutex); ClearFlag(pIrpContext->Flags, BitToClear); LWIO_UNLOCK_MUTEX(bLocked, &pIrpContext->Mutex); return; }
BOOLEAN RdrIsShutdownSet( VOID ) { BOOLEAN bLocked = FALSE; BOOLEAN bResult = FALSE; LWIO_LOCK_MUTEX(bLocked, &gRdrRuntime.Lock); bResult = gRdrRuntime.bShutdown; LWIO_UNLOCK_MUTEX(bLocked, &gRdrRuntime.Lock); return bResult; }
static NTSTATUS SMBPacketAllocatePooled( IN PLWIO_PACKET_ALLOCATOR pPacketAllocator, OUT PSMB_PACKET* ppPacket ) { NTSTATUS ntStatus = 0; BOOLEAN bInLock = FALSE; PSMB_PACKET pPacket = NULL; LWIO_LOCK_MUTEX(bInLock, &pPacketAllocator->mutex); if (pPacketAllocator->pFreePacketStack) { pPacket = (PSMB_PACKET) pPacketAllocator->pFreePacketStack; SMBStackPopNoFree(&pPacketAllocator->pFreePacketStack); pPacketAllocator->freePacketCount--; LWIO_UNLOCK_MUTEX(bInLock, &pPacketAllocator->mutex); memset(pPacket, 0, sizeof(SMB_PACKET)); } else { LWIO_UNLOCK_MUTEX(bInLock, &pPacketAllocator->mutex); ntStatus = LwIoAllocateMemory(sizeof(SMB_PACKET), (PVOID *) &pPacket); BAIL_ON_NT_STATUS(ntStatus); } InterlockedIncrement(&pPacket->refCount); *ppPacket = pPacket; cleanup: LWIO_UNLOCK_MUTEX(bInLock, &pPacketAllocator->mutex); return ntStatus; error: *ppPacket = NULL; goto cleanup; }
static BOOLEAN RdrFinishTreeConnect( PRDR_OP_CONTEXT pContext, NTSTATUS status, PVOID pParam ) { PRDR_TREE pTree = pContext->State.TreeConnect.pTree; PSMB_PACKET pResponsePacket = pParam; BOOLEAN bTreeLocked = FALSE; PTREE_CONNECT_EXT_RESPONSE_HEADER pHeader = NULL; LWIO_LOCK_MUTEX(bTreeLocked, &pTree->mutex); BAIL_ON_NT_STATUS(status); status = pResponsePacket->pSMBHeader->error; BAIL_ON_NT_STATUS(status); pTree->tid = pResponsePacket->pSMBHeader->tid; pTree->state = RDR_TREE_STATE_READY; status = UnmarshallTreeConnectExtResponse( pResponsePacket->pParams, pResponsePacket->bufferUsed - (pResponsePacket->pParams - pResponsePacket->pRawBuffer), pResponsePacket->pParams - pResponsePacket->pRawBuffer, &pHeader); BAIL_ON_NT_STATUS(status); pTree->usSupportFlags = pHeader->optionalSupport; cleanup: RdrFreePacket(pResponsePacket); RdrNotifyContextList(&pTree->StateWaiters, bTreeLocked, &pTree->mutex, status, pTree); LWIO_UNLOCK_MUTEX(bTreeLocked, &pTree->mutex); return RdrTreeConnectComplete(pContext, status, pTree); error: LWIO_UNLOCK_MUTEX(bTreeLocked, &pTree->mutex); RdrTreeInvalidate(pTree, status); goto cleanup; }
BOOLEAN PvfsIrpContextCheckFlag( PPVFS_IRP_CONTEXT pIrpContext, USHORT BitToCheck ) { BOOLEAN bLocked = FALSE; BOOLEAN bIsSet = FALSE; LWIO_LOCK_MUTEX(bLocked, &pIrpContext->Mutex); bIsSet = IsSetFlag(pIrpContext->Flags, BitToCheck); LWIO_UNLOCK_MUTEX(bLocked, &pIrpContext->Mutex); return bIsSet; }
NTSTATUS PvfsZctCompleteRead( IN PPVFS_IRP_CONTEXT pIrpContext ) { PPVFS_ZCT_CONTEXT pZctContext = (PPVFS_ZCT_CONTEXT) pIrpContext->pIrp->Args.ReadWrite.ZctCompletionContext; PPVFS_CCB pCcb = pZctContext->pCcb; BOOLEAN bMutexLocked = FALSE; LWIO_LOCK_MUTEX(bMutexLocked, &pCcb->FileMutex); PvfsFreeZctContext(&pZctContext); LWIO_UNLOCK_MUTEX(bMutexLocked, &pCcb->FileMutex); return STATUS_SUCCESS; }
VOID SrvCancelChangeNotify_SMB_V2( PLWIO_ASYNC_STATE pAsyncState ) { BOOLEAN bInLock = FALSE; PSRV_NOTIFY_STATE_SMB_V2 pNotifyState = (PSRV_NOTIFY_STATE_SMB_V2)pAsyncState->hAsyncState; LWIO_LOCK_MUTEX(bInLock, &pNotifyState->mutex); SrvCancelNotifyState_SMB_V2_inlock(pNotifyState); LWIO_UNLOCK_MUTEX(bInLock, &pNotifyState->mutex); }
VOID SrvNotifyStateCancel( HANDLE hNotifyState ) { BOOLEAN bInLock = FALSE; PSRV_CHANGE_NOTIFY_STATE_SMB_V1 pNotifyState = (PSRV_CHANGE_NOTIFY_STATE_SMB_V1)hNotifyState; LWIO_LOCK_MUTEX(bInLock, &pNotifyState->mutex); SrvNotifyStateCancel_inlock(pNotifyState); LWIO_UNLOCK_MUTEX(bInLock, &pNotifyState->mutex); }
VOID RdrNotifyContextList( PLW_LIST_LINKS pList, BOOLEAN bLocked, pthread_mutex_t* pMutex, NTSTATUS status, PVOID pParam ) { LW_LIST_LINKS List; PLW_LIST_LINKS pLink = NULL; BOOLEAN bWasLocked = bLocked; LWIO_LOCK_MUTEX(bLocked, pMutex); LwListInit(&List); while ((pLink = LwListRemoveHead(pList))) { LwListInsertTail(&List, pLink); } LWIO_UNLOCK_MUTEX(bLocked, pMutex); RdrContinueContextList(&List, status, pParam); LWIO_LOCK_MUTEX(bLocked, pMutex); while ((pLink = LwListRemoveHead(&List))) { LwListInsertTail(pList, pLink); } if (!bWasLocked) { LWIO_UNLOCK_MUTEX(bLocked, pMutex); } }
VOID RdrTree2Release( RDR_TREE2 *pTree ) { BOOLEAN bInLock = FALSE; LW_TASK_EVENT_MASK dummy = 0; LONG64 llDummy = 0; LWIO_LOCK_MUTEX(bInLock, &pTree->pSession->mutex); assert(pTree->refCount > 0); if (--pTree->refCount == 0) { if (pTree->state != RDR_TREE_STATE_READY || !RdrSocketIsValid(pTree->pSession->pSocket)) { RdrTree2Unlink(pTree); LWIO_UNLOCK_MUTEX(bInLock, &pTree->pSession->mutex); RdrTree2Free(pTree); } else { LWIO_LOG_VERBOSE("Tree %p is eligible for reaping", pTree); LWIO_UNLOCK_MUTEX(bInLock, &pTree->pSession->mutex); if (LwRtlCreateTask( gRdrRuntime.pThreadPool, &pTree->pTimeout, gRdrRuntime.pTreeTimerGroup, RdrTree2Timeout, pTree) == STATUS_SUCCESS) { LwRtlWakeTask(pTree->pTimeout); } else { LWIO_LOG_ERROR("Could not create timer for tree %p; disconnecting immediately"); RdrTree2Timeout(NULL, pTree, LW_TASK_EVENT_TIME, &dummy, &llDummy); } } } else { LWIO_UNLOCK_MUTEX(bInLock, &pTree->pSession->mutex); } }
static VOID SrvCancelNotifyState_SMB_V2( HANDLE hNotifyState ) { BOOLEAN bInLock = FALSE; PSRV_NOTIFY_STATE_SMB_V2 pNotifyState = (PSRV_NOTIFY_STATE_SMB_V2)hNotifyState; LWIO_LOCK_MUTEX(bInLock, &pNotifyState->mutex); SrvCancelNotifyState_SMB_V2_inlock(pNotifyState); LWIO_UNLOCK_MUTEX(bInLock, &pNotifyState->mutex); }
VOID RdrSwapDomainHints( PLW_HASHMAP* ppMap ) { PLW_HASHMAP pExisting = NULL; BOOLEAN bLocked = FALSE; LWIO_LOCK_MUTEX(bLocked, &gRdrRuntime.Lock); pExisting = gRdrRuntime.pDomainHints; gRdrRuntime.pDomainHints = *ppMap; LWIO_UNLOCK_MUTEX(bLocked, &gRdrRuntime.Lock); *ppMap = pExisting; }
NTSTATUS SrvElementsGetBootTime( PULONG64 pullBootTime ) { LONG64 llBootTime = 0LL; BOOLEAN bInLock = FALSE; LWIO_LOCK_MUTEX(bInLock, &gSrvElements.mutex); llBootTime = gSrvElements.llBootTime; LWIO_UNLOCK_MUTEX(bInLock, &gSrvElements.mutex); *pullBootTime = llBootTime; return STATUS_SUCCESS; }
static BOOLEAN RdrFinishTreeConnect2( PRDR_OP_CONTEXT pContext, NTSTATUS status, PVOID pParam ) { PRDR_TREE2 pTree = pContext->State.TreeConnect.pTree2; PSMB_PACKET pResponsePacket = pParam; BOOLEAN bTreeLocked = FALSE; PRDR_SMB2_TREE_CONNECT_RESPONSE_HEADER pHeader = NULL; LWIO_LOCK_MUTEX(bTreeLocked, &pTree->mutex); BAIL_ON_NT_STATUS(status); status = pResponsePacket->pSMB2Header->error; BAIL_ON_NT_STATUS(status); status = RdrSmb2DecodeTreeConnectResponse(pResponsePacket, &pHeader); BAIL_ON_NT_STATUS(status); pTree->ulTid = pResponsePacket->pSMB2Header->ulTid; pTree->ulCapabilities = pHeader->ulShareCapabilities; pTree->state = RDR_TREE_STATE_READY; cleanup: RdrFreePacket(pResponsePacket); RdrNotifyContextList(&pTree->StateWaiters, bTreeLocked, &pTree->mutex, status, pTree); LWIO_UNLOCK_MUTEX(bTreeLocked, &pTree->mutex); return RdrTreeConnect2Complete(pContext, status, pTree); error: LWIO_UNLOCK_MUTEX(bTreeLocked, &pTree->mutex); RdrTree2Invalidate(pTree, status); goto cleanup; }
static VOID SMBPacketReleasePooled( IN PLWIO_PACKET_ALLOCATOR pPacketAllocator, IN OUT PSMB_PACKET pPacket ) { if (InterlockedDecrement(&pPacket->refCount) == 0) { BOOLEAN bInLock = FALSE; if (pPacket->pRawBuffer) { SMBPacketBufferFree( pPacketAllocator, pPacket->pRawBuffer, pPacket->bufferLen); pPacket->pRawBuffer = NULL; pPacket->bufferLen = 0; } LWIO_LOCK_MUTEX(bInLock, &pPacketAllocator->mutex); /* If the len is greater than our current allocator len, adjust */ /* @todo: make free list configurable */ if (pPacketAllocator->freePacketCount < pPacketAllocator->ulNumMaxPackets) { assert(sizeof(SMB_PACKET) > sizeof(SMB_STACK)); SMBStackPushNoAlloc(&pPacketAllocator->pFreePacketStack, (PSMB_STACK) pPacket); pPacketAllocator->freePacketCount++; } else { LWIO_UNLOCK_MUTEX(bInLock, &pPacketAllocator->mutex); LwIoFreeMemory(pPacket); } LWIO_UNLOCK_MUTEX(bInLock, &pPacketAllocator->mutex); } }
LW_NTSTATUS LwIoGetActiveCreds( IN OPTIONAL LW_PUNICODE_STRING PathPrefix, OUT LW_PIO_CREDS* ppToken ) { NTSTATUS Status = STATUS_SUCCESS; PIO_PATH_CREDS pPathCreds = NULL; PIO_CREDS pCreds = NULL; BOOL bInLock = FALSE; Status = LwIoGetThreadCreds(&pCreds); BAIL_ON_NT_STATUS(Status); if (!pCreds && PathPrefix) { LWIO_LOCK_MUTEX(bInLock, &gLock); Status = LwIoFindPathCreds(PathPrefix, FALSE, &pPathCreds); BAIL_ON_NT_STATUS(Status); if (pPathCreds) { Status = LwIoCopyCreds(pPathCreds->pCreds, &pCreds); BAIL_ON_NT_STATUS(Status); } } if (!pCreds && gpProcessCreds) { Status = LwIoCopyCreds(gpProcessCreds, &pCreds); BAIL_ON_NT_STATUS(Status); } *ppToken = pCreds; error: LWIO_UNLOCK_MUTEX(bInLock, &gLock); return Status; }
static VOID PvfsNotifyFullReportBuffer( PPVFS_FCB pFcb, PPVFS_FCB pReportParentFcb, PPVFS_NOTIFY_REPORT_RECORD pReport ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PLW_LIST_LINKS pFilterLink = NULL; PPVFS_NOTIFY_FILTER_RECORD pFilter = NULL; BOOLEAN bLocked = FALSE; LWIO_LOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); for (pFilterLink = PvfsListTraverse(pFcb->pNotifyListBuffer, NULL); pFilterLink; pFilterLink = PvfsListTraverse(pFcb->pNotifyListBuffer, pFilterLink)) { pFilter = LW_STRUCT_FROM_FIELD( pFilterLink, PVFS_NOTIFY_FILTER_RECORD, NotifyList); /* Match the filter and depth */ if ((pFilter->NotifyFilter & pReport->Filter) && ((pFcb == pReportParentFcb) || pFilter->bWatchTree)) { ntError = PvfsNotifyReportBuffer( &pFilter->Buffer, pReport->Action, pReport->pszFilename); break; } } LWIO_UNLOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); return; }
NTSTATUS SrvFinderGetSearchSpace( IN HANDLE hFinderRepository, IN USHORT usSearchId, OUT PHANDLE phFinder ) { NTSTATUS ntStatus = 0; PSRV_FINDER_REPOSITORY pFinderRepository = NULL; PSRV_SEARCH_SPACE pSearchSpace = NULL; BOOLEAN bInLock = FALSE; pFinderRepository = (PSRV_FINDER_REPOSITORY)hFinderRepository; LWIO_LOCK_MUTEX(bInLock, &pFinderRepository->mutex); ntStatus = LwRtlRBTreeFind( pFinderRepository->pSearchSpaceCollection, &usSearchId, (PVOID*)&pSearchSpace); BAIL_ON_NT_STATUS(ntStatus); InterlockedIncrement(&pSearchSpace->refCount); *phFinder = pSearchSpace; cleanup: LWIO_UNLOCK_MUTEX(bInLock, &pFinderRepository->mutex); return ntStatus; error: *phFinder = NULL; goto cleanup; }
VOID SrvShareDbReleaseContext( PSRV_SHARE_DB_CONTEXT pDbContext ) { BOOLEAN bInLock = FALSE; PSRV_SHARE_DB_GLOBALS pGlobals = &gShareRepository_lwshare; LWIO_LOCK_MUTEX(bInLock, &pGlobals->mutex); if (pGlobals->ulNumDbContexts < pGlobals->ulMaxNumDbContexts) { SrvShareDbFreeContext(pDbContext); } else { pDbContext->pNext = pGlobals->pDbContextList; pGlobals->pDbContextList = pDbContext; pGlobals->ulNumDbContexts++; } LWIO_UNLOCK_MUTEX(bInLock, &pGlobals->mutex); }
static VOID PvfsNotifyCleanIrpList( PVOID pContext ) { PPVFS_IRP_CONTEXT pIrpCtx = (PPVFS_IRP_CONTEXT)pContext; PPVFS_FCB pFcb = NULL; BOOLEAN bFcbLocked = FALSE; PPVFS_NOTIFY_FILTER_RECORD pFilter = NULL; PLW_LIST_LINKS pFilterLink = NULL; PLW_LIST_LINKS pNextLink = NULL; BOOLEAN bFound = FALSE; LWIO_ASSERT(pIrpCtx->pScb->pOwnerFcb); // We have the IrpCtx->Scb's reference so no need to take another pFcb = pIrpCtx->pScb->pOwnerFcb; LWIO_LOCK_MUTEX(bFcbLocked, &pFcb->BaseControlBlock.Mutex); pFilterLink = PvfsListTraverse(pFcb->pNotifyListIrp, NULL); while (pFilterLink) { pFilter = LW_STRUCT_FROM_FIELD( pFilterLink, PVFS_NOTIFY_FILTER_RECORD, NotifyList); pNextLink = PvfsListTraverse(pFcb->pNotifyListIrp, pFilterLink); if (pFilter->pIrpContext != pIrpCtx) { pFilterLink = pNextLink; continue; } bFound = TRUE; PvfsListRemoveItem(pFcb->pNotifyListIrp, pFilterLink); pFilterLink = NULL; LWIO_UNLOCK_MUTEX(bFcbLocked, &pFcb->BaseControlBlock.Mutex); pFilter->pIrpContext->pIrp->IoStatusBlock.Status = STATUS_CANCELLED; PvfsCompleteIrpContext(pFilter->pIrpContext); PvfsFreeNotifyRecord(&pFilter); /* Can only be one IrpContext match so we are done */ } LWIO_UNLOCK_MUTEX(bFcbLocked, &pFcb->BaseControlBlock.Mutex); if (!bFound) { pIrpCtx->pIrp->IoStatusBlock.Status = STATUS_CANCELLED; PvfsCompleteIrpContext(pIrpCtx); } if (pIrpCtx) { PvfsReleaseIrpContext(&pIrpCtx); } return; }
static VOID PvfsNotifyFullReportIrp( PPVFS_FCB pFcb, PPVFS_FCB pReportParentFcb, PPVFS_NOTIFY_REPORT_RECORD pReport ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PLW_LIST_LINKS pFilterLink = NULL; PLW_LIST_LINKS pNextLink = NULL; PPVFS_NOTIFY_FILTER_RECORD pFilter = NULL; BOOLEAN bActive = FALSE; BOOLEAN bLocked = FALSE; LWIO_LOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); pFilterLink = PvfsListTraverse(pFcb->pNotifyListIrp, NULL); while(pFilterLink) { pFilter = LW_STRUCT_FROM_FIELD( pFilterLink, PVFS_NOTIFY_FILTER_RECORD, NotifyList); pNextLink = PvfsListTraverse(pFcb->pNotifyListIrp, pFilterLink); /* Continue if we don't match the filter and depth */ if (!((pFilter->NotifyFilter & pReport->Filter) && ((pFcb == pReportParentFcb) || pFilter->bWatchTree))) { pFilter = NULL; pFilterLink = pNextLink; continue; } PvfsListRemoveItem(pFcb->pNotifyListIrp, pFilterLink); LWIO_UNLOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); pFilterLink = NULL; PvfsQueueCancelIrpIfRequested(pFilter->pIrpContext); bActive = PvfsIrpContextMarkIfNotSetFlag( pFilter->pIrpContext, PVFS_IRP_CTX_FLAG_CANCELLED, PVFS_IRP_CTX_FLAG_ACTIVE); if (!bActive) { PvfsFreeNotifyRecord(&pFilter); pFilterLink = pNextLink; continue; } ntError = PvfsNotifyReportIrp( pFilter->pIrpContext, pReport->Action, pReport->pszFilename); BAIL_ON_NT_STATUS(ntError); /* If we have been asked to buffer changes, move the Fitler Record to the buffer list */ if (pFilter->Buffer.Length > 0) { LWIO_LOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); ntError = PvfsListAddTail(pFcb->pNotifyListBuffer, pFilterLink); LWIO_UNLOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); BAIL_ON_NT_STATUS(ntError); pFilter = NULL; } /* We only process on matching IRP */ break; } cleanup: LWIO_UNLOCK_MUTEX(bLocked, &pFcb->BaseControlBlock.Mutex); if (pFilter) { PvfsFreeNotifyRecord(&pFilter); } return; error: goto cleanup; }