summaryrefslogtreecommitdiff
path: root/src/btree/bt_sync.c
blob: 69e8662ae240350a0bdcc5369e057bc42786b898 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*-
 * Copyright (c) 2008-2013 WiredTiger, Inc.
 *	All rights reserved.
 *
 * See the file LICENSE for redistribution information.
 */

#include "wt_internal.h"

/*
 * __wt_bt_cache_force_write --
 *	Dirty the root page of the tree so it gets written.
 */
int
__wt_bt_cache_force_write(WT_SESSION_IMPL *session)
{
	WT_BTREE *btree;
	WT_PAGE *page;

	btree = session->btree;
	page = btree->root_page;

	/* Dirty the root page to ensure a write. */
	WT_RET(__wt_page_modify_init(session, page));
	__wt_page_modify_set(session, page);

	return (0);
}

/*
 * __wt_bt_cache_flush --
 *	Write dirty pages from the cache, optionally discarding the file.
 */
int
__wt_bt_cache_flush(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, int op)
{
	WT_DECL_RET;
	WT_BTREE *btree;

	btree = session->btree;

	/*
	 * Flush dirty pages, and optionally discard the file from the cache.
	 *
	 * Reconciliation is just another reader of the page, so with some
	 * care, it can be done in the current thread, leaving the eviction
	 * thread to keep freeing spaces if the cache is full.  Sync and
	 * eviction cannot operate on the same page at the same time, and there
	 * are different modes inside __wt_tree_walk to make sure they don't
	 * trip over each other.
	 *
	 * A further complication is that pages that appear in a checkpoint
	 * cannot be freed until the block lists for the checkpoint are stable.
	 * This is dealt with this by locking out eviction of dirty pages while
	 * writing the internal nodes of a tree.
	 */

	/*
	 * XXX
	 * Set the checkpoint reference for reconciliation -- this is ugly,
	 * but there's no data structure path from here to reconciliation.
	 * Publish: there must be a barrier to ensure the structure fields are
	 * set before the eviction thread can see the request.
	 */
	WT_PUBLISH(btree->ckpt, ckptbase);

	/* Ordinary checkpoints are done in the calling thread. */
	if (op == WT_SYNC_INTERNAL || op == WT_SYNC_LEAF)
		ret = __wt_sync_file(session, op);
	else {
		/*
		 * Schedule and wake the eviction server, then wait for the
		 * eviction server to wake us.
		 */
		WT_ERR(__wt_sync_file_serial(session, op));
		WT_ERR(__wt_evict_server_wake(session));
		WT_ERR(__wt_cond_wait(session, session->cond, 0));
		ret = session->syncop_ret;
	}

	switch (op) {
	case WT_SYNC_DISCARD:
	case WT_SYNC_DISCARD_NOWRITE:
		/* If discarding the tree, the root page should be gone. */
		WT_ASSERT(session, ret != 0 || btree->root_page == NULL);
		break;
	}

err:	btree->ckpt = NULL;
	return (ret);
}