Пример #1
0
static NTSTATUS
PvfsQueryFilePositionInfo(
    PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PIRP pIrp = pIrpContext->pIrp;
    PPVFS_CCB pCcb = NULL;
    PFILE_POSITION_INFORMATION pFileInfo = NULL;
    IRP_ARGS_QUERY_SET_INFORMATION Args = pIrpContext->pIrp->Args.QuerySetInformation;
    off_t CurrentOffset = 0;

    /* Sanity checks */

    ntError =  PvfsAcquireCCB(pIrp->FileHandle, &pCcb);
    BAIL_ON_NT_STATUS(ntError);

    BAIL_ON_INVALID_PTR(Args.FileInformation, ntError);

    ntError = PvfsAccessCheckAnyFileHandle(
                  pCcb,
                  (FILE_READ_DATA|FILE_WRITE_DATA));
    BAIL_ON_NT_STATUS(ntError);

    if (Args.Length < sizeof(*pFileInfo))
    {
        ntError = STATUS_BUFFER_TOO_SMALL;
        BAIL_ON_NT_STATUS(ntError);
    }

    pFileInfo = (PFILE_POSITION_INFORMATION)Args.FileInformation;

    /* Real work starts here */

    /* Position */
    ntError = PvfsSysLseek(pCcb->fd, 0, SEEK_CUR, &CurrentOffset);
    BAIL_ON_NT_STATUS(ntError);

    pFileInfo->CurrentByteOffset = CurrentOffset;

    pIrp->IoStatusBlock.BytesTransferred = sizeof(*pFileInfo);
    ntError = STATUS_SUCCESS;

cleanup:

    if (pCcb) {
        PvfsReleaseCCB(pCcb);
    }

    return ntError;

error:
    goto cleanup;
}
Пример #2
0
NTSTATUS
PvfsSysWrite(
    PPVFS_CCB pCcb,
    PVOID pBuffer,
    ULONG pBufLen,
    PULONG64 pOffset,
    PULONG pBytesWritten
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    ssize_t bytesWritten = 0;
    int unixerr = 0;

    /* Use pwrite() if we have an offset, otherwise fall back
       to write() */

    if (pOffset)
    {
        off_t offset = 0;

        bytesWritten = pwrite(pCcb->fd, pBuffer, pBufLen, (off_t)*pOffset);

        if (bytesWritten > 0)
        {
            /* pread() and pwrite() don't update the file offset */
            ntError = PvfsSysLseek(pCcb->fd, bytesWritten, SEEK_CUR, &offset);
            BAIL_ON_NT_STATUS(ntError);
        }
    }
    else
    {
        bytesWritten = write(pCcb->fd, pBuffer, pBufLen);
    }

    if (bytesWritten == -1) {
        PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError);
    }

    *pBytesWritten = (ULONG)bytesWritten;

cleanup:
    return ntError;

error:
    goto cleanup;
}
Пример #3
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;
}