summaryrefslogtreecommitdiff
path: root/src/btree/bt_split.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/btree/bt_split.c')
-rw-r--r--src/btree/bt_split.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index c0c739d68ad..9e45bf10a5c 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -796,7 +796,7 @@ __split_multi_inmem_final(WT_PAGE *orig, WT_MULTI *multi)
uint32_t i, slot;
/*
- * We've successfully created new in-memory pages. For error-handling
+ * We successfully created new in-memory pages. For error-handling
* reasons, we've left the update chains referenced by both the original
* and new pages. We're ready to discard the original page, terminate
* the original page's reference to any update list we moved.
@@ -818,6 +818,25 @@ __split_multi_inmem_final(WT_PAGE *orig, WT_MULTI *multi)
}
/*
+ * __split_multi_inmem_fail --
+ * Discard allocated pages after failure.
+ */
+static void
+__split_multi_inmem_fail(WT_SESSION_IMPL *session, WT_REF *ref)
+{
+ /*
+ * We failed creating new in-memory pages. For error-handling reasons,
+ * we've left the update chains referenced by both the original and
+ * new pages. Discard the new pages, setting a flag so the discard code
+ * doesn't discard the updates on the page.
+ */
+ if (ref->page != NULL) {
+ F_SET_ATOMIC(ref->page, WT_PAGE_UPDATE_IGNORE);
+ __wt_free_ref(session, ref->page, ref, true);
+ }
+}
+
+/*
* __wt_multi_to_ref --
* Move a multi-block list into an array of WT_REF structures.
*/
@@ -1555,6 +1574,7 @@ __wt_split_reverse(WT_SESSION_IMPL *session, WT_REF *ref)
int
__wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref)
{
+ WT_DECL_RET;
WT_PAGE *page;
WT_PAGE_MODIFY *mod;
WT_REF new;
@@ -1573,7 +1593,7 @@ __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref)
* Build the new page.
*/
memset(&new, 0, sizeof(new));
- WT_RET(__split_multi_inmem(session, page, &new, &mod->mod_multi[0]));
+ WT_ERR(__split_multi_inmem(session, page, &new, &mod->mod_multi[0]));
/*
* The rewrite succeeded, we can no longer fail.
@@ -1597,6 +1617,9 @@ __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref)
WT_PUBLISH(ref->state, WT_REF_MEM);
return (0);
+
+err: __split_multi_inmem_fail(session, &new);
+ return (ret);
}
/*
@@ -1655,24 +1678,8 @@ __split_multi(WT_SESSION_IMPL *session, WT_REF *ref, bool closing)
__wt_page_out(session, &page);
if (0) {
-err: /*
- * A note on error handling: when handling unresolved changes,
- * we create new in-memory pages with those unresolved changes.
- * The problem is the new pages are given references to the
- * original page's update lists, and once all of the pages are
- * created, there's a second pass to remove the updates from the
- * original page. If an error occurs, we can't simply free the
- * newly created pages, that would discard the original page's
- * updates. Set a flag so the discard function doesn't discard
- * the updates on the page.
- */
- for (i = 0; i < new_entries; ++i)
- if (ref_new[i]->page != NULL) {
- F_SET_ATOMIC(
- ref_new[i]->page, WT_PAGE_UPDATE_IGNORE);
- __wt_free_ref(session,
- ref_new[i]->page, ref_new[i], true);
- }
+err: for (i = 0; i < new_entries; ++i)
+ __split_multi_inmem_fail(session, ref_new[i]);
}
__wt_free(session, ref_new);