/* * __truncate_file -- * WT_SESSION::truncate for a file. */ static int __truncate_file(WT_SESSION_IMPL *session, const char *name) { WT_DECL_RET; const char *filename; uint32_t allocsize; filename = name; if (!WT_PREFIX_SKIP(filename, "file:")) return (EINVAL); /* Open and lock the file. */ WT_RET(__wt_session_get_btree( session, name, NULL, NULL, WT_DHANDLE_EXCLUSIVE)); /* Get the allocation size. */ allocsize = S2BT(session)->allocsize; WT_RET(__wt_session_release_btree(session)); /* Close any btree handles in the file. */ WT_WITH_DHANDLE_LOCK(session, ret = __wt_conn_dhandle_close_all(session, name, 0)); WT_RET(ret); /* Delete the root address and truncate the file. */ WT_RET(__wt_meta_checkpoint_clear(session, name)); WT_RET(__wt_block_manager_truncate(session, filename, allocsize)); return (0); }
/* * __wt_salvage -- * Salvage a single file. */ int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[]) { WT_CKPT *ckptbase; WT_DATA_HANDLE *dhandle; WT_DECL_RET; dhandle = session->dhandle; /* * XXX * The salvage process reads and discards previous checkpoints, so the * underlying block manager has to ignore any previous checkpoint * entries when creating a new checkpoint, in other words, we can't use * the metadata checkpoint list, it has all of those checkpoint listed * and we don't care about them. Build a clean checkpoint list and use * it instead. * * Don't first clear the metadata checkpoint list and call the function * to get a list of checkpoints: a crash between clearing the metadata * checkpoint list and creating a new checkpoint list would look like a * create or open of a file without a checkpoint to roll-forward from, * and the contents of the file would be discarded. */ WT_RET(__wt_calloc_def(session, 2, &ckptbase)); WT_ERR(__wt_strdup(session, WT_CHECKPOINT, &ckptbase[0].name)); F_SET(&ckptbase[0], WT_CKPT_ADD); WT_ERR(__wt_bt_salvage(session, ckptbase, cfg)); /* * If no checkpoint was created, well, it's probably bad news, but there * is nothing to do but clear any recorded checkpoints for the file. If * a checkpoint was created, life is good, replace any existing list of * checkpoints with the single new one. */ if (ckptbase[0].raw.data == NULL) WT_ERR(__wt_meta_checkpoint_clear(session, dhandle->name)); else WT_ERR(__wt_meta_ckptlist_set( session, dhandle->name, ckptbase, NULL)); err: __wt_meta_ckptlist_free(session, &ckptbase); return (ret); }
/* * __truncate_file -- * WT_SESSION::truncate for a file. */ static int __truncate_file(WT_SESSION_IMPL *session, const char *name) { const char *filename; filename = name; if (!WT_PREFIX_SKIP(filename, "file:")) return (EINVAL); /* Close any btree handles in the file. */ WT_RET(__wt_conn_btree_close_all(session, name)); /* Delete the root address and truncate the file. */ WT_RET(__wt_meta_checkpoint_clear(session, name)); WT_RET(__wt_block_manager_truncate(session, filename)); return (0); }