VOID PvfsZctCloseCcb( IN PPVFS_CCB pCcb ) { BOOLEAN bMutexLocked = FALSE; PLW_LIST_LINKS pZctCtxLink = NULL; PLW_LIST_LINKS pNextLink = NULL; PPVFS_ZCT_CONTEXT pZctContext = NULL; LWIO_LOCK_MUTEX(bMutexLocked, &pCcb->FileMutex); pZctCtxLink = PvfsListTraverse(pCcb->pZctContextList, NULL); while (pZctCtxLink) { pZctContext = LW_STRUCT_FROM_FIELD( pZctCtxLink, PVFS_ZCT_CONTEXT, CcbLinks); pNextLink = PvfsListTraverse(pCcb->pZctContextList, pZctCtxLink); PvfsListRemoveItem(pCcb->pZctContextList, pZctCtxLink); pZctCtxLink = pNextLink; PvfsFreeZctContext(&pZctContext); } LWIO_UNLOCK_MUTEX(bMutexLocked, &pCcb->FileMutex); }
NTSTATUS PvfsRemoveSCBFromFCB_inlock( IN OUT PPVFS_FCB pFcb, IN PPVFS_SCB pScb ) { NTSTATUS status = STATUS_SUCCESS; if ((pScb->FcbList.Next != NULL) && (pScb->FcbList.Prev != NULL)) { status = PvfsListRemoveItem(pFcb->pScbList, &pScb->FcbList); } return status; }
VOID PvfsFreeZctContext( IN OUT PPVFS_ZCT_CONTEXT *ppZctContext ) { PPVFS_ZCT_CONTEXT pZctContext = *ppZctContext; // pZctContext->pCcb must be locked if the context // is in the CCB list of ZCT contexts. if (pZctContext) { switch (pZctContext->Mode) { case PVFS_ZCT_MODE_MEMORY: PVFS_FREE(&pZctContext->pBuffer); break; #ifdef HAVE_SPLICE case PVFS_ZCT_MODE_SPLICE: if (pZctContext->PipeFds[1] >= 0) { PvfsSysClose(pZctContext->PipeFds[1]); } if (pZctContext->PipeFds[0] >= 0) { PvfsSysClose(pZctContext->PipeFds[0]); } break; #endif default: // can never happen break; } if (pZctContext->pCcb) { PvfsReleaseCCB(pZctContext->pCcb); if (pZctContext->CcbLinks.Next) { PvfsListRemoveItem( pZctContext->pCcb->pZctContextList, &pZctContext->CcbLinks); } } PVFS_FREE(ppZctContext); } }
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; }