diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-04-23 16:44:56 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-04-23 16:44:56 +1000 |
commit | 083ada33a43b740567f409a8da1d00df01bc4449 (patch) | |
tree | d634f367e12b8e43a59b802f4d2206e3bf49a792 | |
parent | 50f69dee7bd605e3c8b2973131e41a7ce7f89089 (diff) | |
download | mongo-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.c | 22 | ||||
-rw-r--r-- | src/btree/bt_walk.c | 11 |
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, |