/* * __wt_block_salvage_end -- * End a file salvage. */ int __wt_block_salvage_end(WT_SESSION_IMPL *session, WT_BLOCK *block) { /* Salvage performs a checkpoint but doesn't start or resolve it. */ WT_ASSERT(session, block->ckpt_state == WT_CKPT_SALVAGE); block->ckpt_state = WT_CKPT_NONE; /* Discard the checkpoint. */ return (__wt_block_checkpoint_unload(session, block, false)); }
/* * __bm_checkpoint_unload -- * Unload a checkpoint point. */ static int __bm_checkpoint_unload(WT_BM *bm, WT_SESSION_IMPL *session) { WT_DECL_RET; /* Unmap any mapped segment. */ if (bm->map != NULL) WT_TRET(__wt_block_unmap(session, bm->block, bm->map, bm->maplen, &bm->mappingcookie)); /* Unload the checkpoint. */ WT_TRET(__wt_block_checkpoint_unload(session, bm->block, !bm->is_live)); return (ret); }
/* * __wt_block_salvage_end -- * End a file salvage. */ int __wt_block_salvage_end(WT_SESSION_IMPL *session, WT_BLOCK *block) { /* Discard the checkpoint. */ return (__wt_block_checkpoint_unload(session, block, 0)); }
/* * __wt_block_checkpoint_load -- * Load a checkpoint. */ int __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *dsk, const uint8_t *addr, uint32_t addr_size, int readonly) { WT_BLOCK_CKPT *ci; WT_DECL_ITEM(tmp); WT_DECL_RET; WT_UNUSED(addr_size); /* * Sometimes we don't find a root page (we weren't given a checkpoint, * or the referenced checkpoint was empty). In that case we return a * root page size of 0. Set that up now. */ dsk->size = 0; ci = &block->live; WT_RET(__wt_block_ckpt_init(session, block, ci, "live", 1)); if (WT_VERBOSE_ISSET(session, ckpt)) { if (addr != NULL) { WT_ERR(__wt_scr_alloc(session, 0, &tmp)); WT_ERR(__ckpt_string(session, block, addr, tmp)); } WT_VERBOSE_ERR(session, ckpt, "%s: load-checkpoint: %s", block->name, addr == NULL ? "[Empty]" : (char *)tmp->data); } /* If not loading a checkpoint from disk, we're done. */ if (addr == NULL || addr_size == 0) return (0); /* Crack the checkpoint cookie. */ if (addr != NULL) WT_ERR(__wt_block_buffer_to_ckpt(session, block, addr, ci)); /* Verify sets up next. */ if (block->verify) WT_ERR(__wt_verify_ckpt_load(session, block, ci)); /* Read, and optionally verify, any root page. */ if (ci->root_offset != WT_BLOCK_INVALID_OFFSET) { WT_ERR(__wt_block_read_off(session, block, dsk, ci->root_offset, ci->root_size, ci->root_cksum)); if (block->verify) { if (tmp == NULL) { WT_ERR(__wt_scr_alloc(session, 0, &tmp)); WT_ERR(__ckpt_string( session, block, addr, tmp)); } WT_ERR( __wt_verify_dsk(session, (char *)tmp->data, dsk)); } } /* * Rolling a checkpoint forward requires the avail list, the blocks from * which we can allocate. */ if (!readonly) WT_ERR( __wt_block_extlist_read_avail(session, block, &ci->avail)); /* * If the checkpoint can be written, that means anything written after * the checkpoint is no longer interesting, truncate the file. Don't * bother checking the avail list for a block at the end of the file, * that was done when the checkpoint was first written (re-writing the * checkpoint might possibly make it relevant here, but it's unlikely * enough that I'm not bothering). */ if (!readonly) { WT_VERBOSE_ERR(session, ckpt, "truncate file to %" PRIuMAX, (uintmax_t)ci->file_size); WT_ERR(__wt_ftruncate(session, block->fh, ci->file_size)); } if (0) { err: (void)__wt_block_checkpoint_unload(session, block); } __wt_scr_free(&tmp); return (ret); }