diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2015-12-01 17:05:36 +1100 |
---|---|---|
committer | Alex Gorrod <alexg@wiredtiger.com> | 2015-12-02 05:46:18 +0000 |
commit | 6feaa2812e1c02fe4b74bcd6c6baeda9f310899b (patch) | |
tree | b8361857a70cd3a7cb236707546e80907b36738f | |
parent | 1da2d3a517392d71e13b7ecdeaa97b01a2627d2d (diff) | |
download | mongo-6feaa2812e1c02fe4b74bcd6c6baeda9f310899b.tar.gz |
Merge pull request #2350 from wiredtiger/WT-2251-ref-addr-leak
(cherry picked from commit e731ef8ab)
Conflicts:
src/btree/bt_discard.c
src/btree/bt_slvg.c
src/btree/bt_split.c
src/evict/evict_page.c
src/reconcile/rec_write.c
-rw-r--r-- | src/btree/bt_split.c | 11 | ||||
-rw-r--r-- | src/include/btree.i | 16 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index 5fc2c4cd89f..c77dfdcf5e3 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -1239,6 +1239,12 @@ __split_insert(WT_SESSION_IMPL *session, WT_REF *ref) child->addr = ref->addr; /* + * The address has moved to the replacement WT_REF. Make sure it isn't + * freed when the original ref is discarded. + */ + ref->addr = NULL; + + /* * Copy the first key from the original page into first ref in the new * parent. Pages created in memory always have a "smallest" insert * list, so look there first. If we don't find one, get the first key @@ -1438,6 +1444,11 @@ __split_insert(WT_SESSION_IMPL *session, WT_REF *ref) return (0); err: if (split_ref[0] != NULL) { + /* + * The address was moved to the replacement WT_REF, restore it. + */ + ref->addr = split_ref[0]->addr; + __wt_free(session, split_ref[0]->key.ikey); __wt_free(session, split_ref[0]); } diff --git a/src/include/btree.i b/src/include/btree.i index 4029b29d207..271284f85a6 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -445,6 +445,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. |