xref: /csrg-svn/lib/libc/db/btree/bt_close.c (revision 50990)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Mike Olson.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #if defined(LIBC_SCCS) && !defined(lint)
12 static char sccsid[] = "@(#)bt_close.c	5.1 (Berkeley) 09/04/91";
13 #endif /* LIBC_SCCS and not lint */
14 
15 #include <sys/param.h>
16 #include <errno.h>
17 #include <db.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include "btree.h"
23 
24 static int bt_meta __P((BTREE *));
25 
26 /*
27  * BT_CLOSE -- Close a btree.
28  *
29  * Parameters:
30  *	dbp:	pointer to access method
31  *
32  * Returns:
33  *	RET_ERROR, RET_SUCCESS
34  */
35 int
36 __bt_close(dbp)
37 	DB *dbp;
38 {
39 	BTREE *t;
40 	int fd;
41 
42 	t = dbp->internal;
43 
44 	/*
45 	 * Delete any already deleted record that we've been saving
46 	 * because the cursor pointed to it.
47 	 */
48 	if (ISSET(t, BTF_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
49 		return (RET_ERROR);
50 
51 	if (__bt_sync(dbp) == RET_ERROR)
52 		return (RET_ERROR);
53 
54 	if (mpool_close(t->bt_mp) == RET_ERROR)
55 		return (RET_ERROR);
56 
57 	if (t->bt_stack)
58 		free(t->bt_stack);
59 	if (t->bt_kbuf)
60 		free(t->bt_kbuf);
61 	if (t->bt_dbuf)
62 		free(t->bt_dbuf);
63 
64 	fd = t->bt_fd;
65 	free(t);
66 	free(dbp);
67 	return (close(fd) ? RET_ERROR : RET_SUCCESS);
68 }
69 
70 /*
71  * BT_SYNC -- sync the btree to disk.
72  *
73  * Parameters:
74  *	dbp:	pointer to access method
75  *
76  * Returns:
77  *	RET_SUCCESS, RET_ERROR.
78  *
79  * XXX
80  * Currently don't handle a key marked for deletion when the tree is synced.
81  * Should copy the page and write it out instead of the real page.
82  */
83 int
84 __bt_sync(dbp)
85 	const DB *dbp;
86 {
87 	BTREE *t;
88 	int status;
89 
90 	t = dbp->internal;
91 
92 	if (ISSET(t, BTF_INMEM))
93 		return (RET_SUCCESS);
94 
95 	if (ISSET(t, BTF_RDONLY)) {
96 		errno = EPERM;
97 		return (RET_ERROR);
98 	}
99 
100 	if (ISSET(t, BTF_METADIRTY) && bt_meta(t) == RET_ERROR)
101 		return (RET_ERROR);
102 
103 	if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS) {
104 		UNSET(t, BTF_MODIFIED);
105 		return (RET_SUCCESS);
106 	}
107 	return (status);
108 }
109 
110 /*
111  * BT_META -- write the tree meta data to disk.
112  *
113  * Parameters:
114  *	t:	tree
115  *
116  * Returns:
117  *	RET_ERROR, RET_SUCCESS
118  */
119 static int
120 bt_meta(t)
121 	BTREE *t;
122 {
123 	BTMETA m;
124 	void *p;
125 
126 	if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
127 		return (RET_ERROR);
128 
129 	/* Fill in meta structure -- lorder MUST be host-independent. */
130 	m.m_magic = BTREEMAGIC;
131 	m.m_version = BTREEVERSION;
132 	m.m_psize = t->bt_psize;
133 	m.m_free = 0;		/* XXX */
134 	m.m_nrecs = t->bt_nrecs;
135 	m.m_flags = t->bt_flags & SAVEMETA;
136 	m.m_lorder = (u_long)htonl((long)t->bt_lorder);
137 
138 	if (t->bt_lorder != BYTE_ORDER) {
139 		BLSWAP(m.m_magic);
140 		BLSWAP(m.m_version);
141 		BLSWAP(m.m_psize);
142 		BLSWAP(m.m_free);
143 		BLSWAP(m.m_nrecs);
144 		BLSWAP(m.m_flags);
145 	}
146 
147 	bcopy(&m, p, sizeof(BTMETA));
148 	mpool_put(t->bt_mp, p, MPOOL_DIRTY);
149 	return (RET_SUCCESS);
150 }
151