rec_close.c revision 331722
138032Speter/*- 2249729Sgshapiro * Copyright (c) 1990, 1993, 1994 364562Sgshapiro * The Regents of the University of California. All rights reserved. 438032Speter * 538032Speter * Redistribution and use in source and binary forms, with or without 638032Speter * modification, are permitted provided that the following conditions 738032Speter * are met: 838032Speter * 1. Redistributions of source code must retain the above copyright 938032Speter * notice, this list of conditions and the following disclaimer. 1038032Speter * 2. Redistributions in binary form must reproduce the above copyright 1138032Speter * notice, this list of conditions and the following disclaimer in the 1238032Speter * documentation and/or other materials provided with the distribution. 1338032Speter * 4. Neither the name of the University nor the names of its contributors 1464562Sgshapiro * may be used to endorse or promote products derived from this software 15168515Sgshapiro * without specific prior written permission. 1638032Speter * 17249729Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1864562Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1964562Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2064562Sgshapiro * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2164562Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2264562Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23223067Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2464562Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2564562Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2664562Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2764562Sgshapiro * SUCH DAMAGE. 2864562Sgshapiro */ 2994334Sgshapiro 3064562Sgshapiro#if defined(LIBC_SCCS) && !defined(lint) 3164562Sgshapirostatic char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94"; 3264562Sgshapiro#endif /* LIBC_SCCS and not lint */ 3390792Sgshapiro#include <sys/cdefs.h> 34141858Sgshapiro__FBSDID("$FreeBSD: stable/11/lib/libc/db/recno/rec_close.c 331722 2018-03-29 02:50:57Z eadler $"); 3564562Sgshapiro 3638032Speter#include "namespace.h" 3738032Speter#include <sys/types.h> 3838032Speter#include <sys/uio.h> 3938032Speter#include <sys/mman.h> 4038032Speter 4138032Speter#include <errno.h> 4238032Speter#include <limits.h> 4338032Speter#include <stdio.h> 4438032Speter#include <unistd.h> 4538032Speter#include "un-namespace.h" 4638032Speter 4738032Speter#include <db.h> 4838032Speter#include "recno.h" 4938032Speter 5038032Speter/* 5138032Speter * __REC_CLOSE -- Close a recno tree. 5238032Speter * 5338032Speter * Parameters: 5438032Speter * dbp: pointer to access method 5538032Speter * 5638032Speter * Returns: 5738032Speter * RET_ERROR, RET_SUCCESS 5838032Speter */ 5938032Speterint 6038032Speter__rec_close(DB *dbp) 6190792Sgshapiro{ 6238032Speter BTREE *t; 6390792Sgshapiro int status; 6490792Sgshapiro 6538032Speter t = dbp->internal; 6638032Speter 6738032Speter /* Toss any page pinned across calls. */ 6838032Speter if (t->bt_pinned != NULL) { 6938032Speter mpool_put(t->bt_mp, t->bt_pinned, 0); 7038032Speter t->bt_pinned = NULL; 7138032Speter } 7238032Speter 7338032Speter if (__rec_sync(dbp, 0) == RET_ERROR) 7438032Speter return (RET_ERROR); 7590792Sgshapiro 7690792Sgshapiro /* Committed to closing. */ 7738032Speter status = RET_SUCCESS; 7838032Speter if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) 7938032Speter status = RET_ERROR; 8038032Speter 8138032Speter if (!F_ISSET(t, R_INMEM)) { 8238032Speter if (F_ISSET(t, R_CLOSEFP)) { 8338032Speter if (fclose(t->bt_rfp)) 8438032Speter status = RET_ERROR; 8538032Speter } else { 8638032Speter if (_close(t->bt_rfd)) 8738032Speter status = RET_ERROR; 8838032Speter } 8938032Speter } 9038032Speter 9138032Speter if (__bt_close(dbp) == RET_ERROR) 9290792Sgshapiro status = RET_ERROR; 9364562Sgshapiro 9438032Speter return (status); 9538032Speter} 9638032Speter 9738032Speter/* 9838032Speter * __REC_SYNC -- sync the recno tree to disk. 9938032Speter * 10038032Speter * Parameters: 10190792Sgshapiro * dbp: pointer to access method 10294334Sgshapiro * 10338032Speter * Returns: 10438032Speter * RET_SUCCESS, RET_ERROR. 10564562Sgshapiro */ 10638032Speterint 10738032Speter__rec_sync(const DB *dbp, u_int flags) 108168515Sgshapiro{ 10938032Speter struct iovec iov[2]; 11038032Speter BTREE *t; 11138032Speter DBT data, key; 11290792Sgshapiro off_t off; 11338032Speter recno_t scursor, trec; 11438032Speter int status; 11538032Speter 11638032Speter t = dbp->internal; 117203004Sgshapiro 118223067Sgshapiro /* Toss any page pinned across calls. */ 119223067Sgshapiro if (t->bt_pinned != NULL) { 120223067Sgshapiro mpool_put(t->bt_mp, t->bt_pinned, 0); 121223067Sgshapiro t->bt_pinned = NULL; 122223067Sgshapiro } 123223067Sgshapiro 124223067Sgshapiro if (flags == R_RECNOSYNC) 125223067Sgshapiro return (__bt_sync(dbp, 0)); 126223067Sgshapiro 127203004Sgshapiro if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED)) 12838032Speter return (RET_SUCCESS); 12938032Speter 13038032Speter /* Read any remaining records into the tree. */ 13138032Speter if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 13238032Speter return (RET_ERROR); 13338032Speter 13490792Sgshapiro /* Rewind the file descriptor. */ 13538032Speter if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) 13638032Speter return (RET_ERROR); 13790792Sgshapiro 13838032Speter /* Save the cursor. */ 13938032Speter scursor = t->bt_cursor.rcursor; 14090792Sgshapiro 14138032Speter key.size = sizeof(recno_t); 14238032Speter key.data = &trec; 14338032Speter 14438032Speter if (F_ISSET(t, R_FIXLEN)) { 14538032Speter /* 14690792Sgshapiro * We assume that fixed length records are all fixed length. 14738032Speter * Any that aren't are either EINVAL'd or corrected by the 14838032Speter * record put code. 14938032Speter */ 15038032Speter status = (dbp->seq)(dbp, &key, &data, R_FIRST); 151203004Sgshapiro while (status == RET_SUCCESS) { 15290792Sgshapiro if (_write(t->bt_rfd, data.data, data.size) != 15390792Sgshapiro (ssize_t)data.size) 15490792Sgshapiro return (RET_ERROR); 15538032Speter status = (dbp->seq)(dbp, &key, &data, R_NEXT); 15638032Speter } 15764562Sgshapiro } else { 15864562Sgshapiro iov[1].iov_base = &t->bt_bval; 15938032Speter iov[1].iov_len = 1; 16038032Speter 16190792Sgshapiro status = (dbp->seq)(dbp, &key, &data, R_FIRST); 16238032Speter while (status == RET_SUCCESS) { 16364562Sgshapiro iov[0].iov_base = data.data; 16438032Speter iov[0].iov_len = data.size; 165168515Sgshapiro if (_writev(t->bt_rfd, iov, 2) != (ssize_t)(data.size + 1)) 166168515Sgshapiro return (RET_ERROR); 16738032Speter status = (dbp->seq)(dbp, &key, &data, R_NEXT); 168168515Sgshapiro } 169168515Sgshapiro } 17038032Speter 17138032Speter /* Restore the cursor. */ 17238032Speter t->bt_cursor.rcursor = scursor; 17390792Sgshapiro 17438032Speter if (status == RET_ERROR) 17538032Speter return (RET_ERROR); 17638032Speter if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1) 17738032Speter return (RET_ERROR); 178168515Sgshapiro if (ftruncate(t->bt_rfd, off)) 179168515Sgshapiro return (RET_ERROR); 180168515Sgshapiro F_CLR(t, R_MODIFIED); 181168515Sgshapiro return (RET_SUCCESS); 18238032Speter} 18338032Speter