summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-04-23 16:44:56 +1000
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-04-23 16:44:56 +1000
commit083ada33a43b740567f409a8da1d00df01bc4449 (patch)
treed634f367e12b8e43a59b802f4d2206e3bf49a792
parent50f69dee7bd605e3c8b2973131e41a7ce7f89089 (diff)
downloadmongo-083ada33a43b740567f409a8da1d00df01bc4449.tar.gz
Finish the fix for the sync / read race.
(These changes should have been committed together with the first set).
-rw-r--r--src/btree/bt_evict.c22
-rw-r--r--src/btree/bt_walk.c11
2 files changed, 20 insertions, 13 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index e35752aef6d..ac8f888f2a5 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -383,6 +383,7 @@ __evict_request_walk(WT_SESSION_IMPL *session)
WT_SESSION_IMPL *request_session;
WT_CACHE *cache;
WT_EVICT_REQ *er, *er_end;
+ WT_PAGE *page;
WT_REF *ref;
int ret;
@@ -412,6 +413,16 @@ __evict_request_walk(WT_SESSION_IMPL *session)
*/
__evict_clr_all(session, 0);
+ /* Clear the current eviction point. */
+ page = session->btree->evict_page;
+ while (page != NULL && !WT_PAGE_IS_ROOT(page)) {
+ ref = page->ref;
+ page = page->parent;
+ if (ref->state == WT_REF_EVICT_WALK)
+ ref->state = WT_REF_MEM;
+ }
+ session->btree->evict_page = NULL;
+
/*
* Wait for LRU eviction activity to drain. It is much easier
* to reason about sync or forced eviction if we can be sure
@@ -484,22 +495,11 @@ static int
__evict_file(WT_SESSION_IMPL *session, WT_EVICT_REQ *er)
{
WT_PAGE *next_page, *page;
- WT_REF *ref;
WT_VERBOSE(session, evictserver,
"file request: %s",
(F_ISSET(er, WT_EVICT_REQ_CLOSE) ? "close" : "sync"));
- /* Clear the current eviction point. */
- page = session->btree->evict_page;
- while (page != NULL && !WT_PAGE_IS_ROOT(page)) {
- ref = page->ref;
- page = page->parent;
- if (ref->state == WT_REF_EVICT_WALK)
- ref->state = WT_REF_MEM;
- }
- session->btree->evict_page = NULL;
-
/*
* We can't evict the page just returned to us, it marks our place in
* the tree. So, always stay one page ahead of the page being returned.
diff --git a/src/btree/bt_walk.c b/src/btree/bt_walk.c
index f85a83890e4..e3ce624cbea 100644
--- a/src/btree/bt_walk.c
+++ b/src/btree/bt_walk.c
@@ -109,8 +109,15 @@ descend: for (;;) {
* the page being evicted by another thread while it is
* being evaluated.
*
- * XXX
- * We also return pages in the "evict-force" state.
+ * We also return pages in the "evict-force" state,
+ * which indicates they are waiting on the eviction
+ * server getting to a request. A sync call in the
+ * meantime must write such a page to ensure all
+ * modifications are written. Since this is happening
+ * inside the eviction server, and an LRU walk will
+ * check the state before adding the page to the LRU
+ * queue, there is no way for an evict-force page to
+ * disappear from under us.
*/
if (eviction) {
if (!WT_ATOMIC_CAS(ref->state,