static NTSTATUS PvfsNotifyAllocateFilter( PPVFS_NOTIFY_FILTER_RECORD *ppNotifyRecord, PPVFS_IRP_CONTEXT pIrpContext, PPVFS_CCB pCcb, FILE_NOTIFY_CHANGE NotifyFilter, BOOLEAN bWatchTree ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_NOTIFY_FILTER_RECORD pFilter = NULL; ntError = PvfsAllocateMemory( OUT_PPVOID(&pFilter), sizeof(PVFS_NOTIFY_FILTER_RECORD), TRUE); BAIL_ON_NT_STATUS(ntError); pFilter->pIrpContext = PvfsReferenceIrpContext(pIrpContext); pFilter->pCcb = PvfsReferenceCCB(pCcb); pFilter->NotifyFilter = NotifyFilter; pFilter->bWatchTree = bWatchTree; *ppNotifyRecord = pFilter; pFilter = NULL; cleanup: return ntError; error: goto cleanup; }
static NTSTATUS PvfsCreateSetAllocationContext( OUT PPVFS_PENDING_SET_ALLOCATION *ppSetAllocationContext, IN PPVFS_IRP_CONTEXT pIrpContext, IN PPVFS_CCB pCcb ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_PENDING_SET_ALLOCATION pSetAllocationCtx = NULL; ntError = PvfsAllocateMemory( (PVOID*)&pSetAllocationCtx, sizeof(PVFS_PENDING_READ)); BAIL_ON_NT_STATUS(ntError); pSetAllocationCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext); pSetAllocationCtx->pCcb = PvfsReferenceCCB(pCcb); *ppSetAllocationContext = pSetAllocationCtx; ntError = STATUS_SUCCESS; cleanup: return ntError; error: goto cleanup; }
static NTSTATUS PvfsCreateSetEndOfFileContext( OUT PPVFS_PENDING_SET_END_OF_FILE *ppSetEndOfFileContext, IN PPVFS_IRP_CONTEXT pIrpContext, IN PPVFS_CCB pCcb ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_PENDING_SET_END_OF_FILE pSetEndOfFileCtx = NULL; ntError = PvfsAllocateMemory( OUT_PPVOID(&pSetEndOfFileCtx), sizeof(PVFS_PENDING_SET_END_OF_FILE), TRUE); BAIL_ON_NT_STATUS(ntError); pSetEndOfFileCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext); pSetEndOfFileCtx->pCcb = PvfsReferenceCCB(pCcb); *ppSetEndOfFileContext = pSetEndOfFileCtx; ntError = STATUS_SUCCESS; cleanup: return ntError; error: goto cleanup; }
static NTSTATUS PvfsCreateReadContext( OUT PPVFS_PENDING_READ *ppReadContext, IN PPVFS_IRP_CONTEXT pIrpContext, IN PPVFS_CCB pCcb ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_PENDING_READ pReadCtx = NULL; ntError = PvfsAllocateMemory( OUT_PPVOID(&pReadCtx), sizeof(PVFS_PENDING_READ), FALSE); BAIL_ON_NT_STATUS(ntError); pReadCtx->pZctContext = NULL; pReadCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext); pReadCtx->pCcb = PvfsReferenceCCB(pCcb); if (IRP_ZCT_OPERATION_PREPARE == pIrpContext->pIrp->Args.ReadWrite.ZctOperation) { ntError = PvfsCreateZctContext( &pReadCtx->pZctContext, pIrpContext, pCcb); BAIL_ON_NT_STATUS(ntError); } *ppReadContext = pReadCtx; ntError = STATUS_SUCCESS; cleanup: return ntError; error: PvfsFreeReadContext(OUT_PPVOID(&pReadCtx)); goto cleanup; }
NTSTATUS PvfsCreateZctContext( OUT PPVFS_ZCT_CONTEXT *ppZctContext, IN PPVFS_IRP_CONTEXT pIrpContext, IN PPVFS_CCB pCcb ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_ZCT_CONTEXT pZctContext = NULL; PVFS_ZCT_MODE ZctMode = gPvfsDriverConfig.ZctMode; if (IRP_ZCT_OPERATION_PREPARE != pIrpContext->pIrp->Args.ReadWrite.ZctOperation) { ntError = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntError); } switch (ZctMode) { case PVFS_ZCT_MODE_MEMORY: #ifdef HAVE_SPLICE case PVFS_ZCT_MODE_SPLICE: #endif break; default: /* So the I/O does a backoff to non-ZCT */ ntError = STATUS_NOT_SUPPORTED; BAIL_ON_NT_STATUS(ntError); } ntError = PvfsAllocateMemory( (PVOID*)&pZctContext, sizeof(*pZctContext)); BAIL_ON_NT_STATUS(ntError); pZctContext->Mode = ZctMode; switch (pZctContext->Mode) { case PVFS_ZCT_MODE_MEMORY: ntError = PvfsAllocateMemory( OUT_PPVOID(&pZctContext->pBuffer), pIrpContext->pIrp->Args.ReadWrite.Length); BAIL_ON_NT_STATUS(ntError); break; #ifdef HAVE_SPLICE case PVFS_ZCT_MODE_SPLICE: if (pIrpContext->pIrp->Args.ReadWrite.Length > SPLICE_PIPE_BUFFER_SIZE) { ntError = STATUS_NOT_SUPPORTED; BAIL_ON_NT_STATUS(ntError); } // TODO: Convert to using pipe2 (Linux). ntError = PvfsSysPipe(pZctContext->PipeFds); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSysSetNonBlocking(pZctContext->PipeFds[0]); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSysSetNonBlocking(pZctContext->PipeFds[1]); BAIL_ON_NT_STATUS(ntError); break; #endif default: // can never happen ntError = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntError); } pZctContext->pCcb = PvfsReferenceCCB(pCcb); ntError = STATUS_SUCCESS; cleanup: *ppZctContext = pZctContext; return ntError; error: /* Backoff to non-ZCT because could not allocate resources */ ntError = STATUS_NOT_SUPPORTED; PvfsFreeZctContext(&pZctContext); goto cleanup; }