xref: /netbsd-src/lib/libc/db/btree/bt_close.c (revision 4b30c543a0b21e3ba94f2c569e9a82b4fdb2075f)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Mike Olson.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #if defined(LIBC_SCCS) && !defined(lint)
38 /* from: static char sccsid[] = "from: @(#)bt_close.c	8.2 (Berkeley) 9/7/93"; */
39 static char *rcsid = "$Id: bt_close.c,v 1.4 1993/09/09 02:41:20 cgd Exp $";
40 #endif /* LIBC_SCCS and not lint */
41 
42 #include <sys/param.h>
43 
44 #include <errno.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49 
50 #include <db.h>
51 #include "btree.h"
52 
53 static int bt_meta __P((BTREE *));
54 
55 /*
56  * BT_CLOSE -- Close a btree.
57  *
58  * Parameters:
59  *	dbp:	pointer to access method
60  *
61  * Returns:
62  *	RET_ERROR, RET_SUCCESS
63  */
64 int
65 __bt_close(dbp)
66 	DB *dbp;
67 {
68 	BTREE *t;
69 	int fd;
70 
71 	t = dbp->internal;
72 
73 	/* Toss any page pinned across calls. */
74 	if (t->bt_pinned != NULL) {
75 		mpool_put(t->bt_mp, t->bt_pinned, 0);
76 		t->bt_pinned = NULL;
77 	}
78 
79 	/*
80 	 * Delete any already deleted record that we've been saving
81 	 * because the cursor pointed to it.
82 	 */
83 	if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
84 		return (RET_ERROR);
85 
86 	if (__bt_sync(dbp, 0) == RET_ERROR)
87 		return (RET_ERROR);
88 
89 	if (mpool_close(t->bt_mp) == RET_ERROR)
90 		return (RET_ERROR);
91 
92 	if (t->bt_stack)
93 		free(t->bt_stack);
94 	if (t->bt_kbuf)
95 		free(t->bt_kbuf);
96 	if (t->bt_dbuf)
97 		free(t->bt_dbuf);
98 
99 	fd = t->bt_fd;
100 	free(t);
101 	free(dbp);
102 	return (close(fd) ? RET_ERROR : RET_SUCCESS);
103 }
104 
105 /*
106  * BT_SYNC -- sync the btree to disk.
107  *
108  * Parameters:
109  *	dbp:	pointer to access method
110  *
111  * Returns:
112  *	RET_SUCCESS, RET_ERROR.
113  */
114 int
115 __bt_sync(dbp, flags)
116 	const DB *dbp;
117 	u_int flags;
118 {
119 	BTREE *t;
120 	int status;
121 	PAGE *h;
122 	void *p;
123 
124 	t = dbp->internal;
125 
126 	/* Toss any page pinned across calls. */
127 	if (t->bt_pinned != NULL) {
128 		mpool_put(t->bt_mp, t->bt_pinned, 0);
129 		t->bt_pinned = NULL;
130 	}
131 
132 	/* Sync doesn't currently take any flags. */
133 	if (flags != 0) {
134 		errno = EINVAL;
135 		return (RET_ERROR);
136 	}
137 
138 	if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED))
139 		return (RET_SUCCESS);
140 
141 	if (ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
142 		return (RET_ERROR);
143 
144 	/*
145 	 * Nastiness.  If the cursor has been marked for deletion, but not
146 	 * actually deleted, we have to make a copy of the page, delete the
147 	 * key/data item, sync the file, and then restore the original page
148 	 * contents.
149 	 */
150 	if (ISSET(t, B_DELCRSR)) {
151 		if ((p = malloc(t->bt_psize)) == NULL)
152 			return (RET_ERROR);
153 		if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
154 			return (RET_ERROR);
155 		memmove(p, h, t->bt_psize);
156 		if ((status =
157 		    __bt_dleaf(t, h, t->bt_bcursor.index)) == RET_ERROR)
158 			goto ecrsr;
159 		mpool_put(t->bt_mp, h, MPOOL_DIRTY);
160 	}
161 
162 	if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
163 		CLR(t, B_MODIFIED);
164 
165 ecrsr:	if (ISSET(t, B_DELCRSR)) {
166 		if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
167 			return (RET_ERROR);
168 		memmove(h, p, t->bt_psize);
169 		free(p);
170 		mpool_put(t->bt_mp, h, MPOOL_DIRTY);
171 	}
172 	return (status);
173 }
174 
175 /*
176  * BT_META -- write the tree meta data to disk.
177  *
178  * Parameters:
179  *	t:	tree
180  *
181  * Returns:
182  *	RET_ERROR, RET_SUCCESS
183  */
184 static int
185 bt_meta(t)
186 	BTREE *t;
187 {
188 	BTMETA m;
189 	void *p;
190 
191 	if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
192 		return (RET_ERROR);
193 
194 	/* Fill in metadata. */
195 	m.m_magic = BTREEMAGIC;
196 	m.m_version = BTREEVERSION;
197 	m.m_psize = t->bt_psize;
198 	m.m_free = t->bt_free;
199 	m.m_nrecs = t->bt_nrecs;
200 	m.m_flags = t->bt_flags & SAVEMETA;
201 
202 	memmove(p, &m, sizeof(BTMETA));
203 	mpool_put(t->bt_mp, p, MPOOL_DIRTY);
204 	return (RET_SUCCESS);
205 }
206