Пример #1
0
static NTSTATUS
PvfsDoZctMemoryReadIo(
    IN PPVFS_ZCT_CONTEXT pZctContext,
    OUT PLW_ZCT_VECTOR pZct,
    IN ULONG BufferLength,
    IN LONG64 Offset,
    OUT PULONG pBytesRead
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    ULONG totalBytesRead = 0;
    LW_ZCT_ENTRY entry = { 0 };

    ntError = PvfsDoReadIo(pZctContext->pCcb,
                           pZctContext->pBuffer,
                           BufferLength,
                           Offset,
                           &totalBytesRead);
    BAIL_ON_NT_STATUS(ntError);

    if (totalBytesRead > 0)
    {
        entry.Type = LW_ZCT_ENTRY_TYPE_MEMORY;
        entry.Length = totalBytesRead;
        entry.Data.Memory.Buffer = pZctContext->pBuffer;

        ntError = LwZctAppend(pZct, &entry, 1);
        BAIL_ON_NT_STATUS(ntError);
    }

cleanup:
    *pBytesRead = totalBytesRead;

    return ntError;

error:
    totalBytesRead = 0;

    goto cleanup;
}
Пример #2
0
static
NTSTATUS
PvfsReadFileWithContext(
    PVOID pContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_PENDING_READ pReadCtx = (PPVFS_PENDING_READ)pContext;
    PIRP pIrp = pReadCtx->pIrpContext->pIrp;
    PPVFS_CCB pCcb = pReadCtx->pCcb;
    ULONG bufLen = pIrp->Args.ReadWrite.Length;
    ULONG Key = pIrp->Args.ReadWrite.Key ? *pIrp->Args.ReadWrite.Key : 0;
    ULONG totalBytesRead = 0;
    ULONG64 Offset = 0;
    BOOLEAN bMutexLocked = FALSE;

    /* Enter critical region - ReadFile() needs to fill
       the buffer atomically while it may take several read()
       calls */

    LWIO_LOCK_MUTEX(bMutexLocked, &pCcb->ControlBlock);

    if (pIrp->Args.ReadWrite.ByteOffset) {
        Offset = *pIrp->Args.ReadWrite.ByteOffset;
    } else {
        off_t offset = 0;

        ntError = PvfsSysLseek(pCcb->fd, 0, SEEK_CUR, &offset);
        BAIL_ON_NT_STATUS(ntError);

        Offset = offset;
    }

    ntError = PvfsCheckLockedRegion(
                  pCcb,
                  PVFS_OPERATION_READ,
                  Key,
                  Offset,
                  bufLen);
    BAIL_ON_NT_STATUS(ntError);

    if (pReadCtx->pZctContext)
    {
        ntError = PvfsDoZctReadIo(pReadCtx->pZctContext,
                                  pIrp->Args.ReadWrite.Zct,
                                  bufLen,
                                  Offset,
                                  &totalBytesRead);
        BAIL_ON_NT_STATUS(ntError);
    }
    else
    {
        ntError = PvfsDoReadIo(pCcb,
                               pIrp->Args.ReadWrite.Buffer,
                               bufLen,
                               Offset,
                               &totalBytesRead);
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Can only get here is the I/O was completed successfully */

    pIrp->IoStatusBlock.BytesTransferred = totalBytesRead;

    if (bufLen == 0)
    {
        ntError = STATUS_SUCCESS;
    }
    else
    {
        ntError = (totalBytesRead > 0) ?
                  STATUS_SUCCESS :
                  STATUS_END_OF_FILE;
    }

    if (pReadCtx->pZctContext && (STATUS_SUCCESS == ntError))
    {
        /* Save the ZCT context for complete */
        pIrp->Args.ReadWrite.ZctCompletionContext = pReadCtx->pZctContext;

        /* Cannot fail */
        ntError = PvfsListAddTail(
                      pCcb->pZctContextList,
                      &pReadCtx->pZctContext->CcbLinks);
        BAIL_ON_NT_STATUS(ntError);

        pReadCtx->pZctContext = NULL;
    }

    pCcb->ChangeEvent |= FILE_NOTIFY_CHANGE_LAST_ACCESS;

cleanup:
    LWIO_UNLOCK_MUTEX(bMutexLocked, &pCcb->ControlBlock);

    return ntError;

error:
    goto cleanup;
}