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; }
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; }