about summary refs log tree commit diff
path: root/db2/mp
diff options
context:
space:
mode:
Diffstat (limited to 'db2/mp')
-rw-r--r--db2/mp/mp_bh.c59
-rw-r--r--db2/mp/mp_fopen.c4
-rw-r--r--db2/mp/mp_pr.c2
-rw-r--r--db2/mp/mp_sync.c14
4 files changed, 67 insertions, 12 deletions
diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c
index e1b68ce450..3d0d053b5f 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.12 (Sleepycat) 8/20/97";
+static const char sccsid[] = "@(#)mp_bh.c	10.15 (Sleepycat) 8/29/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -24,6 +24,8 @@ static const char sccsid[] = "@(#)mp_bh.c	10.12 (Sleepycat) 8/20/97";
 #include "mp.h"
 #include "common_ext.h"
 
+static int __memp_upgrade __P((DB_MPOOL *, DB_MPOOLFILE *, MPOOLFILE *));
+
 /*
  * __memp_bhwrite --
  *	Write the page associated with a given bucket header.
@@ -48,14 +50,20 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 		*wrotep = 0;
 
 	/*
-	 * Walk the process' DB_MPOOLFILE list and try and find a file
-	 * descriptor for this file.
+	 * Walk the process' DB_MPOOLFILE list and find a file descriptor for
+	 * the file.  We also check that the descriptor is open for writing.
+	 * If we find a descriptor on the file that's not open for writing, we
+	 * try and upgrade it to make it writeable.
 	 */
 	LOCKHANDLE(dbmp, &dbmp->mutex);
 	for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
 	    dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q))
-		if (dbmfp->mfp == mfp)
+		if (dbmfp->mfp == mfp) {
+			if (F_ISSET(dbmfp, MP_READONLY) &&
+			    __memp_upgrade(dbmp, dbmfp, mfp))
+				return (0);
 			break;
+		}
 	UNLOCKHANDLE(dbmp, &dbmp->mutex);
 	if (dbmfp != NULL)
 		goto found;
@@ -80,6 +88,10 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 	/*
 	 * Try and open the file; ignore any error, assume it's a permissions
 	 * problem.
+	 *
+	 * XXX
+	 * There's no negative cache here, so we may repeatedly try and open
+	 * files that we have previously tried (and failed) to open.
 	 */
 	dbt.size = mfp->pgcookie_len;
 	dbt.data = ADDR(dbmp, mfp->pgcookie_off);
@@ -435,3 +447,42 @@ __memp_bhfree(dbmp, mfp, bhp, free_mem)
 	if (free_mem)
 		__db_shalloc_free(dbmp->addr, bhp);
 }
+
+/*
+ * __memp_upgrade --
+ *	Upgrade a file descriptor from readonly to readwrite.
+ */
+static int
+__memp_upgrade(dbmp, dbmfp, mfp)
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *dbmfp;
+	MPOOLFILE *mfp;
+{
+	int fd;
+
+	/*
+	 * !!!
+	 * We expect the handle to already be locked.
+	 */
+
+	/* Check to see if we've already upgraded. */
+	if (F_ISSET(dbmfp, MP_UPGRADE))
+		return (0);
+
+	/* Check to see if we've already failed. */
+	if (F_ISSET(dbmfp, MP_UPGRADE_FAIL))
+		return (1);
+
+	/* Try the open. */
+	if (__db_fdopen(ADDR(dbmp, mfp->path_off), 0, 0, 0, &fd) != 0) {
+		F_SET(dbmfp, MP_UPGRADE_FAIL);
+		return (1);
+	}
+
+	/* Swap the descriptors and set the upgrade flag. */
+	(void)close(dbmfp->fd);
+	dbmfp->fd = fd;
+	F_SET(dbmfp, MP_UPGRADE);
+
+	return (0);
+}
diff --git a/db2/mp/mp_fopen.c b/db2/mp/mp_fopen.c
index 7703847b73..1a770bfdf0 100644
--- a/db2/mp/mp_fopen.c
+++ b/db2/mp/mp_fopen.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fopen.c	10.24 (Sleepycat) 8/20/97";
+static const char sccsid[] = "@(#)mp_fopen.c	10.25 (Sleepycat) 8/27/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -110,7 +110,7 @@ __memp_fopen(dbmp, path,
 			ret = EINVAL;
 			goto err;
 		}
-		dbmfp->path = (char *) TEMPORARY;
+		dbmfp->path = (char *)TEMPORARY;
 		F_SET(dbmfp, MP_PATH_TEMP);
 	} else {
 		/* Calculate the real name for this file. */
diff --git a/db2/mp/mp_pr.c b/db2/mp/mp_pr.c
index 94eabf5947..7794cfa7f3 100644
--- a/db2/mp/mp_pr.c
+++ b/db2/mp/mp_pr.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_pr.c	10.12 (Sleepycat) 7/29/97";
+static const char sccsid[] = "@(#)mp_pr.c	10.13 (Sleepycat) 8/27/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
diff --git a/db2/mp/mp_sync.c b/db2/mp/mp_sync.c
index 4f1205661a..65b2a18267 100644
--- a/db2/mp/mp_sync.c
+++ b/db2/mp/mp_sync.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_sync.c	10.8 (Sleepycat) 7/2/97";
+static const char sccsid[] = "@(#)mp_sync.c	10.9 (Sleepycat) 8/29/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -167,8 +167,12 @@ memp_fsync(dbmfp)
 	size_t mf_offset;
 	int pincnt, restart, ret, wrote;
 
-	/* We don't sync temporary files -- what's the use? */
-	if (F_ISSET(dbmfp, MP_PATH_TEMP))
+	/*
+	 * If this handle doesn't have a file descriptor that's open for
+	 * writing, or if the file is a temporary, there's no reason to
+	 * proceed further.
+	 */
+	if (F_ISSET(dbmfp, MP_READONLY | MP_PATH_TEMP))
 		return (0);
 
 	dbmp = dbmfp->dbmp;
@@ -199,7 +203,7 @@ retry:	pincnt = 0;
 				goto retry;
 		}
 
-	UNLOCKREGION(dbmp);
+err:	UNLOCKREGION(dbmp);
 
-err:	return (ret == 0 ? (pincnt ? DB_INCOMPLETE : 0) : ret);
+	return (ret == 0 ? (pincnt ? DB_INCOMPLETE : 0) : ret);
 }