158f0484fSRodney W. Grimes /*- 258f0484fSRodney W. Grimes * Copyright (c) 1990, 1993 358f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 458f0484fSRodney W. Grimes * 558f0484fSRodney W. Grimes * This code is derived from software contributed to Berkeley by 658f0484fSRodney W. Grimes * Mike Olson. 758f0484fSRodney W. Grimes * 858f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 958f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 1058f0484fSRodney W. Grimes * are met: 1158f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 1258f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1358f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1458f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1558f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 1658f0484fSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 1758f0484fSRodney W. Grimes * must display the following acknowledgement: 1858f0484fSRodney W. Grimes * This product includes software developed by the University of 1958f0484fSRodney W. Grimes * California, Berkeley and its contributors. 2058f0484fSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 2158f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 2258f0484fSRodney W. Grimes * without specific prior written permission. 2358f0484fSRodney W. Grimes * 2458f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2558f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2658f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2758f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2858f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2958f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3058f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3158f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3258f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3358f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3458f0484fSRodney W. Grimes * SUCH DAMAGE. 3558f0484fSRodney W. Grimes */ 3658f0484fSRodney W. Grimes 3758f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 3858f0484fSRodney W. Grimes static char sccsid[] = "@(#)bt_close.c 8.3 (Berkeley) 2/21/94"; 3958f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 4058f0484fSRodney W. Grimes 4158f0484fSRodney W. Grimes #include <sys/param.h> 4258f0484fSRodney W. Grimes 4358f0484fSRodney W. Grimes #include <errno.h> 4458f0484fSRodney W. Grimes #include <stdio.h> 4558f0484fSRodney W. Grimes #include <stdlib.h> 4658f0484fSRodney W. Grimes #include <string.h> 4758f0484fSRodney W. Grimes #include <unistd.h> 4858f0484fSRodney W. Grimes 4958f0484fSRodney W. Grimes #include <db.h> 5058f0484fSRodney W. Grimes #include "btree.h" 5158f0484fSRodney W. Grimes 5258f0484fSRodney W. Grimes static int bt_meta __P((BTREE *)); 5358f0484fSRodney W. Grimes 5458f0484fSRodney W. Grimes /* 5558f0484fSRodney W. Grimes * BT_CLOSE -- Close a btree. 5658f0484fSRodney W. Grimes * 5758f0484fSRodney W. Grimes * Parameters: 5858f0484fSRodney W. Grimes * dbp: pointer to access method 5958f0484fSRodney W. Grimes * 6058f0484fSRodney W. Grimes * Returns: 6158f0484fSRodney W. Grimes * RET_ERROR, RET_SUCCESS 6258f0484fSRodney W. Grimes */ 6358f0484fSRodney W. Grimes int 6458f0484fSRodney W. Grimes __bt_close(dbp) 6558f0484fSRodney W. Grimes DB *dbp; 6658f0484fSRodney W. Grimes { 6758f0484fSRodney W. Grimes BTREE *t; 6858f0484fSRodney W. Grimes int fd; 6958f0484fSRodney W. Grimes 7058f0484fSRodney W. Grimes t = dbp->internal; 7158f0484fSRodney W. Grimes 7258f0484fSRodney W. Grimes /* Toss any page pinned across calls. */ 7358f0484fSRodney W. Grimes if (t->bt_pinned != NULL) { 7458f0484fSRodney W. Grimes mpool_put(t->bt_mp, t->bt_pinned, 0); 7558f0484fSRodney W. Grimes t->bt_pinned = NULL; 7658f0484fSRodney W. Grimes } 7758f0484fSRodney W. Grimes 7858f0484fSRodney W. Grimes /* 7958f0484fSRodney W. Grimes * Delete any already deleted record that we've been saving 8058f0484fSRodney W. Grimes * because the cursor pointed to it. 8158f0484fSRodney W. Grimes */ 8258f0484fSRodney W. Grimes if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor)) 8358f0484fSRodney W. Grimes return (RET_ERROR); 8458f0484fSRodney W. Grimes 8558f0484fSRodney W. Grimes if (__bt_sync(dbp, 0) == RET_ERROR) 8658f0484fSRodney W. Grimes return (RET_ERROR); 8758f0484fSRodney W. Grimes 8858f0484fSRodney W. Grimes if (mpool_close(t->bt_mp) == RET_ERROR) 8958f0484fSRodney W. Grimes return (RET_ERROR); 9058f0484fSRodney W. Grimes 9158f0484fSRodney W. Grimes if (t->bt_stack) 9258f0484fSRodney W. Grimes free(t->bt_stack); 9358f0484fSRodney W. Grimes if (t->bt_kbuf) 9458f0484fSRodney W. Grimes free(t->bt_kbuf); 9558f0484fSRodney W. Grimes if (t->bt_dbuf) 9658f0484fSRodney W. Grimes free(t->bt_dbuf); 9758f0484fSRodney W. Grimes 9858f0484fSRodney W. Grimes fd = t->bt_fd; 9958f0484fSRodney W. Grimes free(t); 10058f0484fSRodney W. Grimes free(dbp); 10158f0484fSRodney W. Grimes return (close(fd) ? RET_ERROR : RET_SUCCESS); 10258f0484fSRodney W. Grimes } 10358f0484fSRodney W. Grimes 10458f0484fSRodney W. Grimes /* 10558f0484fSRodney W. Grimes * BT_SYNC -- sync the btree to disk. 10658f0484fSRodney W. Grimes * 10758f0484fSRodney W. Grimes * Parameters: 10858f0484fSRodney W. Grimes * dbp: pointer to access method 10958f0484fSRodney W. Grimes * 11058f0484fSRodney W. Grimes * Returns: 11158f0484fSRodney W. Grimes * RET_SUCCESS, RET_ERROR. 11258f0484fSRodney W. Grimes */ 11358f0484fSRodney W. Grimes int 11458f0484fSRodney W. Grimes __bt_sync(dbp, flags) 11558f0484fSRodney W. Grimes const DB *dbp; 11658f0484fSRodney W. Grimes u_int flags; 11758f0484fSRodney W. Grimes { 11858f0484fSRodney W. Grimes BTREE *t; 11958f0484fSRodney W. Grimes int status; 12058f0484fSRodney W. Grimes PAGE *h; 12158f0484fSRodney W. Grimes void *p; 12258f0484fSRodney W. Grimes 12358f0484fSRodney W. Grimes t = dbp->internal; 12458f0484fSRodney W. Grimes 12558f0484fSRodney W. Grimes /* Toss any page pinned across calls. */ 12658f0484fSRodney W. Grimes if (t->bt_pinned != NULL) { 12758f0484fSRodney W. Grimes mpool_put(t->bt_mp, t->bt_pinned, 0); 12858f0484fSRodney W. Grimes t->bt_pinned = NULL; 12958f0484fSRodney W. Grimes } 13058f0484fSRodney W. Grimes 13158f0484fSRodney W. Grimes /* Sync doesn't currently take any flags. */ 13258f0484fSRodney W. Grimes if (flags != 0) { 13358f0484fSRodney W. Grimes errno = EINVAL; 13458f0484fSRodney W. Grimes return (RET_ERROR); 13558f0484fSRodney W. Grimes } 13658f0484fSRodney W. Grimes 13758f0484fSRodney W. Grimes if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED)) 13858f0484fSRodney W. Grimes return (RET_SUCCESS); 13958f0484fSRodney W. Grimes 14058f0484fSRodney W. Grimes if (ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR) 14158f0484fSRodney W. Grimes return (RET_ERROR); 14258f0484fSRodney W. Grimes 14358f0484fSRodney W. Grimes /* 14458f0484fSRodney W. Grimes * Nastiness. If the cursor has been marked for deletion, but not 14558f0484fSRodney W. Grimes * actually deleted, we have to make a copy of the page, delete the 14658f0484fSRodney W. Grimes * key/data item, sync the file, and then restore the original page 14758f0484fSRodney W. Grimes * contents. 14858f0484fSRodney W. Grimes */ 14958f0484fSRodney W. Grimes if (ISSET(t, B_DELCRSR)) { 15058f0484fSRodney W. Grimes if ((p = (void *)malloc(t->bt_psize)) == NULL) 15158f0484fSRodney W. Grimes return (RET_ERROR); 15258f0484fSRodney W. Grimes if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) 15358f0484fSRodney W. Grimes return (RET_ERROR); 15458f0484fSRodney W. Grimes memmove(p, h, t->bt_psize); 15558f0484fSRodney W. Grimes if ((status = 15658f0484fSRodney W. Grimes __bt_dleaf(t, h, t->bt_bcursor.index)) == RET_ERROR) 15758f0484fSRodney W. Grimes goto ecrsr; 15858f0484fSRodney W. Grimes mpool_put(t->bt_mp, h, MPOOL_DIRTY); 15958f0484fSRodney W. Grimes } 16058f0484fSRodney W. Grimes 16158f0484fSRodney W. Grimes if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS) 16258f0484fSRodney W. Grimes CLR(t, B_MODIFIED); 16358f0484fSRodney W. Grimes 16458f0484fSRodney W. Grimes ecrsr: if (ISSET(t, B_DELCRSR)) { 16558f0484fSRodney W. Grimes if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL) 16658f0484fSRodney W. Grimes return (RET_ERROR); 16758f0484fSRodney W. Grimes memmove(h, p, t->bt_psize); 16858f0484fSRodney W. Grimes free(p); 16958f0484fSRodney W. Grimes mpool_put(t->bt_mp, h, MPOOL_DIRTY); 17058f0484fSRodney W. Grimes } 17158f0484fSRodney W. Grimes return (status); 17258f0484fSRodney W. Grimes } 17358f0484fSRodney W. Grimes 17458f0484fSRodney W. Grimes /* 17558f0484fSRodney W. Grimes * BT_META -- write the tree meta data to disk. 17658f0484fSRodney W. Grimes * 17758f0484fSRodney W. Grimes * Parameters: 17858f0484fSRodney W. Grimes * t: tree 17958f0484fSRodney W. Grimes * 18058f0484fSRodney W. Grimes * Returns: 18158f0484fSRodney W. Grimes * RET_ERROR, RET_SUCCESS 18258f0484fSRodney W. Grimes */ 18358f0484fSRodney W. Grimes static int 18458f0484fSRodney W. Grimes bt_meta(t) 18558f0484fSRodney W. Grimes BTREE *t; 18658f0484fSRodney W. Grimes { 18758f0484fSRodney W. Grimes BTMETA m; 18858f0484fSRodney W. Grimes void *p; 18958f0484fSRodney W. Grimes 19058f0484fSRodney W. Grimes if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL) 19158f0484fSRodney W. Grimes return (RET_ERROR); 19258f0484fSRodney W. Grimes 19358f0484fSRodney W. Grimes /* Fill in metadata. */ 19458f0484fSRodney W. Grimes m.m_magic = BTREEMAGIC; 19558f0484fSRodney W. Grimes m.m_version = BTREEVERSION; 19658f0484fSRodney W. Grimes m.m_psize = t->bt_psize; 19758f0484fSRodney W. Grimes m.m_free = t->bt_free; 19858f0484fSRodney W. Grimes m.m_nrecs = t->bt_nrecs; 19958f0484fSRodney W. Grimes m.m_flags = t->bt_flags & SAVEMETA; 20058f0484fSRodney W. Grimes 20158f0484fSRodney W. Grimes memmove(p, &m, sizeof(BTMETA)); 20258f0484fSRodney W. Grimes mpool_put(t->bt_mp, p, MPOOL_DIRTY); 20358f0484fSRodney W. Grimes return (RET_SUCCESS); 20458f0484fSRodney W. Grimes } 205