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

qam_rec.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1999-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: qam_rec.c,v 12.8 2005/10/20 18:57:13 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/db_am.h"
00022 #include "dbinc/lock.h"
00023 #include "dbinc/log.h"
00024 #include "dbinc/mp.h"
00025 #include "dbinc/qam.h"
00026 #include "dbinc/txn.h"
00027 
00028 /* Determine if we are restoring prepared transactions from __txn_recover. */
00029 #define IS_IN_RESTORE(dbenv)                                             \
00030         (((DB_TXNREGION *)((DB_TXNMGR *)                                 \
00031              (dbenv)->tx_handle)->reginfo.primary)->stat.st_nrestores != 0)
00032 
00033 /*
00034  * __qam_incfirst_recover --
00035  *      Recovery function for incfirst.
00036  *
00037  * PUBLIC: int __qam_incfirst_recover
00038  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00039  */
00040 int
00041 __qam_incfirst_recover(dbenv, dbtp, lsnp, op, info)
00042         DB_ENV *dbenv;
00043         DBT *dbtp;
00044         DB_LSN *lsnp;
00045         db_recops op;
00046         void *info;
00047 {
00048         __qam_incfirst_args *argp;
00049         DB *file_dbp;
00050         DBC *dbc;
00051         DB_LOCK lock;
00052         DB_LSN trunc_lsn;
00053         DB_MPOOLFILE *mpf;
00054         QMETA *meta;
00055         QUEUE_CURSOR *cp;
00056         db_pgno_t metapg;
00057         u_int32_t rec_ext;
00058         int exact, modified, ret, t_ret;
00059 
00060         LOCK_INIT(lock);
00061         COMPQUIET(meta, NULL);
00062         REC_PRINT(__qam_incfirst_print);
00063         REC_INTRO(__qam_incfirst_read, 1, 1);
00064 
00065         metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00066 
00067         if ((ret = __db_lget(dbc,
00068             LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
00069                 goto done;
00070         if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00071                 if (DB_REDO(op)) {
00072                         if ((ret = __memp_fget(mpf,
00073                             &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
00074                                 (void)__LPUT(dbc, lock);
00075                                 goto out;
00076                         }
00077                         meta->dbmeta.pgno = metapg;
00078                         meta->dbmeta.type = P_QAMMETA;
00079                 } else {
00080                         *lsnp = argp->prev_lsn;
00081                         ret = __LPUT(dbc, lock);
00082                         goto out;
00083                 }
00084         }
00085 
00086         modified = 0;
00087 
00088         /*
00089          * Only move first_recno backwards so we pick up the aborted delete.
00090          * When going forward we need to be careful since
00091          * we may have bumped over a locked record.
00092          */
00093         if (DB_UNDO(op)) {
00094                 if (QAM_BEFORE_FIRST(meta, argp->recno)) {
00095                         meta->first_recno = argp->recno;
00096                         modified = 1;
00097                 }
00098 
00099                 trunc_lsn = ((DB_TXNHEAD *)info)->trunc_lsn;
00100                 /* if we are truncating, update the LSN */
00101                 if (!IS_ZERO_LSN(trunc_lsn) &&
00102                     log_compare(&LSN(meta), &trunc_lsn) > 0) {
00103                         LSN(meta) = trunc_lsn;
00104                         modified = 1;
00105                 }
00106         } else {
00107                 if (log_compare(&LSN(meta), lsnp) < 0) {
00108                         LSN(meta) = *lsnp;
00109                         modified = 1;
00110                 }
00111                 if (meta->page_ext == 0)
00112                         rec_ext = 0;
00113                 else
00114                         rec_ext = meta->page_ext * meta->rec_page;
00115                 cp = (QUEUE_CURSOR *)dbc->internal;
00116                 if (meta->first_recno == RECNO_OOB)
00117                         meta->first_recno++;
00118                 while (meta->first_recno != meta->cur_recno &&
00119                     !QAM_BEFORE_FIRST(meta, argp->recno + 1)) {
00120                         if ((ret = __qam_position(dbc,
00121                             &meta->first_recno, QAM_READ, &exact)) != 0)
00122                                 goto err;
00123                         if (cp->page != NULL && (ret =
00124                             __qam_fput(file_dbp, cp->pgno, cp->page, 0)) != 0)
00125                                 goto err;
00126 
00127                         if (exact == 1)
00128                                 break;
00129                         if (cp->page != NULL &&
00130                             rec_ext != 0 && meta->first_recno % rec_ext == 0)
00131                                 if ((ret =
00132                                     __qam_fremove(file_dbp, cp->pgno)) != 0)
00133                                         goto err;
00134                         meta->first_recno++;
00135                         if (meta->first_recno == RECNO_OOB)
00136                                 meta->first_recno++;
00137                         modified = 1;
00138                 }
00139         }
00140 
00141         ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0);
00142         if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
00143                 ret = t_ret;
00144         if (ret != 0)
00145                 goto out;
00146 
00147 done:   *lsnp = argp->prev_lsn;
00148         ret = 0;
00149 
00150         if (0) {
00151 err:            (void)__memp_fput(mpf, meta, 0);
00152                 (void)__LPUT(dbc, lock);
00153         }
00154 
00155 out:    REC_CLOSE;
00156 }
00157 
00158 /*
00159  * __qam_mvptr_recover --
00160  *      Recovery function for mvptr.
00161  *
00162  * PUBLIC: int __qam_mvptr_recover
00163  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00164  */
00165 int
00166 __qam_mvptr_recover(dbenv, dbtp, lsnp, op, info)
00167         DB_ENV *dbenv;
00168         DBT *dbtp;
00169         DB_LSN *lsnp;
00170         db_recops op;
00171         void *info;
00172 {
00173         __qam_mvptr_args *argp;
00174         DB *file_dbp;
00175         DBC *dbc;
00176         DB_LSN trunc_lsn;
00177         DB_LOCK lock;
00178         DB_MPOOLFILE *mpf;
00179         QMETA *meta;
00180         QUEUE_CURSOR *cp;
00181         db_pgno_t metapg;
00182         int cmp_n, cmp_p, exact, modified, ret;
00183 
00184         REC_PRINT(__qam_mvptr_print);
00185         REC_INTRO(__qam_mvptr_read, 1, 1);
00186 
00187         metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00188 
00189         if ((ret = __db_lget(dbc,
00190             LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
00191                 goto done;
00192         if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00193                 if (DB_REDO(op)) {
00194                         if ((ret = __memp_fget(mpf,
00195                             &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
00196                                 (void)__LPUT(dbc, lock);
00197                                 goto out;
00198                         }
00199                         meta->dbmeta.pgno = metapg;
00200                         meta->dbmeta.type = P_QAMMETA;
00201                 } else {
00202                         *lsnp = argp->prev_lsn;
00203                         ret = __LPUT(dbc, lock);
00204                         goto out;
00205                 }
00206         }
00207 
00208         modified = 0;
00209         cmp_n = log_compare(lsnp, &LSN(meta));
00210         cmp_p = log_compare(&LSN(meta), &argp->metalsn);
00211 
00212         /*
00213          * Under normal circumstances, we never undo a movement of one of
00214          * the pointers.  Just move them along regardless of abort/commit.
00215          * When going forward we need to verify that this is really where
00216          * the pointer belongs.  A transaction may roll back and reinsert
00217          * a record that was missing at the time of this action.
00218          *
00219          * If we're undoing a truncate, we need to reset the pointers to
00220          * their state before the truncate.
00221          */
00222         if (DB_UNDO(op)) {
00223                 if ((argp->opcode & QAM_TRUNCATE) && cmp_n <= 0) {
00224                         meta->first_recno = argp->old_first;
00225                         meta->cur_recno = argp->old_cur;
00226                         LSN(meta) = argp->metalsn;
00227                         modified = 1;
00228                 }
00229                 /* If the page lsn is beyond the truncate point, move it back */
00230                 trunc_lsn = ((DB_TXNHEAD *)info)->trunc_lsn;
00231                 if (!IS_ZERO_LSN(trunc_lsn) &&
00232                     log_compare(&trunc_lsn, &LSN(meta)) < 0) {
00233                         LSN(meta) = argp->metalsn;
00234                         modified = 1;
00235                 }
00236         } else if (op == DB_TXN_APPLY || cmp_p == 0) {
00237                 cp = (QUEUE_CURSOR *)dbc->internal;
00238                 if ((argp->opcode & QAM_SETFIRST) &&
00239                     meta->first_recno == argp->old_first) {
00240                         if ((ret = __qam_position(dbc,
00241                             &meta->first_recno, QAM_READ, &exact)) != 0)
00242                                 goto err;
00243                         if (!exact)
00244                                 meta->first_recno = argp->new_first;
00245                         if (cp->page != NULL && (ret =
00246                             __qam_fput(file_dbp, cp->pgno, cp->page, 0)) != 0)
00247                                 goto err;
00248                 }
00249 
00250                 if ((argp->opcode & QAM_SETCUR) &&
00251                     meta->cur_recno == argp->old_cur) {
00252                         if ((ret = __qam_position(dbc,
00253                             &meta->cur_recno, QAM_READ, &exact)) != 0)
00254                                 goto err;
00255                         if (!exact)
00256                                 meta->cur_recno = argp->new_cur;
00257                         if (cp->page != NULL && (ret =
00258                             __qam_fput(file_dbp, cp->pgno, cp->page, 0)) != 0)
00259                                 goto err;
00260                 }
00261 
00262                 modified = 1;
00263                 meta->dbmeta.lsn = *lsnp;
00264         }
00265 
00266         if ((ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00267                 goto out;
00268 
00269         if ((ret = __LPUT(dbc, lock)) != 0)
00270                 goto out;
00271 
00272 done:   *lsnp = argp->prev_lsn;
00273         ret = 0;
00274 
00275         if (0) {
00276 err:            (void)__memp_fput(mpf, meta, 0);
00277                 (void)__LPUT(dbc, lock);
00278         }
00279 
00280 out:    REC_CLOSE;
00281 }
00282 
00283 /*
00284  * __qam_del_recover --
00285  *      Recovery function for del.
00286  *              Non-extent version or if there is no data (zero len).
00287  *
00288  * PUBLIC: int __qam_del_recover
00289  * PUBLIC:     __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00290  */
00291 int
00292 __qam_del_recover(dbenv, dbtp, lsnp, op, info)
00293         DB_ENV *dbenv;
00294         DBT *dbtp;
00295         DB_LSN *lsnp;
00296         db_recops op;
00297         void *info;
00298 {
00299         __qam_del_args *argp;
00300         DB *file_dbp;
00301         DBC *dbc;
00302         DB_LOCK lock;
00303         DB_MPOOLFILE *mpf;
00304         QAMDATA *qp;
00305         QMETA *meta;
00306         QPAGE *pagep;
00307         db_pgno_t metapg;
00308         int cmp_n, modified, ret, t_ret;
00309 
00310         COMPQUIET(info, NULL);
00311         COMPQUIET(pagep, NULL);
00312         REC_PRINT(__qam_del_print);
00313         REC_INTRO(__qam_del_read, 1, 1);
00314 
00315         if ((ret = __qam_fget(file_dbp,
00316             &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00317                 goto out;
00318 
00319         modified = 0;
00320         if (pagep->pgno == PGNO_INVALID) {
00321                 pagep->pgno = argp->pgno;
00322                 pagep->type = P_QAMDATA;
00323                 modified = 1;
00324         }
00325 
00326         cmp_n = log_compare(lsnp, &LSN(pagep));
00327 
00328         if (DB_UNDO(op)) {
00329                 /* make sure first is behind us */
00330                 metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00331                 if ((ret = __db_lget(dbc,
00332                     LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0)
00333                         goto err;
00334                 if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00335                         (void)__LPUT(dbc, lock);
00336                         goto err;
00337                 }
00338                 if (meta->first_recno == RECNO_OOB ||
00339                     (QAM_BEFORE_FIRST(meta, argp->recno) &&
00340                     (meta->first_recno <= meta->cur_recno ||
00341                     meta->first_recno -
00342                     argp->recno < argp->recno - meta->cur_recno))) {
00343                         meta->first_recno = argp->recno;
00344                         ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
00345                 } else
00346                         ret = __memp_fput(mpf, meta, 0);
00347                 if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
00348                         ret = t_ret;
00349                 if (ret != 0)
00350                         goto err;
00351 
00352                 /* Need to undo delete - mark the record as present */
00353                 qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00354                 F_SET(qp, QAM_VALID);
00355 
00356                 /*
00357                  * Move the LSN back to this point;  do not move it forward.
00358                  * Only move it back if we're in recovery.  If we're in
00359                  * an abort, because we don't hold a page lock, we could
00360                  * foul up a concurrent put.  Having too late an LSN
00361                  * is harmless in queue except when we're determining
00362                  * what we need to roll forward during recovery.  [#2588]
00363                  * If we are aborting a restored transaction then it
00364                  * might get rolled forward later so the LSN needs to
00365                  * be correct in that case too. [#12181]
00366                  */
00367                 if (cmp_n <= 0 &&
00368                       (op == DB_TXN_BACKWARD_ROLL || IS_IN_RESTORE(dbenv)))
00369                         LSN(pagep) = argp->lsn;
00370                 modified = 1;
00371         } else if (op == DB_TXN_APPLY || (cmp_n > 0 && DB_REDO(op))) {
00372                 /* Need to redo delete - clear the valid bit */
00373                 qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00374                 F_CLR(qp, QAM_VALID);
00375                 LSN(pagep) = *lsnp;
00376                 modified = 1;
00377         }
00378         if ((ret = __qam_fput(file_dbp,
00379             argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00380                 goto out;
00381 
00382 done:   *lsnp = argp->prev_lsn;
00383         ret = 0;
00384 
00385         if (0) {
00386 err:            (void)__qam_fput(file_dbp, argp->pgno, pagep, 0);
00387         }
00388 out:    REC_CLOSE;
00389 }
00390 
00391 /*
00392  * __qam_delext_recover --
00393  *      Recovery function for del in an extent based queue.
00394  *
00395  * PUBLIC: int __qam_delext_recover __P((DB_ENV *,
00396  * PUBLIC:     DBT *, DB_LSN *, db_recops, void *));
00397  */
00398 int
00399 __qam_delext_recover(dbenv, dbtp, lsnp, op, info)
00400         DB_ENV *dbenv;
00401         DBT *dbtp;
00402         DB_LSN *lsnp;
00403         db_recops op;
00404         void *info;
00405 {
00406         __qam_delext_args *argp;
00407         DB *file_dbp;
00408         DBC *dbc;
00409         DB_LOCK lock;
00410         DB_MPOOLFILE *mpf;
00411         QAMDATA *qp;
00412         QMETA *meta;
00413         QPAGE *pagep;
00414         db_pgno_t metapg;
00415         int cmp_n, modified, ret, t_ret;
00416 
00417         COMPQUIET(info, NULL);
00418         COMPQUIET(pagep, NULL);
00419         REC_PRINT(__qam_delext_print);
00420         REC_INTRO(__qam_delext_read, 1, 1);
00421 
00422         if ((ret = __qam_fget(file_dbp, &argp->pgno, 0, &pagep)) != 0) {
00423                 if (ret != DB_PAGE_NOTFOUND && ret != ENOENT)
00424                         goto out;
00425                 /*
00426                  * If we are redoing a delete and the page is not there
00427                  * we are done.
00428                  */
00429                 if (DB_REDO(op))
00430                         goto done;
00431                 if ((ret = __qam_fget(file_dbp,
00432                     &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00433                         goto out;
00434         }
00435 
00436         modified = 0;
00437         if (pagep->pgno == PGNO_INVALID) {
00438                 pagep->pgno = argp->pgno;
00439                 pagep->type = P_QAMDATA;
00440                 modified = 1;
00441         }
00442 
00443         cmp_n = log_compare(lsnp, &LSN(pagep));
00444 
00445         if (DB_UNDO(op)) {
00446                 /* make sure first is behind us */
00447                 metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00448                 if ((ret = __db_lget(dbc,
00449                     LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0)
00450                         goto err;
00451                 if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00452                         (void)__LPUT(dbc, lock);
00453                         goto err;
00454                 }
00455                 if (meta->first_recno == RECNO_OOB ||
00456                     (QAM_BEFORE_FIRST(meta, argp->recno) &&
00457                     (meta->first_recno <= meta->cur_recno ||
00458                     meta->first_recno -
00459                     argp->recno < argp->recno - meta->cur_recno))) {
00460                         meta->first_recno = argp->recno;
00461                         ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
00462                 } else
00463                         ret = __memp_fput(mpf, meta, 0);
00464                 if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
00465                         ret = t_ret;
00466                 if (ret != 0)
00467                         goto err;
00468 
00469                 if ((ret = __qam_pitem(dbc, pagep,
00470                     argp->indx, argp->recno, &argp->data)) != 0)
00471                         goto err;
00472 
00473                 /*
00474                  * Move the LSN back to this point;  do not move it forward.
00475                  * Only move it back if we're in recovery.  If we're in
00476                  * an abort, because we don't hold a page lock, we could
00477                  * foul up a concurrent put.  Having too late an LSN
00478                  * is harmless in queue except when we're determining
00479                  * what we need to roll forward during recovery.  [#2588]
00480                  */
00481                 if (cmp_n <= 0 &&
00482                       (op == DB_TXN_BACKWARD_ROLL || IS_IN_RESTORE(dbenv)))
00483                         LSN(pagep) = argp->lsn;
00484                 modified = 1;
00485         } else if (op == DB_TXN_APPLY || (cmp_n > 0 && DB_REDO(op))) {
00486                 /* Need to redo delete - clear the valid bit */
00487                 qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00488                 F_CLR(qp, QAM_VALID);
00489                 LSN(pagep) = *lsnp;
00490                 modified = 1;
00491         }
00492         if ((ret = __qam_fput(file_dbp,
00493             argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00494                 goto out;
00495 
00496 done:   *lsnp = argp->prev_lsn;
00497         ret = 0;
00498 
00499         if (0) {
00500 err:            (void)__qam_fput(file_dbp, argp->pgno, pagep, 0);
00501         }
00502 out:    REC_CLOSE;
00503 }
00504 
00505 /*
00506  * __qam_add_recover --
00507  *      Recovery function for add.
00508  *
00509  * PUBLIC: int __qam_add_recover
00510  * PUBLIC:     __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00511  */
00512 int
00513 __qam_add_recover(dbenv, dbtp, lsnp, op, info)
00514         DB_ENV *dbenv;
00515         DBT *dbtp;
00516         DB_LSN *lsnp;
00517         db_recops op;
00518         void *info;
00519 {
00520         __qam_add_args *argp;
00521         DB *file_dbp;
00522         DBC *dbc;
00523         DB_MPOOLFILE *mpf;
00524         QAMDATA *qp;
00525         QMETA *meta;
00526         QPAGE *pagep;
00527         db_pgno_t metapg;
00528         int cmp_n, meta_dirty, modified, ret;
00529 
00530         COMPQUIET(info, NULL);
00531         COMPQUIET(pagep, NULL);
00532         REC_PRINT(__qam_add_print);
00533         REC_INTRO(__qam_add_read, 1, 1);
00534 
00535         modified = 0;
00536         if ((ret = __qam_fget(file_dbp, &argp->pgno, 0, &pagep)) != 0) {
00537                 if (ret != DB_PAGE_NOTFOUND && ret != ENOENT)
00538                         goto out;
00539                 /*
00540                  * If we are undoing an append and the page is not there
00541                  * we are done.
00542                  */
00543                 if (DB_UNDO(op))
00544                         goto done;
00545                 if ((ret = __qam_fget(file_dbp,
00546                     &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00547                         goto out;
00548         }
00549 
00550         if (pagep->pgno == PGNO_INVALID) {
00551                 pagep->pgno = argp->pgno;
00552                 pagep->type = P_QAMDATA;
00553                 modified = 1;
00554         }
00555 
00556         cmp_n = log_compare(lsnp, &LSN(pagep));
00557 
00558         if (DB_REDO(op)) {
00559                 /* Fix meta-data page. */
00560                 metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00561                 if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0)
00562                         goto err;
00563                 meta_dirty = 0;
00564                 if (QAM_BEFORE_FIRST(meta, argp->recno)) {
00565                         meta->first_recno = argp->recno;
00566                         meta_dirty = 1;
00567                 }
00568                 if (argp->recno == meta->cur_recno ||
00569                    QAM_AFTER_CURRENT(meta, argp->recno)) {
00570                         meta->cur_recno = argp->recno + 1;
00571                         meta_dirty = 1;
00572                 }
00573                 if ((ret = __memp_fput(mpf,
00574                     meta, meta_dirty? DB_MPOOL_DIRTY : 0)) != 0)
00575                         goto err;
00576 
00577                 /* Now update the actual page if necessary. */
00578                 if (op == DB_TXN_APPLY || cmp_n > 0) {
00579                         /* Need to redo add - put the record on page */
00580                         if ((ret = __qam_pitem(dbc,
00581                             pagep, argp->indx, argp->recno, &argp->data)) != 0)
00582                                 goto err;
00583                         LSN(pagep) = *lsnp;
00584                         modified = 1;
00585                 }
00586         } else if (DB_UNDO(op)) {
00587                 /*
00588                  * Need to undo add
00589                  *      If this was an overwrite, put old record back.
00590                  *      Otherwise just clear the valid bit
00591                  */
00592                 if (argp->olddata.size != 0) {
00593                         if ((ret = __qam_pitem(dbc, pagep,
00594                             argp->indx, argp->recno, &argp->olddata)) != 0)
00595                                 goto err;
00596 
00597                         if (!(argp->vflag & QAM_VALID)) {
00598                                 qp = QAM_GET_RECORD(
00599                                     file_dbp, pagep, argp->indx);
00600                                 F_CLR(qp, QAM_VALID);
00601                         }
00602                         modified = 1;
00603                 } else {
00604                         qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00605                         qp->flags = 0;
00606                         modified = 1;
00607                 }
00608 
00609                 /*
00610                  * Move the LSN back to this point;  do not move it forward.
00611                  * Only move it back if we're in recovery.  If we're in
00612                  * an abort, because we don't hold a page lock, we could
00613                  * foul up a concurrent put.  Having too late an LSN
00614                  * is harmless in queue except when we're determining
00615                  * what we need to roll forward during recovery.  [#2588]
00616                  */
00617                 if (cmp_n <= 0 &&
00618                       (op == DB_TXN_BACKWARD_ROLL || IS_IN_RESTORE(dbenv)))
00619                         LSN(pagep) = argp->lsn;
00620         }
00621 
00622         if ((ret = __qam_fput(file_dbp,
00623             argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00624                 goto out;
00625 
00626 done:   *lsnp = argp->prev_lsn;
00627         ret = 0;
00628 
00629         if (0) {
00630 err:            (void)__qam_fput(file_dbp, argp->pgno, pagep, 0);
00631         }
00632 
00633 out:    REC_CLOSE;
00634 }

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