diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2015-11-26 15:47:10 +1100 |
---|---|---|
committer | Alex Gorrod <alexander.gorrod@mongodb.com> | 2015-11-26 15:47:10 +1100 |
commit | 4e1844c6a28ce5b60ea6a44b81bd04a3f5457940 (patch) | |
tree | d6baf14195968d33d84ba4035126947be8a643fa /src | |
parent | cace179242802786b9ecbdb5f229389c517dd531 (diff) | |
parent | 714ae53068b767f64b90dae503a82dc063f9a25f (diff) | |
download | mongo-4e1844c6a28ce5b60ea6a44b81bd04a3f5457940.tar.gz |
Merge pull request #2324 from wiredtiger/wt-2230-multi-split-error-path
WT-2230: multi-split error path
Diffstat (limited to 'src')
-rw-r--r-- | src/btree/bt_discard.c | 26 | ||||
-rw-r--r-- | src/btree/bt_split.c | 8 | ||||
-rw-r--r-- | src/include/extern.h | 2 |
3 files changed, 24 insertions, 12 deletions
diff --git a/src/btree/bt_discard.c b/src/btree/bt_discard.c index 277cdc60522..13bd943f803 100644 --- a/src/btree/bt_discard.c +++ b/src/btree/bt_discard.c @@ -231,7 +231,7 @@ __free_page_int(WT_SESSION_IMPL *session, WT_PAGE *page) */ void __wt_free_ref( - WT_SESSION_IMPL *session, WT_PAGE *page, WT_REF *ref, bool free_pages) + WT_SESSION_IMPL *session, WT_REF *ref, int page_type, bool free_pages) { WT_IKEY *ikey; @@ -250,8 +250,15 @@ __wt_free_ref( __wt_page_out(session, &ref->page); } - /* Free any key allocation. */ - switch (page->type) { + /* + * Optionally free row-store WT_REF key allocation. Historic versions of + * this code looked in a passed-in page argument, but that is dangerous, + * some of our error-path callers create WT_REF structures without ever + * setting WT_REF.home or having a parent page to which the WT_REF will + * be linked. Those WT_REF structures invariably have instantiated keys, + * (they obviously cannot be on-page keys), and we must free the memory. + */ + switch (page_type) { case WT_PAGE_ROW_INT: case WT_PAGE_ROW_LEAF: if ((ikey = __wt_ref_key_instantiated(ref)) != NULL) @@ -259,8 +266,12 @@ __wt_free_ref( break; } - /* Free any address allocation. */ - if (ref->addr != NULL && __wt_off_page(page, ref->addr)) { + /* + * Free any address allocation; if there's no linked WT_REF page, it + * must be allocated. + */ + if (ref->addr != NULL && + (ref->home == NULL || __wt_off_page(ref->home, ref->addr))) { __wt_free(session, ((WT_ADDR *)ref->addr)->addr); __wt_free(session, ref->addr); } @@ -276,7 +287,7 @@ __wt_free_ref( /* * __wt_free_ref_index -- - * Discard a page index and it's references. + * Discard a page index and its references. */ void __wt_free_ref_index(WT_SESSION_IMPL *session, @@ -288,7 +299,8 @@ __wt_free_ref_index(WT_SESSION_IMPL *session, return; for (i = 0; i < pindex->entries; ++i) - __wt_free_ref(session, page, pindex->index[i], free_pages); + __wt_free_ref( + session, pindex->index[i], page->type, free_pages); __wt_free(session, pindex); } diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index 92ed2b3e559..35c3bfea711 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -1527,7 +1527,7 @@ __split_multi_inmem_final(WT_PAGE *orig, WT_MULTI *multi) * Discard allocated pages after failure. */ static void -__split_multi_inmem_fail(WT_SESSION_IMPL *session, WT_REF *ref) +__split_multi_inmem_fail(WT_SESSION_IMPL *session, WT_PAGE *orig, WT_REF *ref) { /* * We failed creating new in-memory pages. For error-handling reasons, @@ -1537,7 +1537,7 @@ __split_multi_inmem_fail(WT_SESSION_IMPL *session, WT_REF *ref) */ if (ref->page != NULL) { F_SET_ATOMIC(ref->page, WT_PAGE_UPDATE_IGNORE); - __wt_free_ref(session, ref->page, ref, true); + __wt_free_ref(session, ref, orig->type, true); } } @@ -1962,7 +1962,7 @@ __split_multi(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) if (0) { err: for (i = 0; i < new_entries; ++i) - __split_multi_inmem_fail(session, ref_new[i]); + __split_multi_inmem_fail(session, page, ref_new[i]); } __wt_free(session, ref_new); @@ -2072,6 +2072,6 @@ __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref) return (0); -err: __split_multi_inmem_fail(session, &new); +err: __split_multi_inmem_fail(session, page, &new); return (ret); } diff --git a/src/include/extern.h b/src/include/extern.h index 3cbbb7b0072..af8a7aa70e9 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -122,7 +122,7 @@ extern bool __wt_delete_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, bool vi extern int __wt_delete_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref); extern void __wt_ref_out(WT_SESSION_IMPL *session, WT_REF *ref); extern void __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep); -extern void __wt_free_ref( WT_SESSION_IMPL *session, WT_PAGE *page, WT_REF *ref, bool free_pages); +extern void __wt_free_ref( WT_SESSION_IMPL *session, WT_REF *ref, int page_type, bool free_pages); extern void __wt_free_ref_index(WT_SESSION_IMPL *session, WT_PAGE *page, WT_PAGE_INDEX *pindex, bool free_pages); extern void __wt_free_update_list(WT_SESSION_IMPL *session, WT_UPDATE *upd); extern int __wt_btree_open(WT_SESSION_IMPL *session, const char *op_cfg[]); |