/*- * Copyright (c) 2014-2015 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * * See the file LICENSE for redistribution information. */ #include "wt_internal.h" /* * __wt_read -- * Read a chunk. */ int __wt_read( WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, size_t len, void *buf) { size_t chunk; ssize_t nr; uint8_t *addr; WT_STAT_FAST_CONN_INCR(session, read_io); WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: read %" WT_SIZET_FMT " bytes at offset %" PRIuMAX, fh->name, len, (uintmax_t)offset)); /* Assert direct I/O is aligned and a multiple of the alignment. */ WT_ASSERT(session, !fh->direct_io || S2C(session)->buffer_alignment == 0 || (!((uintptr_t)buf & (uintptr_t)(S2C(session)->buffer_alignment - 1)) && len >= S2C(session)->buffer_alignment && len % S2C(session)->buffer_alignment == 0)); /* Break reads larger than 1GB into 1GB chunks. */ for (addr = buf; len > 0; addr += nr, len -= (size_t)nr, offset += nr) { chunk = WT_MIN(len, WT_GIGABYTE); if ((nr = pread(fh->fd, addr, chunk, offset)) <= 0) WT_RET_MSG(session, nr == 0 ? WT_ERROR : __wt_errno(), "%s read error: failed to read %" WT_SIZET_FMT " bytes at offset %" PRIuMAX, fh->name, chunk, (uintmax_t)offset); } return (0); } /* * __wt_write -- * Write a chunk. */ int __wt_write(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, size_t len, const void *buf) { size_t chunk; ssize_t nw; const uint8_t *addr; WT_STAT_FAST_CONN_INCR(session, write_io); WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: write %" WT_SIZET_FMT " bytes at offset %" PRIuMAX, fh->name, len, (uintmax_t)offset)); /* Assert direct I/O is aligned and a multiple of the alignment. */ WT_ASSERT(session, !fh->direct_io || S2C(session)->buffer_alignment == 0 || (!((uintptr_t)buf & (uintptr_t)(S2C(session)->buffer_alignment - 1)) && len >= S2C(session)->buffer_alignment && len % S2C(session)->buffer_alignment == 0)); /* Break writes larger than 1GB into 1GB chunks. */ for (addr = buf; len > 0; addr += nw, len -= (size_t)nw, offset += nw) { chunk = WT_MIN(len, WT_GIGABYTE); if ((nw = pwrite(fh->fd, addr, chunk, offset)) < 0) WT_RET_MSG(session, __wt_errno(), "%s write error: failed to write %" WT_SIZET_FMT " bytes at offset %" PRIuMAX, fh->name, chunk, (uintmax_t)offset); } return (0); }