diff options
author | Luke Chen <luke.chen@mongodb.com> | 2020-03-03 09:09:15 +1100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-03-02 22:31:44 +0000 |
commit | b444815b69ab088a808162bdb4676af2ce00ff2c (patch) | |
tree | e91d196dd09a1a39e9b53fa36690c0a199431647 | |
parent | a8d87c2516057864d9cc5032dd99fb16e9581702 (diff) | |
download | mongo-b444815b69ab088a808162bdb4676af2ce00ff2c.tar.gz |
Import wiredtiger: e1bbf9dee97b40a57383a74c6a0c12422c2bf9a8 from branch mongodb-4.2r4.2.4-rc0r4.2.4
ref: 1769920fec..e1bbf9dee9
for: 4.2.4
Revert below tickets:
WT-5219 Btree walk code read the lock WT_REF.addr field without locking
WT-5481 DIAGNOSTIC split code assert can race with WT_REF locking
WT-5489 page-read can race with threads locking in-memory page structures
WT-5557 Fix the wrong page type returned when checking on-page cell
-rw-r--r-- | src/third_party/wiredtiger/import.data | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_compact.c | 69 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_misc.c | 21 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_split.c | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_vrfy.c | 71 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_walk.c | 12 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/btree.i | 68 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/extern.h | 6 |
8 files changed, 119 insertions, 138 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index bb5c088d28d..de72ebb58f8 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", "branch": "mongodb-4.2", - "commit": "1769920fecd262b69d454dcd023712ea76cfcbfa" + "commit": "e1bbf9dee97b40a57383a74c6a0c12422c2bf9a8" } diff --git a/src/third_party/wiredtiger/src/btree/bt_compact.c b/src/third_party/wiredtiger/src/btree/bt_compact.c index c68ff7cbbd7..649ccf6c39e 100644 --- a/src/third_party/wiredtiger/src/btree/bt_compact.c +++ b/src/third_party/wiredtiger/src/btree/bt_compact.c @@ -10,19 +10,31 @@ /* * __compact_rewrite -- - * Return if a modified page needs to be re-written. + * Return if a page needs to be re-written. */ static int __compact_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) { WT_BM *bm; WT_MULTI *multi; + WT_PAGE *page; WT_PAGE_MODIFY *mod; + size_t addr_size; uint32_t i; + const uint8_t *addr; *skipp = true; /* Default skip. */ bm = S2BT(session)->bm; + page = ref->page; + + /* If the page is clean, test the original addresses. */ + if (__wt_page_evict_clean(page)) { + __wt_ref_info(session, ref, &addr, &addr_size, NULL); + if (addr == NULL) + return (0); + return (bm->compact_page_skip(bm, session, addr, addr_size, skipp)); + } /* * If the page is a replacement, test the replacement addresses. Ignore empty pages, they get @@ -32,7 +44,7 @@ __compact_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) * looking at it, so the page modified structure may appear at any time (but cannot disappear). * We've confirmed there is a page modify structure, it's OK to look at it. */ - mod = ref->page->modify; + mod = page->modify; if (mod->rec_result == WT_PM_REC_REPLACE) return ( bm->compact_page_skip(bm, session, mod->mod_replace.addr, mod->mod_replace.size, skipp)); @@ -51,32 +63,17 @@ __compact_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) /* * __compact_rewrite_lock -- - * Return if a page needs to be re-written. + * Lock out checkpoints and return if a page needs to be re-written. */ static int __compact_rewrite_lock(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) { - WT_BM *bm; WT_BTREE *btree; WT_DECL_RET; - size_t addr_size; - const uint8_t *addr; *skipp = true; /* Default skip. */ btree = S2BT(session); - bm = btree->bm; - - /* - * If the page is clean, test the original addresses. We're holding a hazard pointer on the - * page, so we're safe from eviction, no additional locking is required. - */ - if (__wt_page_evict_clean(ref->page)) { - __wt_ref_info(session, ref, &addr, &addr_size, NULL); - if (addr == NULL) - return (0); - return (bm->compact_page_skip(bm, session, addr, addr_size, skipp)); - } /* * Reviewing in-memory pages requires looking at page reconciliation results, because we care @@ -86,8 +83,8 @@ __compact_rewrite_lock(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) * * There are two ways we call reconciliation: checkpoints and eviction. Get the tree's flush * lock which blocks threads writing pages for checkpoints. If checkpoint is holding the lock, - * quit working this file, we'll visit it again in our next pass. As noted above, we're holding - * a hazard pointer on the page, we're safe from eviction. + * quit working this file, we'll visit it again in our next pass. We don't have to worry about + * eviction, we're holding a hazard pointer on the WT_REF, it's not going anywhere. */ WT_RET(__wt_spin_trylock(session, &btree->flush_lock)); @@ -228,12 +225,12 @@ int __wt_compact_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, void *context, bool *skipp) { WT_BM *bm; + WT_DECL_RET; size_t addr_size; - uint8_t addr[WT_BTREE_MAX_ADDR_COOKIE]; - bool is_leaf; + const uint8_t *addr; + u_int type; WT_UNUSED(context); - *skipp = false; /* Default to reading */ /* @@ -257,17 +254,29 @@ __wt_compact_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, void *context, boo return (0); /* + * There's nothing to prevent the WT_REF state from changing underfoot, which can change its + * address. For example, the WT_REF address might reference an on-page cell, and page eviction + * can free that memory. Lock the WT_REF so we can look at its address. + */ + if (!WT_REF_CAS_STATE(session, ref, WT_REF_DISK, WT_REF_LOCKED)) + return (0); + + /* + * The page is on disk, so there had better be an address; assert that fact, test at run-time to + * avoid the core dump. + * * Internal pages must be read to walk the tree; ask the block-manager if it's useful to rewrite * leaf pages, don't do the I/O if a rewrite won't help. - * - * There can be NULL WT_REF.addr values, where the underlying call won't return a valid address. - * The "it's a leaf page" return is enough to confirm we have a valid address for a leaf page. */ - __wt_ref_info_lock(session, ref, addr, &addr_size, &is_leaf); - if (is_leaf) { + __wt_ref_info(session, ref, &addr, &addr_size, &type); + WT_ASSERT(session, addr != NULL); + if (addr != NULL && type != WT_CELL_ADDR_INT) { bm = S2BT(session)->bm; - return (bm->compact_page_skip(bm, session, addr, addr_size, skipp)); + ret = bm->compact_page_skip(bm, session, addr, addr_size, skipp); } - return (0); + /* Reset the WT_REF state. */ + WT_REF_SET_STATE(ref, WT_REF_DISK); + + return (ret); } diff --git a/src/third_party/wiredtiger/src/btree/bt_misc.c b/src/third_party/wiredtiger/src/btree/bt_misc.c index d5ce78e23aa..c6ea0083a40 100644 --- a/src/third_party/wiredtiger/src/btree/bt_misc.c +++ b/src/third_party/wiredtiger/src/btree/bt_misc.c @@ -85,6 +85,27 @@ __wt_cell_type_string(uint8_t type) } /* + * __wt_page_addr_string -- + * Figure out a page's "address" and load a buffer with a printable, nul-terminated + * representation of that address. + */ +const char * +__wt_page_addr_string(WT_SESSION_IMPL *session, WT_REF *ref, WT_ITEM *buf) +{ + size_t addr_size; + const uint8_t *addr; + + if (__wt_ref_is_root(ref)) { + buf->data = "[Root]"; + buf->size = strlen("[Root]"); + return (buf->data); + } + + __wt_ref_info(session, ref, &addr, &addr_size, NULL); + return (__wt_addr_string(session, addr, addr_size, buf)); +} + +/* * __wt_addr_string -- * Load a buffer with a printable, nul-terminated representation of an address. */ diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c index 3cc0d4018f0..17bfdf40969 100644 --- a/src/third_party/wiredtiger/src/btree/bt_split.c +++ b/src/third_party/wiredtiger/src/btree/bt_split.c @@ -778,13 +778,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, uint32_t */ for (i = 0, deleted_refs = scr->mem; i < deleted_entries; ++i) { next_ref = pindex->index[deleted_refs[i]]; -#ifdef HAVE_DIAGNOSTIC - { - uint32_t ref_state; - WT_ORDERED_READ(ref_state, next_ref->state); - WT_ASSERT(session, ref_state == WT_REF_LOCKED || ref_state == WT_REF_SPLIT); - } -#endif + WT_ASSERT(session, next_ref->state == WT_REF_SPLIT); /* * We set the WT_REF to split, discard it, freeing any resources it holds. diff --git a/src/third_party/wiredtiger/src/btree/bt_vrfy.c b/src/third_party/wiredtiger/src/btree/bt_vrfy.c index ea134802bdd..976aceb4cb4 100644 --- a/src/third_party/wiredtiger/src/btree/bt_vrfy.c +++ b/src/third_party/wiredtiger/src/btree/bt_vrfy.c @@ -303,27 +303,6 @@ __verify_checkpoint_reset(WT_VSTUFF *vs) } /* - * __verify_addr_string -- - * Figure out a page's "address" and load a buffer with a printable, nul-terminated - * representation of that address. - */ -static const char * -__verify_addr_string(WT_SESSION_IMPL *session, WT_REF *ref, WT_ITEM *buf) -{ - size_t addr_size; - const uint8_t *addr; - - if (__wt_ref_is_root(ref)) { - buf->data = "[Root]"; - buf->size = strlen("[Root]"); - return (buf->data); - } - - __wt_ref_info(session, ref, &addr, &addr_size, NULL); - return (__wt_addr_string(session, addr, addr_size, buf)); -} - -/* * __verify_addr_ts -- * Check an address block's timestamps. */ @@ -336,26 +315,26 @@ __verify_addr_ts(WT_SESSION_IMPL *session, WT_REF *ref, WT_CELL_UNPACK *unpack, WT_RET_MSG(session, WT_ERROR, "internal page reference at %s has a newest stop " "timestamp of 0", - __verify_addr_string(session, ref, vs->tmp1)); + __wt_page_addr_string(session, ref, vs->tmp1)); if (unpack->oldest_start_ts > unpack->newest_stop_ts) WT_RET_MSG(session, WT_ERROR, "internal page reference at %s has an oldest start " "timestamp %s newer than its newest stop timestamp %s", - __verify_addr_string(session, ref, vs->tmp1), + __wt_page_addr_string(session, ref, vs->tmp1), __wt_timestamp_to_string(unpack->oldest_start_ts, ts_string[0]), __wt_timestamp_to_string(unpack->newest_stop_ts, ts_string[1])); if (unpack->newest_stop_txn == WT_TXN_NONE) WT_RET_MSG(session, WT_ERROR, "internal page reference at %s has a newest stop " "transaction of 0", - __verify_addr_string(session, ref, vs->tmp1)); + __wt_page_addr_string(session, ref, vs->tmp1)); if (unpack->oldest_start_txn > unpack->newest_stop_txn) WT_RET_MSG(session, WT_ERROR, "internal page reference at %s has an oldest start " "transaction (%" PRIu64 ") newer than its newest stop " "transaction (%" PRIu64 ")", - __verify_addr_string(session, ref, vs->tmp1), unpack->oldest_start_txn, + __wt_page_addr_string(session, ref, vs->tmp1), unpack->oldest_start_txn, unpack->newest_stop_txn); return (0); } @@ -384,12 +363,12 @@ __verify_tree(WT_SESSION_IMPL *session, WT_REF *ref, WT_CELL_UNPACK *addr_unpack unpack = &_unpack; - __wt_verbose(session, WT_VERB_VERIFY, "%s %s", __verify_addr_string(session, ref, vs->tmp1), + __wt_verbose(session, WT_VERB_VERIFY, "%s %s", __wt_page_addr_string(session, ref, vs->tmp1), __wt_page_type_string(page->type)); /* Optionally dump the address. */ if (vs->dump_address) - WT_RET(__wt_msg(session, "%s %s", __verify_addr_string(session, ref, vs->tmp1), + WT_RET(__wt_msg(session, "%s %s", __wt_page_addr_string(session, ref, vs->tmp1), __wt_page_type_string(page->type))); /* Track the shape of the tree. */ @@ -448,7 +427,7 @@ recno_chk: if (recno != vs->record_total + 1) WT_RET_MSG(session, WT_ERROR, "page at %s has a starting record of %" PRIu64 " when the expected starting record is %" PRIu64, - __verify_addr_string(session, ref, vs->tmp1), recno, vs->record_total + 1); + __wt_page_addr_string(session, ref, vs->tmp1), recno, vs->record_total + 1); break; } switch (page->type) { @@ -498,7 +477,7 @@ celltype_err: WT_RET_MSG(session, WT_ERROR, "page at %s, of type %s, is referenced in " "its parent by a cell of type %s", - __verify_addr_string(session, ref, vs->tmp1), __wt_page_type_string(page->type), + __wt_page_addr_string(session, ref, vs->tmp1), __wt_page_type_string(page->type), __wt_cell_type_string(addr_unpack->raw)); break; } @@ -533,7 +512,7 @@ celltype_err: "%s is %" PRIu64 " and the expected " "starting record number is %" PRIu64, - entry, __verify_addr_string(session, child_ref, vs->tmp1), child_ref->ref_recno, + entry, __wt_page_addr_string(session, child_ref, vs->tmp1), child_ref->ref_recno, vs->record_total + 1); } @@ -615,13 +594,13 @@ __verify_row_int_key_order( " on the page at %s " "sorts before the last key appearing on page %s, earlier " "in the tree: %s, %s", - entry, __verify_addr_string(session, ref, vs->tmp1), (char *)vs->max_addr->data, + entry, __wt_page_addr_string(session, ref, vs->tmp1), (char *)vs->max_addr->data, __wt_buf_set_printable(session, item.data, item.size, vs->tmp2), __wt_buf_set_printable(session, vs->max_key->data, vs->max_key->size, vs->tmp3)); /* Update the largest key we've seen to the key just checked. */ WT_RET(__wt_buf_set(session, vs->max_key, item.data, item.size)); - WT_IGNORE_RET_PTR(__verify_addr_string(session, ref, vs->max_addr)); + WT_IGNORE_RET_PTR(__wt_page_addr_string(session, ref, vs->max_addr)); return (0); } @@ -668,14 +647,14 @@ __verify_row_leaf_key_order(WT_SESSION_IMPL *session, WT_REF *ref, WT_VSTUFF *vs "the first key on the page at %s sorts equal to " "or less than the last key appearing on the page " "at %s, earlier in the tree: %s, %s", - __verify_addr_string(session, ref, vs->tmp2), (char *)vs->max_addr->data, + __wt_page_addr_string(session, ref, vs->tmp2), (char *)vs->max_addr->data, __wt_buf_set_printable(session, vs->tmp1->data, vs->tmp1->size, vs->tmp3), __wt_buf_set_printable(session, vs->max_key->data, vs->max_key->size, vs->tmp4)); } /* Update the largest key we've seen to the last key on this page. */ WT_RET(__wt_row_leaf_key_copy(session, page, page->pg_row + (page->entries - 1), vs->max_key)); - WT_IGNORE_RET_PTR(__verify_addr_string(session, ref, vs->max_addr)); + WT_IGNORE_RET_PTR(__wt_page_addr_string(session, ref, vs->max_addr)); return (0); } @@ -749,7 +728,7 @@ __verify_ts_addr_cmp(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t cell_num, c WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s failed verification with %s " "timestamp of %s, %s the parent's %s timestamp of %s", - cell_num, __verify_addr_string(session, ref, vs->tmp1), ts1_name, ts1_bp, + cell_num, __wt_page_addr_string(session, ref, vs->tmp1), ts1_name, ts1_bp, gt ? "less than" : "greater than", ts2_name, ts2_bp); } @@ -772,7 +751,7 @@ __verify_txn_addr_cmp(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t cell_num, "transaction of %" PRIu64 ", %s the parent's %s transaction of " "%" PRIu64, - cell_num, __verify_addr_string(session, ref, vs->tmp1), txn1_name, txn1, + cell_num, __wt_page_addr_string(session, ref, vs->tmp1), txn1_name, txn1, gt ? "less than" : "greater than", txn2_name, txn2); } @@ -815,7 +794,7 @@ __verify_page_cell( " on page at %s references " "an overflow item at %s that failed " "verification", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1), + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1), __wt_addr_string(session, unpack.data, unpack.size, vs->tmp2)); break; } @@ -833,18 +812,18 @@ __verify_page_cell( WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has a " "newest stop timestamp of 0", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1)); + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1)); if (unpack.newest_stop_txn == WT_TXN_NONE) WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has a " "newest stop transaction of 0", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1)); + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1)); if (unpack.oldest_start_ts > unpack.newest_stop_ts) WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has an " "oldest start timestamp %s newer than " "its newest stop timestamp %s", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1), + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1), __wt_timestamp_to_string(unpack.oldest_start_ts, ts_string[0]), __wt_timestamp_to_string(unpack.newest_stop_ts, ts_string[1])); if (unpack.oldest_start_txn > unpack.newest_stop_txn) { @@ -854,7 +833,7 @@ __verify_page_cell( ") " "newer than its newest stop transaction " "(%" PRIu64 ")", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1), + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1), unpack.oldest_start_txn, unpack.newest_stop_txn); } @@ -879,27 +858,27 @@ __verify_page_cell( WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has a stop " "timestamp of 0", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1)); + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1)); if (unpack.start_ts > unpack.stop_ts) WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has a " "start timestamp %s newer than its stop " "timestamp %s", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1), + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1), __wt_timestamp_to_string(unpack.start_ts, ts_string[0]), __wt_timestamp_to_string(unpack.stop_ts, ts_string[1])); if (unpack.stop_txn == WT_TXN_NONE) WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has a stop " "transaction of 0", - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1)); + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1)); if (unpack.start_txn > unpack.stop_txn) WT_RET_MSG(session, WT_ERROR, "cell %" PRIu32 " on page at %s has a " "start transaction %" PRIu64 "newer than " "its stop transaction %" PRIu64, - cell_num - 1, __verify_addr_string(session, ref, vs->tmp1), unpack.start_txn, + cell_num - 1, __wt_page_addr_string(session, ref, vs->tmp1), unpack.start_txn, unpack.stop_txn); WT_RET(__verify_ts_addr_cmp(session, ref, cell_num - 1, "start", unpack.start_ts, @@ -924,7 +903,7 @@ __verify_page_cell( WT_RET_MSG(session, WT_ERROR, "page at %s, of type %s and referenced in its parent by a " "cell of type %s, contains overflow items", - __verify_addr_string(session, ref, vs->tmp1), __wt_page_type_string(ref->page->type), + __wt_page_addr_string(session, ref, vs->tmp1), __wt_page_type_string(ref->page->type), __wt_cell_type_string(addr_unpack->raw)); return (0); diff --git a/src/third_party/wiredtiger/src/btree/bt_walk.c b/src/third_party/wiredtiger/src/btree/bt_walk.c index 67e9e3e3b82..fda35559942 100644 --- a/src/third_party/wiredtiger/src/btree/bt_walk.c +++ b/src/third_party/wiredtiger/src/btree/bt_walk.c @@ -79,10 +79,16 @@ found: static inline bool __ref_is_leaf(WT_SESSION_IMPL *session, WT_REF *ref) { - bool is_leaf; + size_t addr_size; + const uint8_t *addr; + u_int type; - __wt_ref_info_lock(session, ref, NULL, NULL, &is_leaf); - return (is_leaf); + /* + * If the page has a disk address, we can crack it to figure out if this page is a leaf page or + * not. If there's no address, the page isn't on disk and we don't know the page type. + */ + __wt_ref_info(session, ref, &addr, &addr_size, &type); + return (addr == NULL ? false : type == WT_CELL_ADDR_LEAF || type == WT_CELL_ADDR_LEAF_NO); } /* diff --git a/src/third_party/wiredtiger/src/include/btree.i b/src/third_party/wiredtiger/src/include/btree.i index f39a87d53c9..494546bc8c2 100644 --- a/src/third_party/wiredtiger/src/include/btree.i +++ b/src/third_party/wiredtiger/src/include/btree.i @@ -1053,7 +1053,7 @@ __wt_row_leaf_value(WT_PAGE *page, WT_ROW *rip, WT_ITEM *value) */ static inline void __wt_ref_info( - WT_SESSION_IMPL *session, WT_REF *ref, const uint8_t **addrp, size_t *sizep, bool *is_leafp) + WT_SESSION_IMPL *session, WT_REF *ref, const uint8_t **addrp, size_t *sizep, u_int *typep) { WT_ADDR *addr; WT_CELL_UNPACK *unpack, _unpack; @@ -1072,61 +1072,33 @@ __wt_ref_info( if (addr == NULL) { *addrp = NULL; *sizep = 0; - if (is_leafp != NULL) - *is_leafp = false; + if (typep != NULL) + *typep = 0; } else if (__wt_off_page(page, addr)) { *addrp = addr->addr; *sizep = addr->size; - if (is_leafp != NULL) - *is_leafp = addr->type != WT_ADDR_INT; + if (typep != NULL) + switch (addr->type) { + case WT_ADDR_INT: + *typep = WT_CELL_ADDR_INT; + break; + case WT_ADDR_LEAF: + *typep = WT_CELL_ADDR_LEAF; + break; + case WT_ADDR_LEAF_NO: + *typep = WT_CELL_ADDR_LEAF_NO; + break; + default: + *typep = 0; + break; + } } else { __wt_cell_unpack(session, page, (WT_CELL *)addr, unpack); *addrp = unpack->data; *sizep = unpack->size; - - if (is_leafp != NULL) - *is_leafp = unpack->type != WT_CELL_ADDR_INT; - } -} - -/* - * __wt_ref_info_lock -- - * Lock the WT_REF and return the addr/size and type triplet for a reference. - */ -static inline void -__wt_ref_info_lock( - WT_SESSION_IMPL *session, WT_REF *ref, uint8_t *addr_buf, size_t *sizep, bool *is_leafp) -{ - size_t size; - uint32_t previous_state; - const uint8_t *addr; - bool is_leaf; - - /* - * The WT_REF address references either an on-page cell or in-memory structure, and eviction - * frees both. If our caller is already blocking eviction (either because the WT_REF is locked - * or there's a hazard pointer on the page), no locking is required, and the caller should call - * the underlying function directly. Otherwise, our caller is not blocking eviction and we lock - * here, and copy out the address instead of returning a reference. - */ - for (;; __wt_yield()) { - previous_state = ref->state; - if (previous_state != WT_REF_LOCKED && previous_state != WT_REF_READING && - WT_REF_CAS_STATE(session, ref, previous_state, WT_REF_LOCKED)) - break; + if (typep != NULL) + *typep = unpack->type; } - - __wt_ref_info(session, ref, &addr, &size, &is_leaf); - - if (addr_buf != NULL) { - if (addr != NULL) - memcpy(addr_buf, addr, size); - *sizep = size; - } - if (is_leafp != NULL) - *is_leafp = is_leaf; - - WT_REF_SET_STATE(ref, previous_state); } /* diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h index 4ad93180572..82c4cdb18dc 100644 --- a/src/third_party/wiredtiger/src/include/extern.h +++ b/src/third_party/wiredtiger/src/include/extern.h @@ -58,6 +58,8 @@ extern const char *__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_se WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_json_tokname(int toktype) WT_GCC_FUNC_DECL_ATTRIBUTE( (visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern const char *__wt_page_addr_string(WT_SESSION_IMPL *session, WT_REF *ref, WT_ITEM *buf) + WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_page_type_string(u_int type) WT_GCC_FUNC_DECL_ATTRIBUTE( (visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_session_strerror(WT_SESSION *wt_session, int error) @@ -2138,9 +2140,7 @@ static inline void __wt_rec_incr( WT_SESSION_IMPL *session, WT_RECONCILE *r, uint32_t v, size_t size); static inline void __wt_ref_addr_free(WT_SESSION_IMPL *session, WT_REF *ref); static inline void __wt_ref_info( - WT_SESSION_IMPL *session, WT_REF *ref, const uint8_t **addrp, size_t *sizep, bool *is_leafp); -static inline void __wt_ref_info_lock( - WT_SESSION_IMPL *session, WT_REF *ref, uint8_t *addr_buf, size_t *sizep, bool *is_leafp); + WT_SESSION_IMPL *session, WT_REF *ref, const uint8_t **addrp, size_t *sizep, u_int *typep); static inline void __wt_ref_key(WT_PAGE *page, WT_REF *ref, void *keyp, size_t *sizep); static inline void __wt_ref_key_clear(WT_REF *ref); static inline void __wt_ref_key_onpage_set(WT_PAGE *page, WT_REF *ref, WT_CELL_UNPACK *unpack); |