Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

bt_open.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  */
00007 /*
00008  * Copyright (c) 1990, 1993, 1994, 1995, 1996
00009  *      Keith Bostic.  All rights reserved.
00010  */
00011 /*
00012  * Copyright (c) 1990, 1993, 1994, 1995
00013  *      The Regents of the University of California.  All rights reserved.
00014  *
00015  * This code is derived from software contributed to Berkeley by
00016  * Mike Olson.
00017  *
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions
00020  * are met:
00021  * 1. Redistributions of source code must retain the above copyright
00022  *    notice, this list of conditions and the following disclaimer.
00023  * 2. Redistributions in binary form must reproduce the above copyright
00024  *    notice, this list of conditions and the following disclaimer in the
00025  *    documentation and/or other materials provided with the distribution.
00026  * 3. Neither the name of the University nor the names of its contributors
00027  *    may be used to endorse or promote products derived from this software
00028  *    without specific prior written permission.
00029  *
00030  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00031  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00033  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00034  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00035  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00036  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00037  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00038  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00039  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00040  * SUCH DAMAGE.
00041  *
00042  * $Id: bt_open.c,v 12.5 2005/09/28 17:44:17 margo Exp $
00043  */
00044 
00045 #include "db_config.h"
00046 
00047 #ifndef NO_SYSTEM_INCLUDES
00048 #include <sys/types.h>
00049 
00050 #include <string.h>
00051 #endif
00052 
00053 #include "db_int.h"
00054 #include "dbinc/crypto.h"
00055 #include "dbinc/db_page.h"
00056 #include "dbinc/db_swap.h"
00057 #include "dbinc/btree.h"
00058 #include "dbinc/db_shash.h"
00059 #include "dbinc/lock.h"
00060 #include "dbinc/log.h"
00061 #include "dbinc/mp.h"
00062 #include "dbinc/fop.h"
00063 
00064 static void __bam_init_meta __P((DB *, BTMETA *, db_pgno_t, DB_LSN *));
00065 
00066 /*
00067  * __bam_open --
00068  *      Open a btree.
00069  *
00070  * PUBLIC: int __bam_open __P((DB *,
00071  * PUBLIC:      DB_TXN *, const char *, db_pgno_t, u_int32_t));
00072  */
00073 int
00074 __bam_open(dbp, txn, name, base_pgno, flags)
00075         DB *dbp;
00076         DB_TXN *txn;
00077         const char *name;
00078         db_pgno_t base_pgno;
00079         u_int32_t flags;
00080 {
00081         BTREE *t;
00082 
00083         COMPQUIET(name, NULL);
00084         t = dbp->bt_internal;
00085 
00086         /*
00087          * We don't permit the user to specify a prefix routine if they didn't
00088          * also specify a comparison routine, they can't know enough about our
00089          * comparison routine to get it right.
00090          */
00091         if (t->bt_compare == __bam_defcmp && t->bt_prefix != __bam_defpfx) {
00092                 __db_err(dbp->dbenv,
00093 "prefix comparison may not be specified for default comparison routine");
00094                 return (EINVAL);
00095         }
00096 
00097         /*
00098          * Verify that the bt_minkey value specified won't cause the
00099          * calculation of ovflsize to underflow [#2406] for this pagesize.
00100          */
00101         if (B_MINKEY_TO_OVFLSIZE(dbp, t->bt_minkey, dbp->pgsize) >
00102             B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) {
00103                 __db_err(dbp->dbenv,
00104                     "bt_minkey value of %lu too high for page size of %lu",
00105                     (u_long)t->bt_minkey, (u_long)dbp->pgsize);
00106                 return (EINVAL);
00107         }
00108 
00109         /* Start up the tree. */
00110         return (__bam_read_root(dbp, txn, base_pgno, flags));
00111 }
00112 
00113 /*
00114  * __bam_metachk --
00115  *
00116  * PUBLIC: int __bam_metachk __P((DB *, const char *, BTMETA *));
00117  */
00118 int
00119 __bam_metachk(dbp, name, btm)
00120         DB *dbp;
00121         const char *name;
00122         BTMETA *btm;
00123 {
00124         DB_ENV *dbenv;
00125         u_int32_t vers;
00126         int ret;
00127 
00128         dbenv = dbp->dbenv;
00129 
00130         /*
00131          * At this point, all we know is that the magic number is for a Btree.
00132          * Check the version, the database may be out of date.
00133          */
00134         vers = btm->dbmeta.version;
00135         if (F_ISSET(dbp, DB_AM_SWAP))
00136                 M_32_SWAP(vers);
00137         switch (vers) {
00138         case 6:
00139         case 7:
00140                 __db_err(dbenv,
00141                     "%s: btree version %lu requires a version upgrade",
00142                     name, (u_long)vers);
00143                 return (DB_OLD_VERSION);
00144         case 8:
00145         case 9:
00146                 break;
00147         default:
00148                 __db_err(dbenv,
00149                     "%s: unsupported btree version: %lu", name, (u_long)vers);
00150                 return (EINVAL);
00151         }
00152 
00153         /* Swap the page if we need to. */
00154         if (F_ISSET(dbp, DB_AM_SWAP) && (ret = __bam_mswap((PAGE *)btm)) != 0)
00155                 return (ret);
00156 
00157         /*
00158          * Check application info against metadata info, and set info, flags,
00159          * and type based on metadata info.
00160          */
00161         if ((ret =
00162             __db_fchk(dbenv, "DB->open", btm->dbmeta.flags, BTM_MASK)) != 0)
00163                 return (ret);
00164 
00165         if (F_ISSET(&btm->dbmeta, BTM_RECNO)) {
00166                 if (dbp->type == DB_BTREE)
00167                         goto wrong_type;
00168                 dbp->type = DB_RECNO;
00169                 DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
00170         } else {
00171                 if (dbp->type == DB_RECNO)
00172                         goto wrong_type;
00173                 dbp->type = DB_BTREE;
00174                 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00175         }
00176 
00177         if (F_ISSET(&btm->dbmeta, BTM_DUP))
00178                 F_SET(dbp, DB_AM_DUP);
00179         else
00180                 if (F_ISSET(dbp, DB_AM_DUP)) {
00181                         __db_err(dbenv,
00182                 "%s: DB_DUP specified to open method but not set in database",
00183                             name);
00184                         return (EINVAL);
00185                 }
00186 
00187         if (F_ISSET(&btm->dbmeta, BTM_RECNUM)) {
00188                 if (dbp->type != DB_BTREE)
00189                         goto wrong_type;
00190                 F_SET(dbp, DB_AM_RECNUM);
00191 
00192                 if ((ret = __db_fcchk(dbenv,
00193                     "DB->open", dbp->flags, DB_AM_DUP, DB_AM_RECNUM)) != 0)
00194                         return (ret);
00195         } else
00196                 if (F_ISSET(dbp, DB_AM_RECNUM)) {
00197                         __db_err(dbenv,
00198             "%s: DB_RECNUM specified to open method but not set in database",
00199                             name);
00200                         return (EINVAL);
00201                 }
00202 
00203         if (F_ISSET(&btm->dbmeta, BTM_FIXEDLEN)) {
00204                 if (dbp->type != DB_RECNO)
00205                         goto wrong_type;
00206                 F_SET(dbp, DB_AM_FIXEDLEN);
00207         } else
00208                 if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
00209                         __db_err(dbenv,
00210         "%s: DB_FIXEDLEN specified to open method but not set in database",
00211                             name);
00212                         return (EINVAL);
00213                 }
00214 
00215         if (F_ISSET(&btm->dbmeta, BTM_RENUMBER)) {
00216                 if (dbp->type != DB_RECNO)
00217                         goto wrong_type;
00218                 F_SET(dbp, DB_AM_RENUMBER);
00219         } else
00220                 if (F_ISSET(dbp, DB_AM_RENUMBER)) {
00221                         __db_err(dbenv,
00222             "%s: DB_RENUMBER specified to open method but not set in database",
00223                             name);
00224                         return (EINVAL);
00225                 }
00226 
00227         if (F_ISSET(&btm->dbmeta, BTM_SUBDB))
00228                 F_SET(dbp, DB_AM_SUBDB);
00229         else
00230                 if (F_ISSET(dbp, DB_AM_SUBDB)) {
00231                         __db_err(dbenv,
00232             "%s: multiple databases specified but not supported by file",
00233                             name);
00234                         return (EINVAL);
00235                 }
00236 
00237         if (F_ISSET(&btm->dbmeta, BTM_DUPSORT)) {
00238                 if (dbp->dup_compare == NULL)
00239                         dbp->dup_compare = __bam_defcmp;
00240                 F_SET(dbp, DB_AM_DUPSORT);
00241         } else
00242                 if (dbp->dup_compare != NULL) {
00243                         __db_err(dbenv,
00244                 "%s: duplicate sort specified but not supported in database",
00245                             name);
00246                         return (EINVAL);
00247                 }
00248 
00249         /* Set the page size. */
00250         dbp->pgsize = btm->dbmeta.pagesize;
00251 
00252         /* Copy the file's ID. */
00253         memcpy(dbp->fileid, btm->dbmeta.uid, DB_FILE_ID_LEN);
00254 
00255         return (0);
00256 
00257 wrong_type:
00258         if (dbp->type == DB_BTREE)
00259                 __db_err(dbenv,
00260                     "open method type is Btree, database type is Recno");
00261         else
00262                 __db_err(dbenv,
00263                     "open method type is Recno, database type is Btree");
00264         return (EINVAL);
00265 }
00266 
00267 /*
00268  * __bam_read_root --
00269  *      Read the root page and check a tree.
00270  *
00271  * PUBLIC: int __bam_read_root __P((DB *, DB_TXN *, db_pgno_t, u_int32_t));
00272  */
00273 int
00274 __bam_read_root(dbp, txn, base_pgno, flags)
00275         DB *dbp;
00276         DB_TXN *txn;
00277         db_pgno_t base_pgno;
00278         u_int32_t flags;
00279 {
00280         BTMETA *meta;
00281         BTREE *t;
00282         DBC *dbc;
00283         DB_LOCK metalock;
00284         DB_MPOOLFILE *mpf;
00285         int ret, t_ret;
00286 
00287         COMPQUIET(flags, 0);
00288         meta = NULL;
00289         t = dbp->bt_internal;
00290         LOCK_INIT(metalock);
00291         mpf = dbp->mpf;
00292         ret = 0;
00293 
00294         /* Get a cursor.  */
00295         if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0)
00296                 return (ret);
00297 
00298         /* Get the metadata page. */
00299         if ((ret =
00300             __db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0)
00301                 goto err;
00302         if ((ret = __memp_fget(mpf, &base_pgno, 0, &meta)) != 0)
00303                 goto err;
00304 
00305         /*
00306          * If the magic number is set, the tree has been created.  Correct
00307          * any fields that may not be right.  Note, all of the local flags
00308          * were set by DB->open.
00309          *
00310          * Otherwise, we'd better be in recovery or abort, in which case the
00311          * metadata page will be created/initialized elsewhere.
00312          */
00313         if (meta->dbmeta.magic == DB_BTREEMAGIC) {
00314                 t->bt_minkey = meta->minkey;
00315                 t->re_pad = (int)meta->re_pad;
00316                 t->re_len = meta->re_len;
00317 
00318                 t->bt_meta = base_pgno;
00319                 t->bt_root = meta->root;
00320         } else {
00321                 DB_ASSERT(IS_RECOVERING(dbp->dbenv) ||
00322                      F_ISSET(dbp, DB_AM_RECOVER));
00323         }
00324 
00325         /*
00326          * !!!
00327          * If creating a subdatabase, we've already done an insert when
00328          * we put the subdatabase's entry into the master database, so
00329          * our last-page-inserted value is wrongly initialized for the
00330          * master database, not the subdatabase we're creating.  I'm not
00331          * sure where the *right* place to clear this value is, it's not
00332          * intuitively obvious that it belongs here.
00333          */
00334         t->bt_lpgno = PGNO_INVALID;
00335 
00336 err:    /* Put the metadata page back. */
00337         if (meta != NULL &&
00338             (t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
00339                 ret = t_ret;
00340         if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
00341                 ret = t_ret;
00342 
00343         if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
00344                 ret = t_ret;
00345         return (ret);
00346 }
00347 
00348 /*
00349  * __bam_init_meta --
00350  *
00351  * Initialize a btree meta-data page.  The following fields may need
00352  * to be updated later: last_pgno, root.
00353  */
00354 static void
00355 __bam_init_meta(dbp, meta, pgno, lsnp)
00356         DB *dbp;
00357         BTMETA *meta;
00358         db_pgno_t pgno;
00359         DB_LSN *lsnp;
00360 {
00361         BTREE *t;
00362 
00363         memset(meta, 0, sizeof(BTMETA));
00364         meta->dbmeta.lsn = *lsnp;
00365         meta->dbmeta.pgno = pgno;
00366         meta->dbmeta.magic = DB_BTREEMAGIC;
00367         meta->dbmeta.version = DB_BTREEVERSION;
00368         meta->dbmeta.pagesize = dbp->pgsize;
00369         if (F_ISSET(dbp, DB_AM_CHKSUM))
00370                 FLD_SET(meta->dbmeta.metaflags, DBMETA_CHKSUM);
00371         if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
00372                 meta->dbmeta.encrypt_alg =
00373                     ((DB_CIPHER *)dbp->dbenv->crypto_handle)->alg;
00374                 DB_ASSERT(meta->dbmeta.encrypt_alg != 0);
00375                 meta->crypto_magic = meta->dbmeta.magic;
00376         }
00377         meta->dbmeta.type = P_BTREEMETA;
00378         meta->dbmeta.free = PGNO_INVALID;
00379         meta->dbmeta.last_pgno = pgno;
00380         if (F_ISSET(dbp, DB_AM_DUP))
00381                 F_SET(&meta->dbmeta, BTM_DUP);
00382         if (F_ISSET(dbp, DB_AM_FIXEDLEN))
00383                 F_SET(&meta->dbmeta, BTM_FIXEDLEN);
00384         if (F_ISSET(dbp, DB_AM_RECNUM))
00385                 F_SET(&meta->dbmeta, BTM_RECNUM);
00386         if (F_ISSET(dbp, DB_AM_RENUMBER))
00387                 F_SET(&meta->dbmeta, BTM_RENUMBER);
00388         if (F_ISSET(dbp, DB_AM_SUBDB))
00389                 F_SET(&meta->dbmeta, BTM_SUBDB);
00390         if (dbp->dup_compare != NULL)
00391                 F_SET(&meta->dbmeta, BTM_DUPSORT);
00392         if (dbp->type == DB_RECNO)
00393                 F_SET(&meta->dbmeta, BTM_RECNO);
00394         memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN);
00395 
00396         t = dbp->bt_internal;
00397         meta->minkey = t->bt_minkey;
00398         meta->re_len = t->re_len;
00399         meta->re_pad = (u_int32_t)t->re_pad;
00400 }
00401 
00402 /*
00403  * __bam_new_file --
00404  * Create the necessary pages to begin a new database file.
00405  *
00406  * This code appears more complex than it is because of the two cases (named
00407  * and unnamed).  The way to read the code is that for each page being created,
00408  * there are three parts: 1) a "get page" chunk (which either uses malloc'd
00409  * memory or calls __memp_fget), 2) the initialization, and 3) the "put page"
00410  * chunk which either does a fop write or an __memp_fput.
00411  *
00412  * PUBLIC: int __bam_new_file __P((DB *, DB_TXN *, DB_FH *, const char *));
00413  */
00414 int
00415 __bam_new_file(dbp, txn, fhp, name)
00416         DB *dbp;
00417         DB_TXN *txn;
00418         DB_FH *fhp;
00419         const char *name;
00420 {
00421         BTMETA *meta;
00422         DB_ENV *dbenv;
00423         DB_LSN lsn;
00424         DB_MPOOLFILE *mpf;
00425         DB_PGINFO pginfo;
00426         DBT pdbt;
00427         PAGE *root;
00428         db_pgno_t pgno;
00429         int ret, t_ret;
00430         void *buf;
00431 
00432         dbenv = dbp->dbenv;
00433         mpf = dbp->mpf;
00434         root = NULL;
00435         meta = NULL;
00436         buf = NULL;
00437 
00438         if (F_ISSET(dbp, DB_AM_INMEM)) {
00439                 /* Build the meta-data page. */
00440                 pgno = PGNO_BASE_MD;
00441                 if ((ret =
00442                     __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &meta)) != 0)
00443                         return (ret);
00444                 LSN_NOT_LOGGED(lsn);
00445                 __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
00446                 meta->root = 1;
00447                 meta->dbmeta.last_pgno = 1;
00448                 if ((ret =
00449                     __db_log_page(dbp, txn, &lsn, pgno, (PAGE *)meta)) != 0)
00450                         goto err;
00451                 ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
00452                 meta = NULL;
00453                 if (ret != 0)
00454                         goto err;
00455 
00456                 /* Build the root page. */
00457                 pgno = 1;
00458                 if ((ret =
00459                     __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0)
00460                         goto err;
00461                 P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
00462                     LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
00463                 LSN_NOT_LOGGED(root->lsn);
00464                 if ((ret =
00465                     __db_log_page(dbp, txn, &root->lsn, pgno, root)) != 0)
00466                         goto err;
00467                 ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY);
00468                 root = NULL;
00469                 if (ret != 0)
00470                         goto err;
00471         } else {
00472                 memset(&pdbt, 0, sizeof(pdbt));
00473 
00474                 /* Build the meta-data page. */
00475                 pginfo.db_pagesize = dbp->pgsize;
00476                 pginfo.flags =
00477                     F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
00478                 pginfo.type = dbp->type;
00479                 pdbt.data = &pginfo;
00480                 pdbt.size = sizeof(pginfo);
00481                 if ((ret = __os_calloc(dbenv, 1, dbp->pgsize, &buf)) != 0)
00482                         return (ret);
00483                 meta = (BTMETA *)buf;
00484                 LSN_NOT_LOGGED(lsn);
00485                 __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
00486                 meta->root = 1;
00487                 meta->dbmeta.last_pgno = 1;
00488                 if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0)
00489                         goto err;
00490                 if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
00491                     dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET(
00492                     dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
00493                         goto err;
00494                 meta = NULL;
00495 
00496                 /* Build the root page. */
00497 #ifdef DIAGNOSTIC
00498                 memset(buf, CLEAR_BYTE, dbp->pgsize);
00499 #endif
00500                 root = (PAGE *)buf;
00501                 P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
00502                     LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
00503                 LSN_NOT_LOGGED(root->lsn);
00504                 if ((ret = __db_pgout(dbenv, root->pgno, root, &pdbt)) != 0)
00505                         goto err;
00506                 if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
00507                     dbp->pgsize, 1, 0, buf, dbp->pgsize, 1, F_ISSET(
00508                     dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
00509                         goto err;
00510                 root = NULL;
00511         }
00512 
00513 err:    if (buf != NULL)
00514                 __os_free(dbenv, buf);
00515         else {
00516                 if (meta != NULL &&
00517                     (t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
00518                         ret = t_ret;
00519                 if (root != NULL &&
00520                     (t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0)
00521                         ret = t_ret;
00522         }
00523         return (ret);
00524 }
00525 
00526 /*
00527  * __bam_new_subdb --
00528  *      Create a metadata page and a root page for a new btree.
00529  *
00530  * PUBLIC: int __bam_new_subdb __P((DB *, DB *, DB_TXN *));
00531  */
00532 int
00533 __bam_new_subdb(mdbp, dbp, txn)
00534         DB *mdbp, *dbp;
00535         DB_TXN *txn;
00536 {
00537         BTMETA *meta;
00538         DBC *dbc;
00539         DB_ENV *dbenv;
00540         DB_LOCK metalock;
00541         DB_LSN lsn;
00542         DB_MPOOLFILE *mpf;
00543         PAGE *root;
00544         int ret, t_ret;
00545 
00546         dbenv = mdbp->dbenv;
00547         mpf = mdbp->mpf;
00548         dbc = NULL;
00549         meta = NULL;
00550         root = NULL;
00551 
00552         if ((ret = __db_cursor(mdbp, txn,
00553             &dbc, CDB_LOCKING(dbenv) ?  DB_WRITECURSOR : 0)) != 0)
00554                 return (ret);
00555 
00556         /* Get, and optionally create the metadata page. */
00557         if ((ret = __db_lget(dbc,
00558             0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
00559                 goto err;
00560         if ((ret =
00561             __memp_fget(mpf, &dbp->meta_pgno, DB_MPOOL_CREATE, &meta)) != 0)
00562                 goto err;
00563 
00564         /* Build meta-data page. */
00565         lsn = meta->dbmeta.lsn;
00566         __bam_init_meta(dbp, meta, dbp->meta_pgno, &lsn);
00567         if ((ret = __db_log_page(mdbp,
00568             txn, &meta->dbmeta.lsn, dbp->meta_pgno, (PAGE *)meta)) != 0)
00569                 goto err;
00570 
00571         /* Create and initialize a root page. */
00572         if ((ret = __db_new(dbc,
00573             dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE, &root)) != 0)
00574                 goto err;
00575         root->level = LEAFLEVEL;
00576 
00577         if (DBENV_LOGGING(dbenv) &&
00578             (ret = __bam_root_log(mdbp, txn, &meta->dbmeta.lsn, 0,
00579             meta->dbmeta.pgno, root->pgno, &meta->dbmeta.lsn)) != 0)
00580                 goto err;
00581 
00582         meta->root = root->pgno;
00583         if ((ret =
00584             __db_log_page(mdbp, txn, &root->lsn, root->pgno, root)) != 0)
00585                 goto err;
00586 
00587         /* Release the metadata and root pages. */
00588         if ((ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY)) != 0)
00589                 goto err;
00590         meta = NULL;
00591         if ((ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY)) != 0)
00592                 goto err;
00593         root = NULL;
00594 err:
00595         if (meta != NULL)
00596                 if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
00597                         ret = t_ret;
00598         if (root != NULL)
00599                 if ((t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0)
00600                         ret = t_ret;
00601         if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
00602                 ret = t_ret;
00603         if (dbc != NULL)
00604                 if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
00605                         ret = t_ret;
00606         return (ret);
00607 }

Generated on Sun Dec 25 12:14:12 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2