diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-12-18 16:45:06 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-12-18 16:45:06 +1100 |
commit | 1953776ada137f3deae50169bf889d2063b353d3 (patch) | |
tree | 474f24e7801d61669fb60a058b38f27d0cd0bcca /src | |
parent | 224db32b2f4b2add6819473383f525cfaf472470 (diff) | |
download | mongo-1953776ada137f3deae50169bf889d2063b353d3.tar.gz |
Don't try to set and clear session->split_gen in WT_INTL_FOREACH_BEGIN: there are too many of those loops to ensure that none of them skip clearing it. Instead, make sure all calls are wrapped in WT_WITH_APAGE_INDEX.
refs SERVER-16546
Diffstat (limited to 'src')
-rw-r--r-- | src/btree/bt_debug.c | 12 | ||||
-rw-r--r-- | src/btree/bt_handle.c | 4 | ||||
-rw-r--r-- | src/btree/bt_split.c | 3 | ||||
-rw-r--r-- | src/btree/bt_vrfy.c | 3 | ||||
-rw-r--r-- | src/evict/evict_page.c | 72 | ||||
-rw-r--r-- | src/include/btmem.h | 8 | ||||
-rw-r--r-- | src/reconcile/rec_write.c | 6 |
7 files changed, 70 insertions, 38 deletions
diff --git a/src/btree/bt_debug.c b/src/btree/bt_debug.c index ebbb335d3a8..05407537a53 100644 --- a/src/btree/bt_debug.c +++ b/src/btree/bt_debug.c @@ -453,7 +453,8 @@ __wt_debug_tree_shape( if (page == NULL) page = S2BT(session)->root.page; - __debug_tree_shape_worker(ds, page, 0); + WT_WITH_PAGE_INDEX(session, + __debug_tree_shape_worker(ds, page, 0)); __dmsg_wrapup(ds); return (0); @@ -535,6 +536,7 @@ __debug_tree( static int __debug_page(WT_DBG *ds, WT_PAGE *page, uint32_t flags) { + WT_DECL_RET; WT_SESSION_IMPL *session; session = ds->session; @@ -549,14 +551,18 @@ __debug_page(WT_DBG *ds, WT_PAGE *page, uint32_t flags) __debug_page_col_fix(ds, page); break; case WT_PAGE_COL_INT: - WT_RET(__debug_page_col_int(ds, page, flags)); + WT_WITH_PAGE_INDEX(session, + ret = __debug_page_col_int(ds, page, flags)); + WT_RET(ret); break; case WT_PAGE_COL_VAR: if (LF_ISSET(WT_DEBUG_TREE_LEAF)) WT_RET(__debug_page_col_var(ds, page)); break; case WT_PAGE_ROW_INT: - WT_RET(__debug_page_row_int(ds, page, flags)); + WT_WITH_PAGE_INDEX(session, + ret = __debug_page_row_int(ds, page, flags)); + WT_RET(ret); break; case WT_PAGE_ROW_LEAF: if (LF_ISSET(WT_DEBUG_TREE_LEAF)) diff --git a/src/btree/bt_handle.c b/src/btree/bt_handle.c index 6d69bd8fc74..69c9ab27656 100644 --- a/src/btree/bt_handle.c +++ b/src/btree/bt_handle.c @@ -106,7 +106,9 @@ __wt_btree_open(WT_SESSION_IMPL *session, const char *op_cfg[]) session, root_addr, root_addr_size)); /* Warm the cache, if possible. */ - WT_ERR(__btree_preload(session)); + WT_WITH_PAGE_INDEX(session, + ret = __btree_preload(session)); + WT_ERR(ret); /* Get the last record number in a column-store file. */ if (btree->type != BTREE_ROW) diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index c6b97733b69..2af6c806be5 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -900,7 +900,8 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, alloc_index = NULL; #ifdef HAVE_DIAGNOSTIC - __split_verify_intl_key_order(session, parent); + WT_WITH_PAGE_INDEX(session, + __split_verify_intl_key_order(session, parent)); #endif /* diff --git a/src/btree/bt_vrfy.c b/src/btree/bt_vrfy.c index e7caf02fd2f..869fa2bb696 100644 --- a/src/btree/bt_vrfy.c +++ b/src/btree/bt_vrfy.c @@ -122,7 +122,8 @@ __wt_verify(WT_SESSION_IMPL *session, const char *cfg[]) __wt_page_type_string( btree->root.page->type))); #endif - ret = __verify_tree(session, &btree->root, vs); + WT_WITH_PAGE_INDEX(session, + ret = __verify_tree(session, &btree->root, vs)); WT_TRET(__wt_cache_op(session, NULL, WT_SYNC_DISCARD)); } diff --git a/src/evict/evict_page.c b/src/evict/evict_page.c index bc791de6d0f..f7cbb55dbe4 100644 --- a/src/evict/evict_page.c +++ b/src/evict/evict_page.c @@ -75,7 +75,8 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, int exclusive) /* Discard any subtree rooted in this page. */ if (istree) - __evict_discard_tree(session, ref, exclusive, 1); + WT_WITH_PAGE_INDEX(session, + __evict_discard_tree(session, ref, exclusive, 1)); /* Update the reference and discard the page. */ if (mod == NULL || !F_ISSET(mod, WT_PM_REC_MASK)) { @@ -253,6 +254,45 @@ __evict_discard_tree( } /* + * __evict_review_subtree -- + * Review a subtree for conditions that would block its eviction. + */ +static int +__evict_review_subtree(WT_SESSION_IMPL *session, + WT_REF *ref, int exclusive, int *inmem_splitp, int *istreep) +{ + WT_PAGE *page; + WT_REF *child; + + page = ref->page; + + WT_INTL_FOREACH_BEGIN(session, page, child) { + switch (child->state) { + case WT_REF_DISK: /* On-disk */ + case WT_REF_DELETED: /* On-disk, deleted */ + break; + case WT_REF_MEM: /* In-memory */ + /* + * Tell our caller if there's a subtree so we + * know to do a full walk when discarding the + * page. + */ + *istreep = 1; + WT_RET(__evict_review(session, child, exclusive, + 0, inmem_splitp, istreep)); + break; + case WT_REF_LOCKED: /* Being evicted */ + case WT_REF_READING: /* Being read */ + case WT_REF_SPLIT: /* Being split */ + return (EBUSY); + WT_ILLEGAL_VALUE(session); + } + } WT_INTL_FOREACH_END; + + return (0); +} + +/* * __evict_review -- * Get exclusive access to the page and review the page and its subtree * for conditions that would block its eviction. @@ -262,9 +302,9 @@ __evict_review(WT_SESSION_IMPL *session, WT_REF *ref, int exclusive, int top, int *inmem_splitp, int *istreep) { WT_BTREE *btree; + WT_DECL_RET; WT_PAGE *page; WT_PAGE_MODIFY *mod; - WT_REF *child; uint32_t flags; btree = S2BT(session); @@ -292,29 +332,11 @@ __evict_review(WT_SESSION_IMPL *session, WT_REF *ref, * have to write pages in depth-first order, otherwise we'll dirty * pages after we've written them. */ - if (WT_PAGE_IS_INTERNAL(page)) - WT_INTL_FOREACH_BEGIN(session, page, child) { - switch (child->state) { - case WT_REF_DISK: /* On-disk */ - case WT_REF_DELETED: /* On-disk, deleted */ - break; - case WT_REF_MEM: /* In-memory */ - /* - * Tell our caller if there's a subtree so we - * know to do a full walk when discarding the - * page. - */ - *istreep = 1; - WT_RET(__evict_review(session, child, exclusive, - 0, inmem_splitp, istreep)); - break; - case WT_REF_LOCKED: /* Being evicted */ - case WT_REF_READING: /* Being read */ - case WT_REF_SPLIT: /* Being split */ - return (EBUSY); - WT_ILLEGAL_VALUE(session); - } - } WT_INTL_FOREACH_END; + if (WT_PAGE_IS_INTERNAL(page)) { + WT_WITH_PAGE_INDEX(session, ret = __evict_review_subtree( + session, ref, exclusive, inmem_splitp, istreep)); + WT_RET(ret); + } mod = page->modify; diff --git a/src/include/btmem.h b/src/include/btmem.h index 8a3ec9ade89..72feb3dce8f 100644 --- a/src/include/btmem.h +++ b/src/include/btmem.h @@ -424,17 +424,15 @@ struct __wt_page { #define WT_INTL_FOREACH_BEGIN(session, page, ref) do { \ WT_PAGE_INDEX *__pindex; \ WT_REF **__refp; \ - WT_SESSION_IMPL *__session = (session); \ uint32_t __entries; \ - WT_ENTER_PAGE_INDEX(session); \ + WT_ASSERT(session, session->split_gen != 0); \ for (__pindex = WT_INTL_INDEX_COPY(page), \ __refp = __pindex->index, \ __entries = __pindex->entries; __entries > 0; --__entries) {\ (ref) = *__refp++; #define WT_INTL_FOREACH_END \ - } \ - WT_LEAVE_PAGE_INDEX(__session); \ - } while (0) + } \ +} while (0) /* Row-store leaf page. */ struct { diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c index 839ab028afd..6ce8247c2d4 100644 --- a/src/reconcile/rec_write.c +++ b/src/reconcile/rec_write.c @@ -397,13 +397,15 @@ __wt_reconcile(WT_SESSION_IMPL *session, ret = __rec_col_fix(session, r, page); break; case WT_PAGE_COL_INT: - ret = __rec_col_int(session, r, page); + WT_WITH_PAGE_INDEX(session, + ret = __rec_col_int(session, r, page)); break; case WT_PAGE_COL_VAR: ret = __rec_col_var(session, r, page, salvage); break; case WT_PAGE_ROW_INT: - ret = __rec_row_int(session, r, page); + WT_WITH_PAGE_INDEX(session, + ret = __rec_row_int(session, r, page)); break; case WT_PAGE_ROW_LEAF: ret = __rec_row_leaf(session, r, page, salvage); |