/* * __evict_force_check -- * Check if a page matches the criteria for forced eviction. */ static bool __evict_force_check(WT_SESSION_IMPL *session, WT_REF *ref) { WT_BTREE *btree; WT_PAGE *page; btree = S2BT(session); page = ref->page; /* Leaf pages only. */ if (WT_PAGE_IS_INTERNAL(page)) return (false); /* * It's hard to imagine a page with a huge memory footprint that has * never been modified, but check to be sure. */ if (page->modify == NULL) return (false); /* Pages are usually small enough, check that first. */ if (page->memory_footprint < btree->splitmempage) return (false); /* * If this session has more than one hazard pointer, eviction will fail * and there is no point trying. */ if (__wt_hazard_count(session, page) > 1) return (false); /* * If we have already tried and the transaction state has not moved on, * eviction is highly likely to fail. */ if (page->modify->last_eviction_id == __wt_txn_oldest_id(session)) return (false); if (page->memory_footprint < btree->maxmempage) return (__wt_leaf_page_can_split(session, page)); /* Trigger eviction on the next page release. */ __wt_page_evict_soon(session, ref); /* Bump the oldest ID, we're about to do some visibility checks. */ WT_IGNORE_RET(__wt_txn_update_oldest(session, 0)); /* If eviction cannot succeed, don't try. */ return (__wt_page_can_evict(session, ref, NULL)); }
/* * __wt_block_read_off -- * Read an addr/size pair referenced block into a buffer. */ int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t checksum) { WT_BLOCK_HEADER *blk, swap; size_t bufsize; uint32_t page_checksum; __wt_verbose(session, WT_VERB_READ, "off %" PRIuMAX ", size %" PRIu32 ", checksum %#" PRIx32, (uintmax_t)offset, size, checksum); WT_STAT_CONN_INCR(session, block_read); WT_STAT_CONN_INCRV(session, block_byte_read, size); /* * Grow the buffer as necessary and read the block. Buffers should be * aligned for reading, but there are lots of buffers (for example, file * cursors have two buffers each, key and value), and it's difficult to * be sure we've found all of them. If the buffer isn't aligned, it's * an easy fix: set the flag and guarantee we reallocate it. (Most of * the time on reads, the buffer memory has not yet been allocated, so * we're not adding any additional processing time.) */ if (F_ISSET(buf, WT_ITEM_ALIGNED)) bufsize = size; else { F_SET(buf, WT_ITEM_ALIGNED); bufsize = WT_MAX(size, buf->memsize + 10); } WT_RET(__wt_buf_init(session, buf, bufsize)); WT_RET(__wt_read(session, block->fh, offset, size, buf->mem)); buf->size = size; /* * We incrementally read through the structure before doing a checksum, * do little- to big-endian handling early on, and then select from the * original or swapped structure as needed. */ blk = WT_BLOCK_HEADER_REF(buf->mem); __wt_block_header_byteswap_copy(blk, &swap); if (swap.checksum == checksum) { blk->checksum = 0; page_checksum = __wt_checksum(buf->mem, F_ISSET(&swap, WT_BLOCK_DATA_CKSUM) ? size : WT_BLOCK_COMPRESS_SKIP); if (page_checksum == checksum) { /* * Swap the page-header as needed; this doesn't belong * here, but it's the best place to catch all callers. */ __wt_page_header_byteswap(buf->mem); return (0); } if (!F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE)) __wt_errx(session, "%s: read checksum error for %" PRIu32 "B block at " "offset %" PRIuMAX ": calculated block checksum " "of %#" PRIx32 " doesn't match expected checksum " "of %#" PRIx32, block->name, size, (uintmax_t)offset, page_checksum, checksum); } else if (!F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE)) __wt_errx(session, "%s: read checksum error for %" PRIu32 "B block at " "offset %" PRIuMAX ": block header checksum " "of %#" PRIx32 " doesn't match expected checksum " "of %#" PRIx32, block->name, size, (uintmax_t)offset, swap.checksum, checksum); if (!F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE)) WT_IGNORE_RET( __wt_bm_corrupt_dump(session, buf, offset, size, checksum)); /* Panic if a checksum fails during an ordinary read. */ F_SET(S2C(session), WT_CONN_DATA_CORRUPTION); if (block->verify || F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE)) return (WT_ERROR); WT_PANIC_RET(session, WT_ERROR, "%s: fatal read error", block->name); }
/* * __wt_cursor_set_value_notsup -- * WT_CURSOR.set_value not-supported. */ void __wt_cursor_set_value_notsup(WT_CURSOR *cursor, ...) { WT_IGNORE_RET(__wt_cursor_notsup(cursor)); }