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

crdel_rec.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: crdel_rec.c,v 12.6 2005/10/20 18:57:04 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <string.h>
00016 #endif
00017 
00018 #include "db_int.h"
00019 #include "dbinc/db_page.h"
00020 #include "dbinc/db_shash.h"
00021 #include "dbinc/fop.h"
00022 #include "dbinc/hash.h"
00023 #include "dbinc/log.h"
00024 #include "dbinc/mp.h"
00025 #include "dbinc/txn.h"
00026 
00027 /*
00028  * __crdel_metasub_recover --
00029  *      Recovery function for metasub.
00030  *
00031  * PUBLIC: int __crdel_metasub_recover
00032  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00033  */
00034 int
00035 __crdel_metasub_recover(dbenv, dbtp, lsnp, op, info)
00036         DB_ENV *dbenv;
00037         DBT *dbtp;
00038         DB_LSN *lsnp;
00039         db_recops op;
00040         void *info;
00041 {
00042         __crdel_metasub_args *argp;
00043         DB *file_dbp;
00044         DBC *dbc;
00045         DB_MPOOLFILE *mpf;
00046         PAGE *pagep;
00047         int cmp_p, modified, ret;
00048 
00049         pagep = NULL;
00050         COMPQUIET(info, NULL);
00051         REC_PRINT(__crdel_metasub_print);
00052         REC_INTRO(__crdel_metasub_read, 0, 0);
00053 
00054         if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00055                 /* If this is an in-memory file, this might be OK. */
00056                 if (F_ISSET(file_dbp, DB_AM_INMEM) && (ret = __memp_fget(mpf,
00057                     &argp->pgno, DB_MPOOL_CREATE, &pagep)) == 0)
00058                         LSN_NOT_LOGGED(LSN(pagep));
00059                 else {
00060                         *lsnp = argp->prev_lsn;
00061                         ret = 0;
00062                         goto out;
00063                 }
00064         }
00065 
00066         modified = 0;
00067         cmp_p = log_compare(&LSN(pagep), &argp->lsn);
00068         CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
00069 
00070         if (cmp_p == 0 && DB_REDO(op)) {
00071                 memcpy(pagep, argp->page.data, argp->page.size);
00072                 LSN(pagep) = *lsnp;
00073                 modified = 1;
00074 
00075                 /*
00076                  * If this was an in-memory database and we are re-creating
00077                  * and this is the meta-data page, then we need to set up a
00078                  * bunch of fields in the dbo as well.
00079                  */
00080                 if (F_ISSET(file_dbp, DB_AM_INMEM) &&
00081                     argp->pgno == PGNO_BASE_MD &&
00082                     (ret = __db_meta_setup(file_dbp->dbenv,
00083                     file_dbp, file_dbp->dname, (DBMETA *)pagep, 0, 1)) != 0)
00084                         goto out;
00085         } else if (DB_UNDO(op)) {
00086                 /*
00087                  * We want to undo this page creation.  The page creation
00088                  * happened in two parts.  First, we called __bam_new which
00089                  * was logged separately. Then we wrote the meta-data onto
00090                  * the page.  So long as we restore the LSN, then the recovery
00091                  * for __bam_new will do everything else.
00092                  *
00093                  * Don't bother checking the lsn on the page.  If we are
00094                  * rolling back the next thing is that this page will get
00095                  * freed.  Opening the subdb will have reinitialized the
00096                  * page, but not the lsn.
00097                  */
00098                 LSN(pagep) = argp->lsn;
00099                 modified = 1;
00100         }
00101         if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00102                 goto out;
00103         pagep = NULL;
00104 
00105 done:   *lsnp = argp->prev_lsn;
00106         ret = 0;
00107 
00108 out:    if (pagep != NULL)
00109                 (void)__memp_fput(mpf, pagep, 0);
00110         REC_CLOSE;
00111 }
00112 
00113 /*
00114  * __crdel_inmem_create_recover --
00115  *      Recovery function for inmem_create.
00116  *
00117  * PUBLIC: int __crdel_inmem_create_recover
00118  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00119  */
00120 int
00121 __crdel_inmem_create_recover(dbenv, dbtp, lsnp, op, info)
00122         DB_ENV *dbenv;
00123         DBT *dbtp;
00124         DB_LSN *lsnp;
00125         db_recops op;
00126         void *info;
00127 {
00128         DB *dbp;
00129         __crdel_inmem_create_args *argp;
00130         int do_close, ret, t_ret;
00131 
00132         COMPQUIET(info, NULL);
00133         dbp = NULL;
00134         do_close = 0;
00135         REC_PRINT(__crdel_inmem_create_print);
00136         REC_NOOP_INTRO(__crdel_inmem_create_read);
00137 
00138         /* First, see if the DB handle already exists. */
00139         if (argp->fileid == DB_LOGFILEID_INVALID) {
00140                 if (DB_REDO(op))
00141                         ret = ENOENT;
00142                 else
00143                         ret = 0;
00144         } else
00145                 ret = __dbreg_id_to_db_int(dbenv,
00146                     argp->txnid, &dbp, argp->fileid, 0, 0);
00147 
00148         if (DB_REDO(op)) {
00149                 /*
00150                  * If the dbreg failed, that means that we're creating a
00151                  * tmp file.
00152                  */
00153                 if (ret != 0) {
00154                         if ((ret = db_create(&dbp, dbenv, 0)) != 0)
00155                                 goto out;
00156 
00157                         F_SET(dbp, DB_AM_RECOVER | DB_AM_INMEM);
00158                         memcpy(dbp->fileid, argp->fid.data, DB_FILE_ID_LEN);
00159                         if (((ret = __os_strdup(dbenv,
00160                             argp->name.data, &dbp->dname)) != 0))
00161                                 goto out;
00162 
00163                         /*
00164                          * This DBP is never going to be entered into the
00165                          * dbentry table, so if we leave it open here,
00166                          * then we're going to lose it.
00167                          */
00168                         do_close = 1;
00169                 }
00170 
00171                 /* Now, set the fileid. */
00172                 memcpy(dbp->fileid, argp->fid.data, argp->fid.size);
00173                 if ((ret = __memp_set_fileid(dbp->mpf, dbp->fileid)) != 0)
00174                         goto out;
00175                 dbp->preserve_fid = 1;
00176                 MAKE_INMEM(dbp);
00177                 if ((ret = __db_dbenv_setup(dbp,
00178                     NULL, NULL, argp->name.data, TXN_INVALID, 0)) != 0)
00179                         goto out;
00180                 ret = __db_dbenv_mpool(dbp, argp->name.data, 0);
00181 
00182                 if (ret == ENOENT) {
00183                         dbp->pgsize = argp->pgsize;
00184                         if ((ret = __db_dbenv_mpool(dbp,
00185                             argp->name.data, DB_CREATE)) != 0)
00186                                 goto out;
00187                 } else if (ret != 0)
00188                         goto out;
00189         }
00190 
00191         if (DB_UNDO(op)) {
00192                 if (ret == 0)
00193                         ret = __memp_nameop(dbenv, argp->fid.data, NULL,
00194                             (const char *)argp->name.data,  NULL, 1);
00195 
00196                 if (ret == ENOENT || ret == DB_DELETED)
00197                         ret = 0;
00198                 else
00199                         goto out;
00200         }
00201 
00202         *lsnp = argp->prev_lsn;
00203 
00204 out:    if (dbp != NULL) {
00205                 t_ret = 0;
00206                 if (DB_UNDO(op))
00207                         t_ret = __db_refresh(dbp, NULL, DB_NOSYNC, NULL, 0);
00208                 else if (do_close || ret != 0)
00209                         t_ret = __db_close(dbp, NULL, DB_NOSYNC);
00210                 if (t_ret != 0 && ret == 0)
00211                         ret = t_ret;
00212         }
00213         REC_NOOP_CLOSE;
00214 }
00215 
00216 /*
00217  * __crdel_inmem_rename_recover --
00218  *      Recovery function for inmem_rename.
00219  *
00220  * PUBLIC: int __crdel_inmem_rename_recover
00221  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00222  */
00223 int
00224 __crdel_inmem_rename_recover(dbenv, dbtp, lsnp, op, info)
00225         DB_ENV *dbenv;
00226         DBT *dbtp;
00227         DB_LSN *lsnp;
00228         db_recops op;
00229         void *info;
00230 {
00231         __crdel_inmem_rename_args *argp;
00232         u_int8_t *fileid;
00233         int ret;
00234 
00235         COMPQUIET(info, NULL);
00236         REC_PRINT(__crdel_inmem_rename_print);
00237         REC_NOOP_INTRO(__crdel_inmem_rename_read);
00238         fileid = argp->fid.data;
00239 
00240         /* Void out errors because the files may or may not still exist. */
00241         if (DB_REDO(op))
00242                 (void)__memp_nameop(dbenv, fileid,
00243                     (const char *)argp->newname.data,
00244                     (const char *)argp->oldname.data,
00245                     (const char *)argp->newname.data, 1);
00246 
00247         if (DB_UNDO(op))
00248                 (void)__memp_nameop(dbenv, fileid,
00249                     (const char *)argp->oldname.data,
00250                     (const char *)argp->newname.data,
00251                     (const char *)argp->oldname.data, 1);
00252 
00253         *lsnp = argp->prev_lsn;
00254         ret = 0;
00255 
00256         REC_NOOP_CLOSE;
00257 }
00258 
00259 /*
00260  * __crdel_inmem_remove_recover --
00261  *      Recovery function for inmem_remove.
00262  *
00263  * PUBLIC: int __crdel_inmem_remove_recover
00264  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00265  */
00266 int
00267 __crdel_inmem_remove_recover(dbenv, dbtp, lsnp, op, info)
00268         DB_ENV *dbenv;
00269         DBT *dbtp;
00270         DB_LSN *lsnp;
00271         db_recops op;
00272         void *info;
00273 {
00274         __crdel_inmem_remove_args *argp;
00275         int ret;
00276 
00277         COMPQUIET(info, NULL);
00278         REC_PRINT(__crdel_inmem_remove_print);
00279         REC_NOOP_INTRO(__crdel_inmem_remove_read);
00280 
00281         /*
00282          * Since removes are delayed; there is no undo for a remove; only redo.
00283          * The remove may fail, which is OK.
00284          */
00285         if (DB_REDO(op)) {
00286                 (void)__memp_nameop(dbenv,
00287                     argp->fid.data, NULL, argp->name.data, NULL, 1);
00288         }
00289 
00290         *lsnp = argp->prev_lsn;
00291         ret = 0;
00292 
00293         REC_NOOP_CLOSE;
00294 }

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