diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2015-12-01 14:32:50 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-12-01 14:32:50 +1100 |
commit | e2a91fe5f6a9401c64a85ffeff4090940ec1e6e1 (patch) | |
tree | 6746f226087fb8e37756fa223ebdbdd110fc106f /src | |
parent | 264ec216effa832977bab41cfe095bb8292f5f3c (diff) | |
download | mongo-e2a91fe5f6a9401c64a85ffeff4090940ec1e6e1.tar.gz |
WT-2251 Free addresses when we discard deleted page references.
There was a lot of repeated code to check for offpage and free ref->addr, create an inlined function.
Diffstat (limited to 'src')
-rw-r--r-- | src/btree/bt_discard.c | 6 | ||||
-rw-r--r-- | src/btree/bt_slvg.c | 6 | ||||
-rw-r--r-- | src/btree/bt_split.c | 1 | ||||
-rw-r--r-- | src/evict/evict_page.c | 10 | ||||
-rw-r--r-- | src/include/btree.i | 16 | ||||
-rw-r--r-- | src/reconcile/rec_write.c | 14 |
6 files changed, 24 insertions, 29 deletions
diff --git a/src/btree/bt_discard.c b/src/btree/bt_discard.c index 7cd97831044..54d9761c487 100644 --- a/src/btree/bt_discard.c +++ b/src/btree/bt_discard.c @@ -269,11 +269,7 @@ __wt_free_ref( * 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); - } + __wt_ref_free_addr(session, ref); /* Free any page-deleted information. */ if (ref->page_del != NULL) { diff --git a/src/btree/bt_slvg.c b/src/btree/bt_slvg.c index 80e467b5707..39a5e5c4f91 100644 --- a/src/btree/bt_slvg.c +++ b/src/btree/bt_slvg.c @@ -1290,8 +1290,7 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) * would have been lost.) Clear the reference addr so eviction doesn't * free the underlying blocks. */ - __wt_free(session, ((WT_ADDR *)ref->addr)->addr); - __wt_free(session, ref->addr); + __wt_ref_free_addr(session, ref); ref->addr = NULL; /* Write the new version of the leaf page to disk. */ @@ -2013,8 +2012,7 @@ __slvg_row_build_leaf( * would have been lost.) Clear the reference addr so eviction doesn't * free the underlying blocks. */ - __wt_free(session, ((WT_ADDR *)ref->addr)->addr); - __wt_free(session, ref->addr); + __wt_ref_free_addr(session, ref); ref->addr = NULL; /* Write the new version of the leaf page to disk. */ diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index a0dfbf32cad..862a683645e 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -895,6 +895,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, */ WT_ASSERT(session, next_ref->page_del == NULL); + __wt_ref_free_addr(session, next_ref); WT_TRET(__split_safe_free( session, split_gen, exclusive, next_ref, sizeof(WT_REF))); parent_decr += sizeof(WT_REF); diff --git a/src/evict/evict_page.c b/src/evict/evict_page.c index 26ea9117fae..6d02c5cec49 100644 --- a/src/evict/evict_page.c +++ b/src/evict/evict_page.c @@ -250,10 +250,7 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) switch (mod->rec_result) { case WT_PM_REC_EMPTY: /* Page is empty */ /* Discard the parent's address. */ - if (ref->addr != NULL && __wt_off_page(parent, ref->addr)) { - __wt_free(session, ((WT_ADDR *)ref->addr)->addr); - __wt_free(session, ref->addr); - } + __wt_ref_free_addr(session, ref); /* * Update the parent to reference a deleted page. The fact that @@ -308,10 +305,7 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) return (EBUSY); /* Discard the parent's address. */ - if (ref->addr != NULL && __wt_off_page(parent, ref->addr)) { - __wt_free(session, ((WT_ADDR *)ref->addr)->addr); - __wt_free(session, ref->addr); - } + __wt_ref_free_addr(session, ref); /* * Update the parent to reference the replacement page. diff --git a/src/include/btree.i b/src/include/btree.i index 3f8dc08a1da..9db88440225 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -466,6 +466,22 @@ __wt_off_page(WT_PAGE *page, const void *p) } /* + * __wt_ref_free_addr -- + * Free the address in a reference, if necessary. + */ +static inline void +__wt_ref_free_addr(WT_SESSION_IMPL *session, WT_REF *ref) +{ + if (ref->addr != NULL) { + if (ref->home == NULL || __wt_off_page(ref->home, ref->addr)) { + __wt_free(session, ((WT_ADDR *)ref->addr)->addr); + __wt_free(session, ref->addr); + } else + ref->addr = NULL; + } +} + +/* * __wt_ref_key -- * Return a reference to a row-store internal page key as cheaply as * possible. diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c index 8bf81eafac2..0e1e7498568 100644 --- a/src/reconcile/rec_write.c +++ b/src/reconcile/rec_write.c @@ -1395,12 +1395,7 @@ __rec_child_deleted(WT_SESSION_IMPL *session, __wt_txn_visible_all(session, page_del->txnid))) { WT_RET(__wt_ref_info(session, ref, &addr, &addr_size, NULL)); WT_RET(__rec_block_free(session, addr, addr_size)); - - if (__wt_off_page(ref->home, ref->addr)) { - __wt_free(session, ((WT_ADDR *)ref->addr)->addr); - __wt_free(session, ref->addr); - } - ref->addr = NULL; + __wt_ref_free_addr(session, ref); } /* @@ -5434,12 +5429,7 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) WT_RET(__wt_ref_info( session, ref, &addr, &addr_size, NULL)); WT_RET(__rec_block_free(session, addr, addr_size)); - if (__wt_off_page(ref->home, ref->addr)) { - __wt_free( - session, ((WT_ADDR *)ref->addr)->addr); - __wt_free(session, ref->addr); - } - ref->addr = NULL; + __wt_ref_free_addr(session, ref); } break; case WT_PM_REC_EMPTY: /* Page deleted */ |