/* * __wt_bm_read -- * Map or read address cookie referenced block into a buffer. */ int __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) { WT_BLOCK *block; wt_off_t offset; uint32_t cksum, size; bool mapped; WT_UNUSED(addr_size); block = bm->block; /* Crack the cookie. */ WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); /* * Map the block if it's possible. */ mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen; if (mapped) { buf->data = (uint8_t *)bm->map + offset; buf->size = size; WT_RET(__wt_mmap_preload(session, buf->data, buf->size)); WT_STAT_FAST_CONN_INCR(session, block_map_read); WT_STAT_FAST_CONN_INCRV(session, block_byte_map_read, size); return (0); } #ifdef HAVE_DIAGNOSTIC /* * In diagnostic mode, verify the block we're about to read isn't on * the available list, or for live systems, the discard list. */ WT_RET(__wt_block_misplaced( session, block, "read", offset, size, bm->is_live)); #endif /* Read the block. */ WT_RET(__wt_block_read_off(session, block, buf, offset, size, cksum)); #ifdef HAVE_POSIX_FADVISE /* Optionally discard blocks from the system's buffer cache. */ if (block->os_cache_max != 0 && (block->os_cache += size) > block->os_cache_max) { WT_DECL_RET; block->os_cache = 0; /* Ignore EINVAL - some file systems don't support the flag. */ if ((ret = posix_fadvise(block->fh->fd, (wt_off_t)0, (wt_off_t)0, POSIX_FADV_DONTNEED)) != 0 && ret != EINVAL) WT_RET_MSG( session, ret, "%s: posix_fadvise", block->name); } #endif return (0); }
/* * __wt_bm_preload -- * Pre-load a page. */ int __wt_bm_preload( WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) { WT_BLOCK *block; WT_DECL_ITEM(tmp); WT_DECL_RET; wt_off_t offset; uint32_t cksum, size; bool mapped; WT_UNUSED(addr_size); block = bm->block; /* * Turn off pre-load when direct I/O is configured for the file, * the kernel cache isn't interesting. */ if (block->fh->direct_io) return (0); WT_STAT_FAST_CONN_INCR(session, block_preload); /* Crack the cookie. */ WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); /* Check for a mapped block. */ mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen; if (mapped) return (__wt_mmap_preload( session, (uint8_t *)bm->map + offset, size)); #ifdef HAVE_POSIX_FADVISE if (posix_fadvise(block->fh->fd, (wt_off_t)offset, (wt_off_t)size, POSIX_FADV_WILLNEED) == 0) return (0); #endif WT_RET(__wt_scr_alloc(session, size, &tmp)); ret = __wt_block_read_off(session, block, tmp, offset, size, cksum); __wt_scr_free(session, &tmp); return (ret); }
/* * __wt_bm_preload -- * Pre-load a page. */ int __wt_bm_preload(WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) { WT_BLOCK *block; WT_DECL_RET; off_t offset; uint32_t cksum, size; int mapped; WT_UNUSED(addr_size); block = bm->block; ret = EINVAL; /* Play games due to conditional compilation */ /* Crack the cookie. */ WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); /* Check for a mapped block. */ mapped = bm->map != NULL && offset + size <= (off_t)bm->maplen; if (mapped) WT_RET(__wt_mmap_preload( session, (uint8_t *)bm->map + offset, size)); else { #ifdef HAVE_POSIX_FADVISE ret = posix_fadvise(block->fh->fd, (off_t)offset, (off_t)size, POSIX_FADV_WILLNEED); #endif if (ret != 0) { WT_DECL_ITEM(tmp); WT_RET(__wt_scr_alloc(session, size, &tmp)); ret = __wt_block_read_off( session, block, tmp, offset, size, cksum); __wt_scr_free(&tmp); WT_RET(ret); } } WT_STAT_FAST_CONN_INCR(session, block_preload); return (0); }
/* * __wt_bm_read -- * Map or read address cookie referenced block into a buffer. */ int __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, uint32_t addr_size) { WT_BLOCK *block; off_t offset; uint32_t size, cksum; int mapped; WT_UNUSED(addr_size); block = bm->block; /* Crack the cookie. */ WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); /* * Clear buffers previously used for mapped memory, we may be forced * to read into this buffer. */ if (F_ISSET(buf, WT_ITEM_MAPPED)) __wt_buf_free(session, buf); /* * If we're going to be able to return mapped memory and the buffer * has allocated memory, discard it. */ mapped = bm->map != NULL && offset + size <= (off_t)bm->maplen; if (buf->mem != NULL && mapped) __wt_buf_free(session, buf); /* Map the block if it's possible. */ if (mapped) { buf->mem = (uint8_t *)bm->map + offset; buf->memsize = size; buf->data = buf->mem; buf->size = size; F_SET(buf, WT_ITEM_MAPPED); WT_RET(__wt_mmap_preload(session, buf->mem, buf->size)); WT_CSTAT_INCR(session, block_map_read); WT_CSTAT_INCRV(session, block_byte_map_read, size); return (0); } /* Read the block. */ WT_RET(__wt_block_read_off(session, block, buf, offset, size, cksum)); #ifdef HAVE_POSIX_FADVISE /* Optionally discard blocks from the system's buffer cache. */ if (block->os_cache_max != 0 && (block->os_cache += size) > block->os_cache_max) { WT_DECL_RET; block->os_cache = 0; if ((ret = posix_fadvise(block->fh->fd, (off_t)0, (off_t)0, POSIX_FADV_DONTNEED)) != 0) WT_RET_MSG( session, ret, "%s: posix_fadvise", block->name); } #endif return (0); }