summaryrefslogtreecommitdiff
path: root/db/dbreg
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2004-10-16 01:31:54 +0000
committerjbj <devnull@localhost>2004-10-16 01:31:54 +0000
commitd03f220fde879509cab2ac1c73b71b7efb52b737 (patch)
tree1e34bfadac0a6618d0e9a7933bad90063a785acf /db/dbreg
parent2dc699bfe049b9319ea3719f604d25940ff52004 (diff)
downloadlibrpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.gz
librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.bz2
librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.zip
... and in with the New ...
CVS patchset: 7471 CVS date: 2004/10/16 01:31:54
Diffstat (limited to 'db/dbreg')
-rw-r--r--db/dbreg/dbreg.c181
-rw-r--r--db/dbreg/dbreg.src6
-rw-r--r--db/dbreg/dbreg_auto.c223
-rw-r--r--db/dbreg/dbreg_autop.c89
-rw-r--r--db/dbreg/dbreg_rec.c196
-rw-r--r--db/dbreg/dbreg_stat.c97
-rw-r--r--db/dbreg/dbreg_util.c237
7 files changed, 534 insertions, 495 deletions
diff --git a/db/dbreg/dbreg.c b/db/dbreg/dbreg.c
index 4101e5e5a..76edd520c 100644
--- a/db/dbreg/dbreg.c
+++ b/db/dbreg/dbreg.c
@@ -1,14 +1,13 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: dbreg.c,v 11.89 2004/09/22 03:43:09 bostic Exp $
*/
-#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: dbreg.c,v 11.81 2003/10/27 15:54:31 sue Exp $";
-#endif /* not lint */
+#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -22,6 +21,10 @@ static const char revid[] = "$Id: dbreg.c,v 11.81 2003/10/27 15:54:31 sue Exp $"
#include "dbinc/txn.h"
#include "dbinc/db_am.h"
+static int __dbreg_push_id __P((DB_ENV *, int32_t));
+static int __dbreg_pop_id __P((DB_ENV *, int32_t *));
+static int __dbreg_pluck_id __P((DB_ENV *, int32_t));
+
/*
* The dbreg subsystem, as its name implies, registers database handles so
* that we can associate log messages with them without logging a filename
@@ -98,33 +101,33 @@ __dbreg_setup(dbp, name, create_txnid)
DB_ENV *dbenv;
DB_LOG *dblp;
FNAME *fnp;
+ REGINFO *infop;
int ret;
size_t len;
void *namep;
dbenv = dbp->dbenv;
dblp = dbenv->lg_handle;
+ infop = &dblp->reginfo;
fnp = NULL;
namep = NULL;
/* Allocate an FNAME and, if necessary, a buffer for the name itself. */
- R_LOCK(dbenv, &dblp->reginfo);
- if ((ret =
- __db_shalloc(dblp->reginfo.addr, sizeof(FNAME), 0, &fnp)) != 0)
+ R_LOCK(dbenv, infop);
+ if ((ret = __db_shalloc(infop, sizeof(FNAME), 0, &fnp)) != 0)
goto err;
memset(fnp, 0, sizeof(FNAME));
if (name != NULL) {
len = strlen(name) + 1;
- if ((ret =
- __db_shalloc(dblp->reginfo.addr, len, 0, &namep)) != 0)
+ if ((ret = __db_shalloc(infop, len, 0, &namep)) != 0)
goto err;
- fnp->name_off = R_OFFSET(&dblp->reginfo, namep);
+ fnp->name_off = R_OFFSET(dbenv, infop, namep);
memcpy(namep, name, len);
} else
fnp->name_off = INVALID_ROFF;
- R_UNLOCK(dbenv, &dblp->reginfo);
+ R_UNLOCK(dbenv, infop);
/*
* Fill in all the remaining info that we'll need later to register
@@ -140,7 +143,7 @@ __dbreg_setup(dbp, name, create_txnid)
return (0);
-err: R_UNLOCK(dbenv, &dblp->reginfo);
+err: R_UNLOCK(dbenv, infop);
if (ret == ENOMEM)
__db_err(dbenv,
"Logging region out of memory; you may need to increase its size");
@@ -160,10 +163,12 @@ __dbreg_teardown(dbp)
{
DB_ENV *dbenv;
DB_LOG *dblp;
+ REGINFO *infop;
FNAME *fnp;
dbenv = dbp->dbenv;
dblp = dbenv->lg_handle;
+ infop = &dblp->reginfo;
fnp = dbp->log_filename;
/*
@@ -175,12 +180,11 @@ __dbreg_teardown(dbp)
DB_ASSERT(fnp->id == DB_LOGFILEID_INVALID);
- R_LOCK(dbenv, &dblp->reginfo);
+ R_LOCK(dbenv, infop);
if (fnp->name_off != INVALID_ROFF)
- __db_shalloc_free(dblp->reginfo.addr,
- R_ADDR(&dblp->reginfo, fnp->name_off));
- __db_shalloc_free(dblp->reginfo.addr, fnp);
- R_UNLOCK(dbenv, &dblp->reginfo);
+ __db_shalloc_free(infop, R_ADDR(dbenv, infop, fnp->name_off));
+ __db_shalloc_free(infop, fnp);
+ R_UNLOCK(dbenv, infop);
dbp->log_filename = NULL;
@@ -279,7 +283,7 @@ __dbreg_get_id(dbp, txn, idp)
memset(&fid_dbt, 0, sizeof(fid_dbt));
memset(&r_name, 0, sizeof(r_name));
if (fnp->name_off != INVALID_ROFF) {
- r_name.data = R_ADDR(&dblp->reginfo, fnp->name_off);
+ r_name.data = R_ADDR(dbenv, &dblp->reginfo, fnp->name_off);
r_name.size = (u_int32_t)strlen((char *)r_name.data) + 1;
}
fid_dbt.data = dbp->fileid;
@@ -291,7 +295,7 @@ __dbreg_get_id(dbp, txn, idp)
goto err;
/*
* Once we log the create_txnid, we need to make sure we never
- * log it again (as might happen if this is a replication client
+ * log it again (as might happen if this is a replication client
* that later upgrades to a master).
*/
fnp->create_txnid = TXN_INVALID;
@@ -310,7 +314,7 @@ err:
if (ret != 0 && id != DB_LOGFILEID_INVALID) {
(void)__dbreg_revoke_id(dbp, 1, id);
id = DB_LOGFILEID_INVALID;
- }
+ }
*idp = id;
return (ret);
}
@@ -390,8 +394,13 @@ cont: if ((ret = __dbreg_pluck_id(dbenv, id)) != 0)
fnp->is_durable = !F_ISSET(dbp, DB_AM_NOT_DURABLE);
SH_TAILQ_INSERT_HEAD(&lp->fq, fnp, q, __fname);
+ /*
+ * If we get an error adding the dbentry, revoke the id.
+ * We void the return value since we want to retain and
+ * return the original error in ret anyway.
+ */
if ((ret = __dbreg_add_dbentry(dbenv, dblp, dbp, id)) != 0)
- goto err;
+ (void)__dbreg_revoke_id(dbp, 1, id);
err: MUTEX_UNLOCK(dbenv, &lp->fq_mutex);
@@ -466,12 +475,13 @@ __dbreg_revoke_id(dbp, have_lock, force_id)
* Take a dbreg id away from a dbp that we're closing, and log
* the unregistry.
*
- * PUBLIC: int __dbreg_close_id __P((DB *, DB_TXN *));
+ * PUBLIC: int __dbreg_close_id __P((DB *, DB_TXN *, u_int32_t));
*/
int
-__dbreg_close_id(dbp, txn)
+__dbreg_close_id(dbp, txn, op)
DB *dbp;
DB_TXN *txn;
+ u_int32_t op;
{
DBT fid_dbt, r_name, *dbtp;
DB_ENV *dbenv;
@@ -496,7 +506,7 @@ __dbreg_close_id(dbp, txn)
dbtp = NULL;
else {
memset(&r_name, 0, sizeof(r_name));
- r_name.data = R_ADDR(&dblp->reginfo, fnp->name_off);
+ r_name.data = R_ADDR(dbenv, &dblp->reginfo, fnp->name_off);
r_name.size =
(u_int32_t)strlen((char *)r_name.data) + 1;
dbtp = &r_name;
@@ -506,7 +516,7 @@ __dbreg_close_id(dbp, txn)
fid_dbt.size = DB_FILE_ID_LEN;
if ((ret = __dbreg_register_log(dbenv, txn, &r_unused,
F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0,
- DBREG_CLOSE, dbtp, &fid_dbt, fnp->id,
+ op, dbtp, &fid_dbt, fnp->id,
fnp->s_type, fnp->meta_pgno, TXN_INVALID)) != 0)
goto err;
@@ -515,3 +525,122 @@ __dbreg_close_id(dbp, txn)
err: MUTEX_UNLOCK(dbenv, &lp->fq_mutex);
return (ret);
}
+
+/*
+ * __dbreg_push_id and __dbreg_pop_id --
+ * Dbreg ids from closed files are kept on a stack in shared memory
+ * for recycling. (We want to reuse them as much as possible because each
+ * process keeps open files in an array by ID.) Push them to the stack and
+ * pop them from it, managing memory as appropriate.
+ *
+ * The stack is protected by the fq_mutex, and in both functions we assume
+ * that this is already locked.
+ */
+static int
+__dbreg_push_id(dbenv, id)
+ DB_ENV *dbenv;
+ int32_t id;
+{
+ DB_LOG *dblp;
+ LOG *lp;
+ REGINFO *infop;
+ int32_t *stack, *newstack;
+ int ret;
+
+ dblp = dbenv->lg_handle;
+ infop = &dblp->reginfo;
+ lp = infop->primary;
+
+ if (lp->free_fid_stack == INVALID_ROFF) {
+ stack = NULL;
+ DB_ASSERT(lp->free_fids_alloced == 0);
+ } else
+ stack = R_ADDR(dbenv, infop, lp->free_fid_stack);
+
+ /* Check if we have room on the stack. */
+ if (lp->free_fids_alloced <= lp->free_fids + 1) {
+ R_LOCK(dbenv, infop);
+ if ((ret = __db_shalloc(infop,
+ (lp->free_fids_alloced + 20) * sizeof(u_int32_t), 0,
+ &newstack)) != 0) {
+ R_UNLOCK(dbenv, infop);
+ return (ret);
+ }
+
+ if (stack != NULL) {
+ memcpy(newstack, stack,
+ lp->free_fids_alloced * sizeof(u_int32_t));
+ __db_shalloc_free(infop, stack);
+ }
+ stack = newstack;
+ lp->free_fid_stack = R_OFFSET(dbenv, infop, stack);
+ lp->free_fids_alloced += 20;
+ R_UNLOCK(dbenv, infop);
+ }
+
+ stack[lp->free_fids++] = id;
+ return (0);
+}
+
+static int
+__dbreg_pop_id(dbenv, id)
+ DB_ENV *dbenv;
+ int32_t *id;
+{
+ DB_LOG *dblp;
+ LOG *lp;
+ int32_t *stack;
+
+ dblp = dbenv->lg_handle;
+ lp = dblp->reginfo.primary;
+
+ /* Do we have anything to pop? */
+ if (lp->free_fid_stack != INVALID_ROFF && lp->free_fids > 0) {
+ stack = R_ADDR(dbenv, &dblp->reginfo, lp->free_fid_stack);
+ *id = stack[--lp->free_fids];
+ } else
+ *id = DB_LOGFILEID_INVALID;
+
+ return (0);
+}
+
+/*
+ * __dbreg_pluck_id --
+ * Remove a particular dbreg id from the stack of free ids. This is
+ * used when we open a file, as in recovery, with a specific ID that might
+ * be on the stack.
+ *
+ * Returns success whether or not the particular id was found, and like
+ * push and pop, assumes that the fq_mutex is locked.
+ */
+static int
+__dbreg_pluck_id(dbenv, id)
+ DB_ENV *dbenv;
+ int32_t id;
+{
+ DB_LOG *dblp;
+ LOG *lp;
+ int32_t *stack;
+ u_int i;
+
+ dblp = dbenv->lg_handle;
+ lp = dblp->reginfo.primary;
+
+ /* Do we have anything to look at? */
+ if (lp->free_fid_stack != INVALID_ROFF) {
+ stack = R_ADDR(dbenv, &dblp->reginfo, lp->free_fid_stack);
+ for (i = 0; i < lp->free_fids; i++)
+ if (id == stack[i]) {
+ /*
+ * Found it. Overwrite it with the top
+ * id (which may harmlessly be itself),
+ * and shorten the stack by one.
+ */
+ stack[i] = stack[lp->free_fids - 1];
+ lp->free_fids--;
+ return (0);
+ }
+ }
+
+ return (0);
+}
diff --git a/db/dbreg/dbreg.src b/db/dbreg/dbreg.src
index c2205958b..ff3fc2923 100644
--- a/db/dbreg/dbreg.src
+++ b/db/dbreg/dbreg.src
@@ -1,17 +1,15 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*
- * $Id: dbreg.src,v 10.24 2003/04/24 14:19:17 bostic Exp $
+ * $Id: dbreg.src,v 10.26 2004/06/17 17:35:17 bostic Exp $
*/
PREFIX __dbreg
DBPRIVATE
-INCLUDE #include "db_config.h"
-INCLUDE
INCLUDE #ifndef NO_SYSTEM_INCLUDES
INCLUDE #include <sys/types.h>
INCLUDE
diff --git a/db/dbreg/dbreg_auto.c b/db/dbreg/dbreg_auto.c
index 857559c66..a9cc5f704 100644
--- a/db/dbreg/dbreg_auto.c
+++ b/db/dbreg/dbreg_auto.c
@@ -1,4 +1,5 @@
/* Do not edit: automatically built by gen_rec.awk. */
+
#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
@@ -39,31 +40,42 @@ __dbreg_register_log(dbenv, txnid, ret_lsnp, flags,
{
DBT logrec;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
+ COMPQUIET(lr, NULL);
+
rectype = DB___dbreg_register;
npad = 0;
+ rlsnp = ret_lsnp;
- is_durable = 1;
- if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE)) {
+ ret = 0;
+
+ if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
if (txnid == NULL)
return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -82,27 +94,23 @@ __dbreg_register_log(dbenv, txnid, ret_lsnp, flags,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -162,139 +170,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__dbreg_register_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __dbreg_register_getpgnos __P((DB_ENV *, DBT *,
- * PUBLIC: DB_LSN *, db_recops, void *));
- */
-int
-__dbreg_register_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __dbreg_register_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__dbreg_register_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __dbreg_register_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __dbreg_register_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__dbreg_register%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
- (void)printf("\tname: ");
- for (i = 0; i < argp->name.size; i++) {
- ch = ((u_int8_t *)argp->name.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tuid: ");
- for (i = 0; i < argp->uid.size; i++) {
- ch = ((u_int8_t *)argp->uid.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tftype: 0x%lx\n", (u_long)argp->ftype);
- (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno);
- (void)printf("\tid: 0x%lx\n", (u_long)argp->id);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __dbreg_register_read __P((DB_ENV *, void *,
* PUBLIC: __dbreg_register_args **));
@@ -313,9 +229,9 @@ __dbreg_register_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__dbreg_register_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -362,45 +278,6 @@ __dbreg_register_read(dbenv, recbuf, argpp)
}
/*
- * PUBLIC: int __dbreg_init_print __P((DB_ENV *, int (***)(DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
- */
-int
-__dbreg_init_print(dbenv, dtabp, dtabsizep)
- DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __dbreg_register_print, DB___dbreg_register)) != 0)
- return (ret);
- return (0);
-}
-
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __dbreg_init_getpgnos __P((DB_ENV *,
- * PUBLIC: int (***)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *),
- * PUBLIC: size_t *));
- */
-int
-__dbreg_init_getpgnos(dbenv, dtabp, dtabsizep)
- DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __dbreg_register_getpgnos, DB___dbreg_register)) != 0)
- return (ret);
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
* PUBLIC: int __dbreg_init_recover __P((DB_ENV *, int (***)(DB_ENV *,
* PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
*/
diff --git a/db/dbreg/dbreg_autop.c b/db/dbreg/dbreg_autop.c
new file mode 100644
index 000000000..3889b357d
--- /dev/null
+++ b/db/dbreg/dbreg_autop.c
@@ -0,0 +1,89 @@
+/* Do not edit: automatically built by gen_rec.awk. */
+
+#include "db_config.h"
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_dispatch.h"
+#include "dbinc/db_am.h"
+#include "dbinc/log.h"
+#include "dbinc/txn.h"
+
+/*
+ * PUBLIC: int __dbreg_register_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__dbreg_register_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __dbreg_register_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __dbreg_register_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__dbreg_register%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
+ (void)printf("\tname: ");
+ for (i = 0; i < argp->name.size; i++) {
+ ch = ((u_int8_t *)argp->name.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tuid: ");
+ for (i = 0; i < argp->uid.size; i++) {
+ ch = ((u_int8_t *)argp->uid.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tftype: 0x%lx\n", (u_long)argp->ftype);
+ (void)printf("\tmeta_pgno: %lu\n", (u_long)argp->meta_pgno);
+ (void)printf("\tid: 0x%lx\n", (u_long)argp->id);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __dbreg_init_print __P((DB_ENV *, int (***)(DB_ENV *,
+ * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
+ */
+int
+__dbreg_init_print(dbenv, dtabp, dtabsizep)
+ DB_ENV *dbenv;
+ int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
+ size_t *dtabsizep;
+{
+ int ret;
+
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __dbreg_register_print, DB___dbreg_register)) != 0)
+ return (ret);
+ return (0);
+}
diff --git a/db/dbreg/dbreg_rec.c b/db/dbreg/dbreg_rec.c
index 3c81e29d7..07b175a1f 100644
--- a/db/dbreg/dbreg_rec.c
+++ b/db/dbreg/dbreg_rec.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -31,14 +31,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
+ * $Id: dbreg_rec.c,v 11.133 2004/09/24 00:43:18 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: dbreg_rec.c,v 11.120 2003/10/27 15:54:31 sue Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -52,7 +50,6 @@ static const char revid[] = "$Id: dbreg_rec.c,v 11.120 2003/10/27 15:54:31 sue E
#include "dbinc/log.h"
#include "dbinc/mp.h"
#include "dbinc/txn.h"
-#include "dbinc/qam.h"
static int __dbreg_open_file __P((DB_ENV *,
DB_TXN *, __dbreg_register_args *, void *));
@@ -74,6 +71,7 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
DB *dbp;
__dbreg_register_args *argp;
int do_close, do_open, do_rem, ret, t_ret;
+ u_int32_t status;
dblp = dbenv->lg_handle;
dbp = NULL;
@@ -93,7 +91,6 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
else
do_close = 1;
break;
-
case DBREG_CLOSE:
if (DB_UNDO(op))
do_open = 1;
@@ -114,12 +111,15 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
else
do_close = 1;
break;
-
case DBREG_CHKPNT:
if (DB_UNDO(op) ||
op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES)
do_open = 1;
break;
+ default:
+ DB_ASSERT(0);
+ ret = EINVAL;
+ break;
}
if (do_open) {
@@ -138,6 +138,8 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
ret = __dbreg_open_file(dbenv,
op == DB_TXN_ABORT || op == DB_TXN_POPENFILES ?
argp->txnid : NULL, argp, info);
+ if (ret == DB_PAGE_NOTFOUND && argp->meta_pgno != PGNO_BASE_MD)
+ ret = ENOENT;
if (ret == ENOENT || ret == EINVAL) {
/*
* If this is an OPEN while rolling forward, it's
@@ -152,6 +154,9 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
dblp->dbentry[argp->fileid].deleted = 0;
ret =
__dbreg_open_file(dbenv, NULL, argp, info);
+ if (ret == DB_PAGE_NOTFOUND &&
+ argp->meta_pgno != PGNO_BASE_MD)
+ ret = ENOENT;
}
/*
* We treat ENOENT as OK since it's possible that
@@ -190,11 +195,15 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
* recovery, it's possible that we failed after
* the log record, but before we actually entered
* a handle here.
+ * 3. If we aborted an open, then we wrote a non-txnal
+ * RCLOSE into the log. During the forward pass, the
+ * file won't be open, and that's OK.
*/
dbe = &dblp->dbentry[argp->fileid];
if (dbe->dbp == NULL && !dbe->deleted) {
/* No valid entry here. */
- if (DB_REDO(op) ||
+ if ((DB_REDO(op) &&
+ argp->opcode != DBREG_RCLOSE) ||
argp->opcode == DBREG_CHKPNT) {
__db_err(dbenv,
"Improper file close at %lu/%lu",
@@ -208,64 +217,70 @@ __dbreg_register_recover(dbenv, dbtp, lsnp, op, info)
/* We have either an open entry or a deleted entry. */
if ((dbp = dbe->dbp) != NULL) {
- MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
- (void)__dbreg_revoke_id(dbp, 0,
- DB_LOGFILEID_INVALID);
-
/*
* If we're a replication client, it's
* possible to get here with a dbp that
* the user opened, but which we later
* assigned a fileid to. Be sure that
* we only close dbps that we opened in
- * the recovery code; they should have
- * DB_AM_RECOVER set.
- *
- * The only exception is if we're aborting
- * in a normal environment; then we might
- * get here with a non-AM_RECOVER database.
+ * the recovery code or that were opened
+ * inside a currently aborting transaction.
*/
- if (F_ISSET(dbp, DB_AM_RECOVER) ||
- op == DB_TXN_ABORT)
- do_rem = 1;
+ do_rem = F_ISSET(dbp, DB_AM_RECOVER) ||
+ op == DB_TXN_ABORT;
+ MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
+ if (op == DB_TXN_ABORT)
+ (void)__dbreg_close_id(dbp,
+ NULL, DBREG_RCLOSE);
+ else
+ (void)__dbreg_revoke_id(dbp, 0,
+ DB_LOGFILEID_INVALID);
} else if (dbe->deleted) {
MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
__dbreg_rem_dbentry(dblp, argp->fileid);
}
} else
MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
- if (do_rem) {
- /*
- * During recovery, all files are closed. On an abort,
- * we only close the file if we opened it during the
- * abort (DB_AM_RECOVER set), otherwise we simply do
- * a __db_refresh. For the close case, if remove or
- * rename has closed the file, don't request a sync,
- * because the NULL mpf would be a problem.
- */
- if (dbp != NULL) {
- /*
- * If we are undoing a create we'd better
- * discard any buffers from the memory pool.
- * We identify creates because the argp->id
- * field contains the transaction containing
- * the file create; if that id is invalid, we
- * are not creating.
- */
- if (argp->id != TXN_INVALID)
+ /*
+ * During recovery, all files are closed. On an abort, we only
+ * close the file if we opened it during the abort
+ * (DB_AM_RECOVER set), otherwise we simply do a __db_refresh.
+ * For the close case, if remove or rename has closed the file,
+ * don't request a sync, because a NULL mpf would be a problem.
+ *
+ * If we are undoing a create we'd better discard any buffers
+ * from the memory pool. We identify creates because the
+ * argp->id field contains the transaction containing the file
+ * create; if that id is invalid, we are not creating.
+ *
+ * On the backward pass, we need to "undo" opens even if the
+ * transaction in which they appeared committed, because we have
+ * already undone the corresponding close. In that case, the
+ * id will be valid, but we do not want to discard buffers.
+ */
+ if (do_rem && dbp != NULL) {
+ if (argp->id != TXN_INVALID) {
+ if ((ret = __db_txnlist_find(dbenv,
+ info, argp->txnid->txnid, &status))
+ != DB_NOTFOUND && ret != 0)
+ goto out;
+ if (ret == DB_NOTFOUND || status != TXN_COMMIT)
F_SET(dbp, DB_AM_DISCARD);
- if (op == DB_TXN_ABORT &&
- !F_ISSET(dbp, DB_AM_RECOVER))
- t_ret = __db_refresh(dbp,
- NULL, DB_NOSYNC, NULL);
- else {
- if (op == DB_TXN_APPLY)
- __db_sync(dbp);
- t_ret =
- __db_close(dbp, NULL, DB_NOSYNC);
- }
- if (t_ret != 0 && ret == 0)
+ ret = 0;
+ }
+
+ if (op == DB_TXN_ABORT &&
+ !F_ISSET(dbp, DB_AM_RECOVER)) {
+ if ((t_ret = __db_refresh(dbp,
+ NULL, DB_NOSYNC, NULL)) != 0 && ret == 0)
+ ret = t_ret;
+ } else {
+ if (op == DB_TXN_APPLY &&
+ (t_ret = __db_sync(dbp)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret = __db_close(
+ dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
ret = t_ret;
}
}
@@ -291,49 +306,51 @@ __dbreg_open_file(dbenv, txn, argp, info)
void *info;
{
DB_ENTRY *dbe;
- DB_LOG *lp;
+ DB_LOG *dblp;
DB *dbp;
- u_int32_t id;
+ u_int32_t id, status;
+ int ret;
- lp = (DB_LOG *)dbenv->lg_handle;
- /*
- * We never re-open temporary files. Temp files are only
- * useful during aborts in which case the dbp was entered
- * when the file was registered. During recovery, we treat
- * temp files as properly deleted files, allowing the open to
- * fail and not reporting any errors when recovery fails to
- * get a valid dbp from __dbreg_id_to_db.
- */
- if (argp->name.size == 0) {
- (void)__dbreg_add_dbentry(dbenv, lp, NULL, argp->fileid);
- return (ENOENT);
- }
+ dblp = (DB_LOG *)dbenv->lg_handle;
/*
* When we're opening, we have to check that the name we are opening
* is what we expect. If it's not, then we close the old file and
* open the new one.
*/
- MUTEX_THREAD_LOCK(dbenv, lp->mutexp);
- if (argp->fileid < lp->dbentry_cnt)
- dbe = &lp->dbentry[argp->fileid];
+ MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);
+ if (argp->fileid < dblp->dbentry_cnt)
+ dbe = &dblp->dbentry[argp->fileid];
else
dbe = NULL;
if (dbe != NULL) {
if (dbe->deleted) {
- MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);
+ MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
return (ENOENT);
}
+
+ /*
+ * At the end of OPENFILES, we may have a file open. The
+ * open was part of a committed transaction, so it doesn't
+ * get undone. However, if the fileid was previously used,
+ * we'll see a close that may need to get undone. There are
+ * three ways we can detect this. 1) the meta-pgno in the
+ * current file does not match that of the open file, 2) the
+ * file uid of the current file does not match that of the
+ * previously opened file, 3) the current file is unnamed, in
+ * which case it should never be opened during recovery.
+ */
if ((dbp = dbe->dbp) != NULL) {
if (dbp->meta_pgno != argp->meta_pgno ||
- memcmp(dbp->fileid,
- argp->uid.data, DB_FILE_ID_LEN) != 0) {
- MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);
+ argp->name.size == 0 ||
+ memcmp(dbp->fileid, argp->uid.data,
+ DB_FILE_ID_LEN) != 0) {
+ MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
(void)__dbreg_revoke_id(dbp, 0,
DB_LOGFILEID_INVALID);
if (F_ISSET(dbp, DB_AM_RECOVER))
- __db_close(dbp, NULL, DB_NOSYNC);
+ (void)__db_close(dbp, NULL, DB_NOSYNC);
goto reopen;
}
@@ -343,7 +360,7 @@ __dbreg_open_file(dbenv, txn, argp, info)
* here had better be the same dbp.
*/
DB_ASSERT(dbe->dbp == dbp);
- MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);
+ MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
/*
* This is a successful open. We need to record that
@@ -351,27 +368,40 @@ __dbreg_open_file(dbenv, txn, argp, info)
* subtransaction that created the file system object.
*/
if (argp->id != TXN_INVALID &&
- __db_txnlist_update(dbenv, info,
- argp->id, TXN_EXPECTED, NULL) == TXN_NOTFOUND)
- (void)__db_txnlist_add(dbenv,
- info, argp->id, TXN_EXPECTED, NULL);
+ (ret = __db_txnlist_update(dbenv, info,
+ argp->id, TXN_EXPECTED, NULL, &status, 1)) != 0)
+ return (ret);
return (0);
}
}
- MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);
+ MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
+
+reopen:
+ /*
+ * We never re-open temporary files. Temp files are only useful during
+ * aborts in which case the dbp was entered when the file was
+ * registered. During recovery, we treat temp files as properly deleted
+ * files, allowing the open to fail and not reporting any errors when
+ * recovery fails to get a valid dbp from __dbreg_id_to_db.
+ */
+ if (argp->name.size == 0) {
+ (void)__dbreg_add_dbentry(dbenv, dblp, NULL, argp->fileid);
+ return (ENOENT);
+ }
/*
* We are about to pass a recovery txn pointer into the main library.
* We need to make sure that any accessed fields are set appropriately.
*/
-reopen: if (txn != NULL) {
+ if (txn != NULL) {
id = txn->txnid;
memset(txn, 0, sizeof(DB_TXN));
txn->txnid = id;
txn->mgrp = dbenv->tx_handle;
}
- return (__dbreg_do_open(dbenv, txn, lp, argp->uid.data, argp->name.data,
+ return (__dbreg_do_open(dbenv,
+ txn, dblp, argp->uid.data, argp->name.data,
argp->ftype, argp->fileid, argp->meta_pgno, info, argp->id));
}
diff --git a/db/dbreg/dbreg_stat.c b/db/dbreg/dbreg_stat.c
new file mode 100644
index 000000000..d033d7ea1
--- /dev/null
+++ b/db/dbreg/dbreg_stat.c
@@ -0,0 +1,97 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997-2004
+ * Sleepycat Software. All rights reserved.
+ *
+ * $Id: dbreg_stat.c,v 11.47 2004/09/22 03:43:09 bostic Exp $
+ */
+
+#include "db_config.h"
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/log.h"
+#include "dbinc/txn.h"
+
+#ifdef HAVE_STATISTICS
+/*
+ * __dbreg_print_fname --
+ * Display the contents of an FNAME structure.
+ *
+ * PUBLIC: void __dbreg_print_fname __P((DB_ENV *, FNAME *));
+ */
+void
+__dbreg_print_fname(dbenv, fnp)
+ DB_ENV *dbenv;
+ FNAME *fnp;
+{
+ __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
+ __db_msg(dbenv, "DB handle FNAME contents:");
+ STAT_LONG("log ID", fnp->id);
+ STAT_ULONG("Meta pgno", fnp->meta_pgno);
+ __db_print_fileid(dbenv, fnp->ufid, "\tFile ID");
+ STAT_ULONG("create txn", fnp->create_txnid);
+ STAT_LONG("durable", fnp->is_durable);
+}
+
+/*
+ * __dbreg_print_dblist --
+ * Display the DB_ENV's list of files.
+ *
+ * PUBLIC: void __dbreg_print_dblist __P((DB_ENV *, u_int32_t));
+ */
+void
+__dbreg_print_dblist(dbenv, flags)
+ DB_ENV *dbenv;
+ u_int32_t flags;
+{
+ DB *dbp;
+ DB_LOG *dblp;
+ FNAME *fnp;
+ LOG *lp;
+ int del, first;
+ char *name;
+
+ dblp = dbenv->lg_handle;
+ lp = dblp->reginfo.primary;
+
+ __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
+ __db_msg(dbenv, "LOG FNAME list:");
+ __db_print_mutex(dbenv, NULL, &lp->fq_mutex, "File name mutex", flags);
+
+ STAT_LONG("Fid max", lp->fid_max);
+
+ MUTEX_LOCK(dbenv, &lp->fq_mutex);
+ for (first = 1, fnp = SH_TAILQ_FIRST(&lp->fq, __fname);
+ fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
+ if (first) {
+ first = 0;
+ __db_msg(dbenv,
+ "ID\tName\tType\tPgno\tTxnid\tDBP-info");
+ }
+ if (fnp->name_off == INVALID_ROFF)
+ name = "";
+ else
+ name = R_ADDR(dbenv, &dblp->reginfo, fnp->name_off);
+
+ dbp = fnp->id >= dblp->dbentry_cnt ? NULL :
+ dblp->dbentry[fnp->id].dbp;
+ del = fnp->id >= dblp->dbentry_cnt ? 0 :
+ dblp->dbentry[fnp->id].deleted;
+ __db_msg(dbenv, "%ld\t%s\t%s\t%lu\t%lx\t%s %d %lx %lx",
+ (long)fnp->id, name,
+ __db_dbtype_to_string(fnp->s_type),
+ (u_long)fnp->meta_pgno, (u_long)fnp->create_txnid,
+ dbp == NULL ? "No DBP" : "DBP", del, P_TO_ULONG(dbp),
+ (u_long)(dbp == NULL ? 0 : dbp->flags));
+ }
+ MUTEX_UNLOCK(dbenv, &lp->fq_mutex);
+}
+#endif
diff --git a/db/dbreg/dbreg_util.c b/db/dbreg/dbreg_util.c
index 6e21c35f3..c0d36ef17 100644
--- a/db/dbreg/dbreg_util.c
+++ b/db/dbreg/dbreg_util.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997-2003
+ * Copyright (c) 1997-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: dbreg_util.c,v 11.49 2004/09/22 03:43:09 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: dbreg_util.c,v 11.39 2003/11/10 17:42:34 sue Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <string.h>
@@ -51,7 +49,7 @@ __dbreg_add_dbentry(dbenv, dblp, dbp, ndx)
*/
if (dblp->dbentry_cnt <= ndx) {
if ((ret = __os_realloc(dbenv,
- (ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY),
+ (size_t)(ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY),
&dblp->dbentry)) != 0)
goto err;
@@ -91,13 +89,13 @@ __dbreg_rem_dbentry(dblp, ndx)
}
/*
- * __dbreg_open_files --
- * Put a DBREG_CHKPNT log record for each open database.
+ * __dbreg_log_files --
+ * Put a DBREG_CHKPNT/CLOSE log record for each open database.
*
- * PUBLIC: int __dbreg_open_files __P((DB_ENV *));
+ * PUBLIC: int __dbreg_log_files __P((DB_ENV *));
*/
int
-__dbreg_open_files(dbenv)
+__dbreg_log_files(dbenv)
DB_ENV *dbenv;
{
DB_LOG *dblp;
@@ -121,7 +119,7 @@ __dbreg_open_files(dbenv)
dbtp = NULL;
else {
memset(&t, 0, sizeof(t));
- t.data = R_ADDR(&dblp->reginfo, fnp->name_off);
+ t.data = R_ADDR(dbenv, &dblp->reginfo, fnp->name_off);
t.size = (u_int32_t)strlen(t.data) + 1;
dbtp = &t;
}
@@ -185,9 +183,9 @@ __dbreg_close_files(dbenv)
* so that we don't end up leaving around FNAME entries
* for dbps that shouldn't have them.
*/
- if ((dbp = dblp->dbentry[i].dbp) != NULL) {
+ if ((dbp = dblp->dbentry[i].dbp) != NULL) {
/*
- * It's unsafe to call DB->close or revoke_id
+ * It's unsafe to call DB->close or revoke_id
* while holding the thread lock, because
* we'll call __dbreg_rem_dbentry and grab it again.
*
@@ -302,7 +300,7 @@ __dbreg_id_to_db_int(dbenv, txn, dbpp, ndx, inc, tryopen)
* assumption, because the other process that has the file
* open shouldn't be closing it while we're trying to abort.
*/
- name = R_ADDR(&dblp->reginfo, fname->name_off);
+ name = R_ADDR(dbenv, &dblp->reginfo, fname->name_off);
/*
* At this point, we are not holding the thread lock, so exit
@@ -346,9 +344,9 @@ err: MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);
* PUBLIC: int __dbreg_id_to_fname __P((DB_LOG *, int32_t, int, FNAME **));
*/
int
-__dbreg_id_to_fname(dblp, lid, have_lock, fnamep)
+__dbreg_id_to_fname(dblp, id, have_lock, fnamep)
DB_LOG *dblp;
- int32_t lid;
+ int32_t id;
int have_lock;
FNAME **fnamep;
{
@@ -366,7 +364,7 @@ __dbreg_id_to_fname(dblp, lid, have_lock, fnamep)
MUTEX_LOCK(dbenv, &lp->fq_mutex);
for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname);
fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (fnp->id == lid) {
+ if (fnp->id == id) {
*fnamep = fnp;
ret = 0;
break;
@@ -433,12 +431,12 @@ __dbreg_get_name(dbenv, fid, namep)
char **namep;
{
DB_LOG *dblp;
- FNAME *fname;
+ FNAME *fnp;
dblp = dbenv->lg_handle;
- if (dblp != NULL && __dbreg_fid_to_fname(dblp, fid, 0, &fname) == 0) {
- *namep = R_ADDR(&dblp->reginfo, fname->name_off);
+ if (dblp != NULL && __dbreg_fid_to_fname(dblp, fid, 0, &fnp) == 0) {
+ *namep = R_ADDR(dbenv, &dblp->reginfo, fnp->name_off);
return (0);
}
@@ -467,8 +465,8 @@ __dbreg_do_open(dbenv,
u_int32_t id;
{
DB *dbp;
+ u_int32_t cstat, ret_stat;
int ret;
- u_int32_t cstat;
if ((ret = db_create(&dbp, lp->dbenv, 0)) != 0)
return (ret);
@@ -516,26 +514,21 @@ __dbreg_do_open(dbenv,
* know how to handle the subtransaction that created
* the file system object.
*/
- if (id != TXN_INVALID) {
- if ((ret = __db_txnlist_update(dbenv,
- info, id, cstat, NULL)) == TXN_NOTFOUND)
- ret = __db_txnlist_add(dbenv,
- info, id, cstat, NULL);
- else if (ret > 0)
- ret = 0;
- }
+ if (id != TXN_INVALID)
+ ret = __db_txnlist_update(dbenv,
+ info, id, cstat, NULL, &ret_stat, 1);
+
err: if (cstat == TXN_IGNORE)
goto not_right;
return (ret);
} else if (ret == ENOENT) {
/* Record that the open failed in the txnlist. */
- if (id != TXN_INVALID && (ret = __db_txnlist_update(dbenv,
- info, id, TXN_UNEXPECTED, NULL)) == TXN_NOTFOUND)
- ret = __db_txnlist_add(dbenv,
- info, id, TXN_UNEXPECTED, NULL);
+ if (id != TXN_INVALID)
+ ret = __db_txnlist_update(dbenv, info,
+ id, TXN_UNEXPECTED, NULL, &ret_stat, 1);
}
not_right:
- (void)__db_close(dbp, NULL, 0);
+ (void)__db_close(dbp, NULL, DB_NOSYNC);
/* Add this file as deleted. */
(void)__dbreg_add_dbentry(dbenv, lp, NULL, ndx);
return (ret);
@@ -625,7 +618,7 @@ __dbreg_lazy_id(dbp)
* modification call finding a valid ID in the dbp before the
* dbreg_register and commit records are in the log.
* If there was an error, then we call __dbreg_revoke_id to
- * remove the entry from the lists.
+ * remove the entry from the lists.
*/
fnp->id = id;
err:
@@ -634,177 +627,3 @@ err:
MUTEX_UNLOCK(dbenv, &lp->fq_mutex);
return (ret);
}
-
-/*
- * __dbreg_push_id and __dbreg_pop_id --
- * Dbreg ids from closed files are kept on a stack in shared memory
- * for recycling. (We want to reuse them as much as possible because each
- * process keeps open files in an array by ID.) Push them to the stack and
- * pop them from it, managing memory as appropriate.
- *
- * The stack is protected by the fq_mutex, and in both functions we assume
- * that this is already locked.
- *
- * PUBLIC: int __dbreg_push_id __P((DB_ENV *, int32_t));
- * PUBLIC: int __dbreg_pop_id __P((DB_ENV *, int32_t *));
- */
-int
-__dbreg_push_id(dbenv, id)
- DB_ENV *dbenv;
- int32_t id;
-{
- DB_LOG *dblp;
- LOG *lp;
- int32_t *stack, *newstack;
- int ret;
-
- dblp = dbenv->lg_handle;
- lp = dblp->reginfo.primary;
-
- if (lp->free_fid_stack != INVALID_ROFF)
- stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack);
- else
- stack = NULL;
-
- /* Check if we have room on the stack. */
- if (lp->free_fids_alloced <= lp->free_fids + 1) {
- R_LOCK(dbenv, &dblp->reginfo);
- if ((ret = __db_shalloc(dblp->reginfo.addr,
- (lp->free_fids_alloced + 20) * sizeof(u_int32_t), 0,
- &newstack)) != 0) {
- R_UNLOCK(dbenv, &dblp->reginfo);
- return (ret);
- }
-
- memcpy(newstack, stack,
- lp->free_fids_alloced * sizeof(u_int32_t));
- lp->free_fid_stack = R_OFFSET(&dblp->reginfo, newstack);
- lp->free_fids_alloced += 20;
-
- if (stack != NULL)
- __db_shalloc_free(dblp->reginfo.addr, stack);
-
- stack = newstack;
- R_UNLOCK(dbenv, &dblp->reginfo);
- }
-
- DB_ASSERT(stack != NULL);
- stack[lp->free_fids++] = id;
- return (0);
-}
-
-int
-__dbreg_pop_id(dbenv, id)
- DB_ENV *dbenv;
- int32_t *id;
-{
- DB_LOG *dblp;
- LOG *lp;
- int32_t *stack;
-
- dblp = dbenv->lg_handle;
- lp = dblp->reginfo.primary;
-
- /* Do we have anything to pop? */
- if (lp->free_fid_stack != INVALID_ROFF && lp->free_fids > 0) {
- stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack);
- *id = stack[--lp->free_fids];
- } else
- *id = DB_LOGFILEID_INVALID;
-
- return (0);
-}
-
-/*
- * __dbreg_pluck_id --
- * Remove a particular dbreg id from the stack of free ids. This is
- * used when we open a file, as in recovery, with a specific ID that might
- * be on the stack.
- *
- * Returns success whether or not the particular id was found, and like
- * push and pop, assumes that the fq_mutex is locked.
- *
- * PUBLIC: int __dbreg_pluck_id __P((DB_ENV *, int32_t));
- */
-int
-__dbreg_pluck_id(dbenv, id)
- DB_ENV *dbenv;
- int32_t id;
-{
- DB_LOG *dblp;
- LOG *lp;
- int32_t *stack;
- int i;
-
- dblp = dbenv->lg_handle;
- lp = dblp->reginfo.primary;
-
- /* Do we have anything to look at? */
- if (lp->free_fid_stack != INVALID_ROFF) {
- stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack);
- for (i = 0; i < lp->free_fids; i++)
- if (id == stack[i]) {
- /*
- * Found it. Overwrite it with the top
- * id (which may harmlessly be itself),
- * and shorten the stack by one.
- */
- stack[i] = stack[lp->free_fids - 1];
- lp->free_fids--;
- return (0);
- }
- }
-
- return (0);
-}
-
-#ifdef DEBUG
-/*
- * __dbreg_print_dblist --
- * Display the list of files.
- *
- * PUBLIC: void __dbreg_print_dblist __P((DB_ENV *));
- */
-void
-__dbreg_print_dblist(dbenv)
- DB_ENV *dbenv;
-{
- DB *dbp;
- DB_LOG *dblp;
- FNAME *fnp;
- LOG *lp;
- int del, first;
- char *name;
-
- dblp = dbenv->lg_handle;
- lp = dblp->reginfo.primary;
-
- MUTEX_LOCK(dbenv, &lp->fq_mutex);
-
- for (first = 1, fnp = SH_TAILQ_FIRST(&lp->fq, __fname);
- fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
- if (first) {
- first = 0;
- __db_err(dbenv,
- "ID\t\t\tName\tType\tPgno\tTxnid\tDBP-info");
- }
- if (fnp->name_off == INVALID_ROFF)
- name = "";
- else
- name = R_ADDR(&dblp->reginfo, fnp->name_off);
-
- dbp = fnp->id >= dblp->dbentry_cnt ? NULL :
- dblp->dbentry[fnp->id].dbp;
- del = fnp->id >= dblp->dbentry_cnt ? 0 :
- dblp->dbentry[fnp->id].deleted;
- __db_err(dbenv, "%ld\t%s\t\t\t%s\t%lu\t%lx\t%s %d %lx %lx",
- (long)fnp->id, name,
- __db_dbtype_to_string(fnp->s_type),
- (u_long)fnp->meta_pgno, (u_long)fnp->create_txnid,
- dbp == NULL ? "No DBP" : "DBP", del, P_TO_ULONG(dbp),
- (u_long)(dbp == NULL ? 0 : dbp->flags));
- }
-
- MUTEX_UNLOCK(dbenv, &lp->fq_mutex);
-}
-#endif