about summary refs log tree commit diff
path: root/db2/mp/mp_bh.c
diff options
context:
space:
mode:
Diffstat (limited to 'db2/mp/mp_bh.c')
-rw-r--r--db2/mp/mp_bh.c176
1 files changed, 92 insertions, 84 deletions
diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c
index d89f9c2ded..12c53417d9 100644
--- a/db2/mp/mp_bh.c
+++ b/db2/mp/mp_bh.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_bh.c	10.38 (Sleepycat) 5/20/98";
+static const char sccsid[] = "@(#)mp_bh.c	10.45 (Sleepycat) 11/25/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -42,11 +42,13 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 {
 	DB_MPOOLFILE *dbmfp;
 	DB_MPREG *mpreg;
+	int incremented, ret;
 
 	if (restartp != NULL)
 		*restartp = 0;
 	if (wrotep != NULL)
 		*wrotep = 0;
+	incremented = 0;
 
 	/*
 	 * Walk the process' DB_MPOOLFILE list and find a file descriptor for
@@ -63,6 +65,13 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 				UNLOCKHANDLE(dbmp, dbmp->mutexp);
 				return (0);
 			}
+
+			/*
+			 * Increment the reference count -- see the comment in
+			 * memp_fclose().
+			 */
+			++dbmfp->ref;
+			incremented = 1;
 			break;
 		}
 	UNLOCKHANDLE(dbmp, dbmp->mutexp);
@@ -117,7 +126,15 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 	    0, 0, mfp->stat.st_pagesize, 0, NULL, &dbmfp) != 0)
 		return (0);
 
-found:	return (__memp_pgwrite(dbmfp, bhp, restartp, wrotep));
+found:	ret = __memp_pgwrite(dbmfp, bhp, restartp, wrotep);
+
+	if (incremented) {
+		LOCKHANDLE(dbmp, dbmp->mutexp);
+		--dbmfp->ref;
+		UNLOCKHANDLE(dbmp, dbmp->mutexp);
+	}
+
+	return (ret);
 }
 
 /*
@@ -132,11 +149,12 @@ __memp_pgread(dbmfp, bhp, can_create)
 	BH *bhp;
 	int can_create;
 {
+	DB_IO db_io;
 	DB_MPOOL *dbmp;
 	MPOOLFILE *mfp;
-	size_t pagesize;
+	size_t len, pagesize;
 	ssize_t nr;
-	int ret;
+	int created, ret;
 
 	dbmp = dbmfp->dbmp;
 	mfp = dbmfp->mfp;
@@ -147,70 +165,63 @@ __memp_pgread(dbmfp, bhp, can_create)
 	UNLOCKREGION(dbmp);
 
 	/*
-	 * Temporary files may not yet have been created.
-	 *
-	 * Seek to the page location.
+	 * Temporary files may not yet have been created.  We don't create
+	 * them now, we create them when the pages have to be flushed.
 	 */
