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