150995Sbostic /*- 261207Sbostic * Copyright (c) 1990, 1993 361207Sbostic * The Regents of the University of California. All rights reserved. 450995Sbostic * 550995Sbostic * %sccs.include.redist.c% 650995Sbostic */ 750995Sbostic 850995Sbostic #if defined(LIBC_SCCS) && !defined(lint) 9*64461Sbostic static char sccsid[] = "@(#)rec_close.c 8.2 (Berkeley) 09/07/93"; 1050995Sbostic #endif /* LIBC_SCCS and not lint */ 1150995Sbostic 1257462Sbostic #include <sys/types.h> 1350995Sbostic #include <sys/uio.h> 1458748Sbostic #include <sys/mman.h> 1556754Sbostic 1650995Sbostic #include <errno.h> 1757462Sbostic #include <limits.h> 1856754Sbostic #include <stdio.h> 1950995Sbostic #include <unistd.h> 2056754Sbostic 2157933Sbostic #include <db.h> 2251087Sbostic #include "recno.h" 2350995Sbostic 2450995Sbostic /* 2550995Sbostic * __REC_CLOSE -- Close a recno tree. 2650995Sbostic * 2750995Sbostic * Parameters: 2850995Sbostic * dbp: pointer to access method 2950995Sbostic * 3050995Sbostic * Returns: 3150995Sbostic * RET_ERROR, RET_SUCCESS 3250995Sbostic */ 3350995Sbostic int 3450995Sbostic __rec_close(dbp) 3550995Sbostic DB *dbp; 3650995Sbostic { 3754280Sbostic BTREE *t; 3854280Sbostic int rval; 3954280Sbostic 40*64461Sbostic t = dbp->internal; 41*64461Sbostic 42*64461Sbostic /* Toss any page pinned across calls. */ 43*64461Sbostic if (t->bt_pinned != NULL) { 44*64461Sbostic mpool_put(t->bt_mp, t->bt_pinned, 0); 45*64461Sbostic t->bt_pinned = NULL; 46*64461Sbostic } 47*64461Sbostic 4860056Sbostic if (__rec_sync(dbp, 0) == RET_ERROR) 4950995Sbostic return (RET_ERROR); 5054280Sbostic 5154280Sbostic /* Committed to closing. */ 5258748Sbostic rval = RET_SUCCESS; 5360056Sbostic if (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) 5458748Sbostic rval = RET_ERROR; 5558748Sbostic 5660056Sbostic if (!ISSET(t, R_INMEM)) 5760056Sbostic if (ISSET(t, R_CLOSEFP)) { 5858812Sbostic if (fclose(t->bt_rfp)) 5958812Sbostic rval = RET_ERROR; 6058812Sbostic } else 6158812Sbostic if (close(t->bt_rfd)) 6258812Sbostic rval = RET_ERROR; 6358748Sbostic 6454280Sbostic if (__bt_close(dbp) == RET_ERROR) 6558748Sbostic rval = RET_ERROR; 6654280Sbostic 6758748Sbostic return (rval); 6850995Sbostic } 6950995Sbostic 7050995Sbostic /* 7150995Sbostic * __REC_SYNC -- sync the recno tree to disk. 7250995Sbostic * 7350995Sbostic * Parameters: 7450995Sbostic * dbp: pointer to access method 7550995Sbostic * 7650995Sbostic * Returns: 7750995Sbostic * RET_SUCCESS, RET_ERROR. 7850995Sbostic */ 7950995Sbostic int 8060056Sbostic __rec_sync(dbp, flags) 8150995Sbostic const DB *dbp; 8260056Sbostic u_int flags; 8350995Sbostic { 8450995Sbostic struct iovec iov[2]; 8550995Sbostic BTREE *t; 8650995Sbostic DBT data, key; 8751087Sbostic off_t off; 8855312Sbostic recno_t scursor, trec; 8950995Sbostic int status; 9050995Sbostic 9150995Sbostic t = dbp->internal; 9250995Sbostic 93*64461Sbostic /* Toss any page pinned across calls. */ 94*64461Sbostic if (t->bt_pinned != NULL) { 95*64461Sbostic mpool_put(t->bt_mp, t->bt_pinned, 0); 96*64461Sbostic t->bt_pinned = NULL; 97*64461Sbostic } 98*64461Sbostic 9960056Sbostic if (flags == R_RECNOSYNC) 10060056Sbostic return (__bt_sync(dbp, 0)); 10160056Sbostic 10260056Sbostic if (ISSET(t, R_RDONLY | R_INMEM) || !ISSET(t, R_MODIFIED)) 10350995Sbostic return (RET_SUCCESS); 10450995Sbostic 10556702Sbostic /* Read any remaining records into the tree. */ 10660056Sbostic if (!ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 10750995Sbostic return (RET_ERROR); 10850995Sbostic 10950995Sbostic /* Rewind the file descriptor. */ 11056702Sbostic if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) 11150995Sbostic return (RET_ERROR); 11250995Sbostic 11350995Sbostic iov[1].iov_base = "\n"; 11450995Sbostic iov[1].iov_len = 1; 11550995Sbostic scursor = t->bt_rcursor; 11650995Sbostic 11755312Sbostic key.size = sizeof(recno_t); 11855312Sbostic key.data = &trec; 11955312Sbostic 12050995Sbostic status = (dbp->seq)(dbp, &key, &data, R_FIRST); 12150995Sbostic while (status == RET_SUCCESS) { 12250995Sbostic iov[0].iov_base = data.data; 12350995Sbostic iov[0].iov_len = data.size; 12450995Sbostic if (writev(t->bt_rfd, iov, 2) != data.size + 1) 12550995Sbostic return (RET_ERROR); 12650995Sbostic status = (dbp->seq)(dbp, &key, &data, R_NEXT); 12750995Sbostic } 12850995Sbostic t->bt_rcursor = scursor; 12951087Sbostic if (status == RET_ERROR) 13051087Sbostic return (RET_ERROR); 13158748Sbostic if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1) 13251087Sbostic return (RET_ERROR); 13351087Sbostic if (ftruncate(t->bt_rfd, off)) 13451087Sbostic return (RET_ERROR); 13560056Sbostic CLR(t, R_MODIFIED); 13651087Sbostic return (RET_SUCCESS); 13750995Sbostic } 138