-	ret = 0;
-	LOCKHANDLE(dbmp, dbmfp->mutexp);
-	if (dbmfp->fd == -1 || (ret =
-	    __db_seek(dbmfp->fd, pagesize, bhp->pgno, 0, 0, SEEK_SET)) != 0) {
-		if (!can_create) {
-			if (dbmfp->fd == -1)
-				ret = EINVAL;
-			UNLOCKHANDLE(dbmp, dbmfp->mutexp);
+	nr = 0;
+	if (dbmfp->fd == -1)
+		ret = 0;
+	else {
+		/*
+		 * Ignore read errors if we have permission to create the page.
+		 * Assume that the page doesn't exist, and that we'll create it
+		 * when we write it out.
+		 */
+		db_io.fd_io = dbmfp->fd;
+		db_io.fd_lock = dbmp->reginfo.fd;
+		db_io.mutexp =
+		    F_ISSET(dbmp, MP_LOCKHANDLE) ? dbmfp->mutexp : NULL;
+		db_io.pagesize = db_io.bytes = pagesize;
+		db_io.pgno = bhp->pgno;
+		db_io.buf = bhp->buf;
+
+		ret = __os_io(&db_io, DB_IO_READ, &nr);
+	}
+
+	created = 0;
+	if (nr < (ssize_t)pagesize) {
+		if (can_create)
+			created = 1;
+		else {
+			/* If we had a short read, ret may be 0. */
+			if (ret == 0)
+				ret = EIO;
 			__db_err(dbmp->dbenv,
 			    "%s: page %lu doesn't exist, create flag not set",
 			    __memp_fn(dbmfp), (u_long)bhp->pgno);
 			goto err;
 		}
-		UNLOCKHANDLE(dbmp, dbmfp->mutexp);
-
-		/* Clear the created page. */
-		if (mfp->clear_len == 0)
-			memset(bhp->buf, 0, pagesize);
-		else {
-			memset(bhp->buf, 0, mfp->clear_len);
-#ifdef DIAGNOSTIC
-			memset(bhp->buf + mfp->clear_len,
-			    0xff, pagesize - mfp->clear_len);
-#endif
-		}
-
-		goto pgin;
 	}
 
 	/*
-	 * Read the page; short reads are treated like creates, although
-	 * any valid data is preserved.
+	 * Clear any bytes we didn't read that need to be cleared.  If we're
+	 * running in diagnostic mode, smash any bytes on the page that are
+	 * unknown quantities for the caller.
 	 */
-	ret = __db_read(dbmfp->fd, bhp->buf, pagesize, &nr);
-	UNLOCKHANDLE(dbmp, dbmfp->mutexp);
-	if (ret != 0)
-		goto err;
-
-	if (nr == (ssize_t)pagesize)
-		can_create = 0;
-	else {
-		if (!can_create) {
-			ret = EINVAL;
-			goto err;
-		}
-
-		/*
-		 * If we didn't fail until we tried the read, don't clear the
-		 * whole page, it wouldn't be insane for a filesystem to just
-		 * always behave that way.  Else, clear any uninitialized data.
-		 */
-		if (nr == 0)
-			memset(bhp->buf, 0,
-			    mfp->clear_len == 0 ? pagesize : mfp->clear_len);
-		else
-			memset(bhp->buf + nr, 0, pagesize - nr);
+	if (nr != (ssize_t)pagesize) {
+		len = mfp->clear_len == 0 ? pagesize : mfp->clear_len;
+		if (nr < (ssize_t)len)
+			memset(bhp->buf + nr, 0, len - nr);
+#ifdef DIAGNOSTIC
+		if (nr > (ssize_t)len)
+			len = nr;
+		if (len < pagesize)
+			memset(bhp->buf + len, 0xdb, pagesize - len);
+#endif
 	}
 
 	/* Call any pgin function. */
-pgin:	ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp, 1);
+	ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp, 1);
 
 	/* Unlock the buffer and reacquire the region lock. */
 err:	UNLOCKBUFFER(dbmp, bhp);
@@ -225,7 +236,7 @@ err:	UNLOCKBUFFER(dbmp, bhp);
 		F_CLR(bhp, BH_TRASH);
 
 		/* Update the statistics. */
-		if (can_create) {
+		if (created) {
 			++dbmp->mp->stat.st_page_create;
 			++mfp->stat.st_page_create;
 		} else {
@@ -250,12 +261,12 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	int *restartp, *wrotep;
 {
 	DB_ENV *dbenv;
+	DB_IO db_io;
 	DB_LOG *lg_info;
 	DB_LSN lsn;
 	DB_MPOOL *dbmp;
 	MPOOL *mp;
 	MPOOLFILE *mfp;
-	size_t pagesize;
 	ssize_t nw;
 	int callpgin, ret, syncfail;
 	const char *fail;
@@ -270,7 +281,6 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	if (wrotep != NULL)
 		*wrotep = 0;
 	callpgin = 0;
-	pagesize = mfp->stat.st_pagesize;
 
 	/*
 	 * Check the dirty bit -- this buffer may have been written since we
@@ -326,34 +336,32 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	}
 
 	/* Temporary files may not yet have been created. */
-	LOCKHANDLE(dbmp, dbmfp->mutexp);
-	if (dbmfp->fd == -1 &&
-	    ((ret = __db_appname(dbenv, DB_APP_TMP, NULL, NULL,
-	    DB_CREATE | DB_EXCL | DB_TEMPORARY, &dbmfp->fd, NULL)) != 0 ||
-	    dbmfp->fd == -1)) {
+	if (dbmfp->fd == -1) {
+		LOCKHANDLE(dbmp, dbmfp->mutexp);
+		if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv,
+		    DB_APP_TMP, NULL, NULL, DB_CREATE | DB_EXCL | DB_TEMPORARY,
+		    &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) {
+			UNLOCKHANDLE(dbmp, dbmfp->mutexp);
+			__db_err(dbenv,
+			    "unable to create temporary backing file");
+			goto err;
+		}
 		UNLOCKHANDLE(dbmp, dbmfp->mutexp);
-		__db_err(dbenv, "unable to create temporary backing file");
-		goto err;
 	}
 
-	/*
-	 * Write the page out.
-	 *
-	 * XXX
-	 * Shut the compiler up; it doesn't understand the correlation between
-	 * the failing clauses to __db_lseek and __db_write and this ret != 0.
-	 */
-	COMPQUIET(fail, NULL);
-	if ((ret =
-	    __db_seek(dbmfp->fd, pagesize, bhp->pgno, 0, 0, SEEK_SET)) != 0)
-		fail = "seek";
-	else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0)
+	/* Write the page. */
+	db_io.fd_io = dbmfp->fd;
+	db_io.fd_lock = dbmp->reginfo.fd;
+	db_io.mutexp = F_ISSET(dbmp, MP_LOCKHANDLE) ? dbmfp->mutexp : NULL;
+	db_io.pagesize = db_io.bytes = mfp->stat.st_pagesize;
+	db_io.pgno = bhp->pgno;
+	db_io.buf = bhp->buf;
+	if ((ret = __os_io(&db_io, DB_IO_WRITE, &nw)) != 0) {
+		__db_panic(dbenv, ret);
 		fail = "write";
-	UNLOCKHANDLE(dbmp, dbmfp->mutexp);
-	if (ret != 0)
 		goto syserr;
-
-	if (nw != (ssize_t)pagesize) {
+	}
+	if (nw != (ssize_t)mfp->stat.st_pagesize) {
 		ret = EIO;
 		fail = "write";
 		goto syserr;
@@ -394,7 +402,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	if (F_ISSET(bhp, BH_WRITE)) {
 		if (mfp->lsn_cnt == 1) {
 			UNLOCKREGION(dbmp);
-			syncfail = __db_fsync(dbmfp->fd) != 0;
+			syncfail = __os_fsync(dbmfp->fd) != 0;
 			LOCKREGION(dbmp);
 			if (syncfail)
 				F_SET(mp, MP_LSN_RETRY);
@@ -574,11 +582,11 @@ __memp_upgrade(dbmp, dbmfp, mfp)
 		ret = 1;
 	} else {
 		/* Swap the descriptors and set the upgrade flag. */
-		(void)__db_close(dbmfp->fd);
+		(void)__os_close(dbmfp->fd);
 		dbmfp->fd = fd;
 		F_SET(dbmfp, MP_UPGRADE);
 		ret = 0;
 	}
-	FREES(rpath);
+	__os_freestr(rpath);
 	return (ret);
 }