Beispiel #1
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}