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