summaryrefslogtreecommitdiff
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);
}