00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: crdel__rec_8c-source.html,v 1.1 2008/06/08 10:16:30 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <errno.h>
00018 #include <string.h>
00019 #endif
00020
00021 #include "db_int.h"
00022 #include "db_page.h"
00023 #include "log.h"
00024 #include "hash.h"
00025 #include "mp.h"
00026 #include "db_dispatch.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035 int
00036 CDB___crdel_fileopen_recover(dbenv, dbtp, lsnp, op, info)
00037 DB_ENV *dbenv;
00038 DBT *dbtp;
00039 DB_LSN *lsnp;
00040 db_recops op;
00041 void *info;
00042 {
00043 __crdel_fileopen_args *argp;
00044 DBMETA ondisk;
00045 DB_FH fh;
00046 size_t nr;
00047 int do_unlink, ret;
00048 u_int32_t b, mb, io;
00049 char *real_name;
00050
00051 COMPQUIET(info, NULL);
00052
00053 real_name = NULL;
00054 REC_PRINT(CDB___crdel_fileopen_print);
00055
00056 if ((ret = CDB___crdel_fileopen_read(dbenv, dbtp->data, &argp)) != 0)
00057 goto out;
00058
00059
00060
00061
00062 if (argp->name.size == 0)
00063 goto done;
00064
00065 if ((ret = CDB___db_appname(dbenv, DB_APP_DATA,
00066 NULL, argp->name.data, 0, NULL, &real_name)) != 0)
00067 goto out;
00068 if (DB_REDO(op)) {
00069
00070
00071
00072
00073 if ((ret = CDB___os_open(dbenv, real_name,
00074 DB_OSO_CREATE, argp->mode, &fh)) != 0)
00075 goto out;
00076 if ((ret = CDB___os_closehandle(&fh)) != 0)
00077 goto out;
00078 } else if (DB_UNDO(op)) {
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 if (CDB___os_exists(real_name, NULL) != 0)
00091 goto done;
00092
00093 if ((ret = CDB___os_open(dbenv, real_name, 0, 0, &fh)) != 0)
00094 goto out;
00095 if ((ret = CDB___os_ioinfo(dbenv,
00096 real_name, &fh, &mb, &b, &io)) != 0)
00097 goto out;
00098 do_unlink = 0;
00099 if (mb != 0 || b != 0) {
00100
00101
00102
00103
00104 if ((ret = CDB___os_read(dbenv, &fh,
00105 &ondisk, sizeof(ondisk), &nr)) != 0 ||
00106 nr != sizeof(ondisk))
00107 goto out;
00108 if (ondisk.magic == 0)
00109 do_unlink = 1;
00110 }
00111 if ((ret = CDB___os_closehandle(&fh)) != 0)
00112 goto out;
00113
00114 if (do_unlink || (mb == 0 && b == 0))
00115 if ((ret = CDB___os_unlink(dbenv, real_name)) != 0)
00116 goto out;
00117 }
00118
00119 done: *lsnp = argp->prev_lsn;
00120 ret = 0;
00121
00122 out: if (argp != NULL)
00123 CDB___os_free(argp, sizeof(*argp));
00124 if (real_name != NULL)
00125 CDB___os_freestr(real_name);
00126 return (ret);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136 int
00137 CDB___crdel_metasub_recover(dbenv, dbtp, lsnp, op, info)
00138 DB_ENV *dbenv;
00139 DBT *dbtp;
00140 DB_LSN *lsnp;
00141 db_recops op;
00142 void *info;
00143 {
00144 __crdel_metasub_args *argp;
00145 DB *file_dbp;
00146 DBC *dbc;
00147 DB_MPOOLFILE *mpf;
00148 PAGE *pagep;
00149 int cmp_p, modified, ret;
00150
00151 COMPQUIET(info, NULL);
00152 REC_PRINT(CDB___crdel_metasub_print);
00153 REC_INTRO(CDB___crdel_metasub_read, 0);
00154
00155 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00156 if (DB_REDO(op)) {
00157 if ((ret = CDB_memp_fget(mpf,
00158 &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00159 goto out;
00160 } else {
00161 *lsnp = argp->prev_lsn;
00162 ret = 0;
00163 goto out;
00164 }
00165 }
00166
00167 modified = 0;
00168 cmp_p = CDB_log_compare(&LSN(pagep), &argp->lsn);
00169 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->lsn);
00170
00171 if (cmp_p == 0 && DB_REDO(op)) {
00172 memcpy(pagep, argp->page.data, argp->page.size);
00173 LSN(pagep) = *lsnp;
00174 modified = 1;
00175 } else if (DB_UNDO(op)) {
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 LSN(pagep) = argp->lsn;
00188 modified = 1;
00189 }
00190 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00191 goto out;
00192
00193 done: *lsnp = argp->prev_lsn;
00194 ret = 0;
00195
00196 out: REC_CLOSE;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 int
00207 CDB___crdel_metapage_recover(dbenv, dbtp, lsnp, op, info)
00208 DB_ENV *dbenv;
00209 DBT *dbtp;
00210 DB_LSN *lsnp;
00211 db_recops op;
00212 void *info;
00213 {
00214 __crdel_metapage_args *argp;
00215 DB *dbp;
00216 DBMETA *meta, ondisk;
00217 DB_FH fh;
00218 size_t nr;
00219 u_int32_t b, io, mb, pagesize;
00220 int is_done, ret;
00221 char *real_name;
00222
00223 COMPQUIET(info, NULL);
00224
00225 real_name = NULL;
00226 memset(&fh, 0, sizeof(fh));
00227 REC_PRINT(CDB___crdel_metapage_print);
00228
00229 if ((ret = CDB___crdel_metapage_read(dbenv, dbtp->data, &argp)) != 0)
00230 goto out;
00231
00232
00233
00234
00235
00236 if (argp->name.size == 0)
00237 goto done;
00238
00239 meta = (DBMETA *)argp->page.data;
00240 CDB___ua_memcpy(&pagesize, &meta->pagesize, sizeof(pagesize));
00241
00242 if ((ret = CDB___db_appname(dbenv, DB_APP_DATA,
00243 NULL, argp->name.data, 0, NULL, &real_name)) != 0)
00244 goto out;
00245 if (DB_REDO(op)) {
00246 if ((ret = CDB___db_fileid_to_db(dbenv,
00247 &dbp, argp->fileid, 0)) != 0) {
00248 if (ret == DB_DELETED)
00249 goto done;
00250 else
00251 goto out;
00252 }
00253
00254
00255
00256
00257
00258 if ((ret = CDB___os_open(dbenv, real_name, 0, 0, &fh)) != 0)
00259 goto out;
00260 if ((ret = CDB___os_seek(dbenv, &fh,
00261 pagesize, argp->pgno, 0, 0, DB_OS_SEEK_SET)) != 0)
00262 goto out;
00263
00264
00265
00266
00267
00268
00269
00270 if ((ret = CDB___os_read(dbenv, &fh, &ondisk,
00271 sizeof(ondisk), &nr)) == 0 && nr == sizeof(ondisk)) {
00272 if (ondisk.magic != 0)
00273 goto done;
00274 if ((ret = CDB___os_seek(dbenv, &fh,
00275 pagesize, argp->pgno, 0, 0, DB_OS_SEEK_SET)) != 0)
00276 goto out;
00277 }
00278
00279
00280
00281
00282
00283 CDB___ua_memcpy(&meta->lsn, lsnp, sizeof(DB_LSN));
00284 if ((ret = CDB___os_write(dbp->dbenv, &fh,
00285 argp->page.data, argp->page.size, &nr)) != 0)
00286 goto out;
00287 if (nr != (size_t)argp->page.size) {
00288 CDB___db_err(dbenv, "Write failed during recovery");
00289 ret = EIO;
00290 goto out;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299 if ((ret = CDB___log_reopen_file(dbenv,
00300 argp->name.data, argp->fileid,
00301 meta->uid, argp->pgno)) != 0)
00302 goto out;
00303
00304
00305 } else if (DB_UNDO(op)) {
00306 is_done = 0;
00307
00308
00309 if (CDB___os_exists(real_name, NULL) != 0)
00310 goto done;
00311
00312
00313
00314
00315
00316
00317 dbp = NULL;
00318 if ((ret =
00319 CDB___db_fileid_to_db(dbenv, &dbp, argp->fileid, 0)) == 0)
00320 (void)dbp->sync(dbp, 0);
00321
00322
00323
00324
00325
00326
00327
00328
00329 if ((ret = CDB___os_open(dbenv, real_name, 0, 0, &fh)) != 0)
00330 goto out;
00331 if ((ret = CDB___os_ioinfo(dbenv,
00332 real_name, &fh, &mb, &b, &io)) != 0)
00333 goto out;
00334 if (mb != 0 || b != 0) {
00335
00336 if ((ret = CDB___os_seek(dbenv, &fh,
00337 pagesize, argp->pgno, 0, 0, DB_OS_SEEK_SET)) != 0)
00338 goto out;
00339 if ((ret = CDB___os_read(dbenv, &fh,
00340 &ondisk, sizeof(ondisk), &nr)) != 0)
00341 goto out;
00342 if (CDB_log_compare(&ondisk.lsn, lsnp) != 0)
00343 is_done = 1;
00344 }
00345
00346
00347
00348
00349
00350 if ((ret = CDB___os_closehandle(&fh)) != 0)
00351 goto out;
00352
00353 if (!is_done) {
00354
00355
00356
00357
00358
00359
00360 if (dbp != NULL && dbp->saved_open_fhp != NULL &&
00361 F_ISSET(dbp->saved_open_fhp, DB_FH_VALID) &&
00362 (ret = CDB___os_closehandle(dbp->saved_open_fhp)) != 0)
00363 goto out;
00364 if (dbp != NULL && dbp->mpf != NULL) {
00365 (void)CDB___memp_fremove(dbp->mpf);
00366 if ((ret = CDB_memp_fclose(dbp->mpf)) != 0)
00367 goto out;
00368 F_SET(dbp, DB_AM_DISCARD);
00369 dbp->mpf = NULL;
00370 }
00371 if ((ret = CDB___os_unlink(dbenv, real_name)) != 0)
00372 goto out;
00373 }
00374 }
00375
00376 done: *lsnp = argp->prev_lsn;
00377 ret = 0;
00378
00379 out: if (argp != NULL)
00380 CDB___os_free(argp, sizeof(*argp));
00381 if (real_name != NULL)
00382 CDB___os_freestr(real_name);
00383 if (F_ISSET(&fh, DB_FH_VALID))
00384 (void)CDB___os_closehandle(&fh);
00385 return (ret);
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395 int
00396 CDB___crdel_delete_recover(dbenv, dbtp, lsnp, op, info)
00397 DB_ENV *dbenv;
00398 DBT *dbtp;
00399 DB_LSN *lsnp;
00400 db_recops op;
00401 void *info;
00402 {
00403 DB *dbp;
00404 __crdel_delete_args *argp;
00405 int ret;
00406 char *backup, *real_back, *real_name;
00407
00408 REC_PRINT(CDB___crdel_delete_print);
00409
00410 backup = real_back = real_name = NULL;
00411 if ((ret = CDB___crdel_delete_read(dbenv, dbtp->data, &argp)) != 0)
00412 goto out;
00413
00414 if (DB_REDO(op)) {
00415
00416
00417
00418
00419
00420
00421 if ((ret = CDB___db_appname(dbenv, DB_APP_DATA,
00422 NULL, argp->name.data, 0, NULL, &real_name)) != 0)
00423 goto out;
00424 if (CDB___os_exists(real_name, NULL) == 0) {
00425
00426
00427
00428
00429 if ((ret = CDB___db_fileid_to_db(
00430 dbenv, &dbp, argp->fileid, 0)) != 0)
00431 goto out;
00432 (void)CDB___memp_fremove(dbp->mpf);
00433 if ((ret = CDB_memp_fclose(dbp->mpf)) != 0)
00434 goto out;
00435 dbp->mpf = NULL;
00436 if ((ret = CDB___os_unlink(dbenv, real_name)) != 0)
00437 goto out;
00438 }
00439
00440
00441
00442
00443
00444 if ((ret = CDB___db_backup_name(dbenv, argp->name.data,
00445 &backup, lsnp)) != 0)
00446 goto out;
00447 if ((ret = CDB___db_appname(dbenv,
00448 DB_APP_DATA, NULL, backup, 0, NULL, &real_back)) != 0)
00449 goto out;
00450 if (CDB___os_exists(real_back, NULL) == 0)
00451 if ((ret = CDB___os_unlink(dbenv, real_back)) != 0)
00452 goto out;
00453 if ((ret = CDB___db_txnlist_delete(dbenv, info,
00454 argp->name.data, TXNLIST_INVALID_ID, 1)) != 0)
00455 goto out;
00456 } else if (DB_UNDO(op)) {
00457
00458
00459
00460
00461
00462
00463 if ((ret = CDB___db_backup_name(dbenv, argp->name.data,
00464 &backup, lsnp)) != 0)
00465 goto out;
00466 if ((ret = CDB___db_appname(dbenv,
00467 DB_APP_DATA, NULL, backup, 0, NULL, &real_back)) != 0)
00468 goto out;
00469 if ((ret = CDB___db_appname(dbenv, DB_APP_DATA,
00470 NULL, argp->name.data, 0, NULL, &real_name)) != 0)
00471 goto out;
00472 if (CDB___os_exists(real_back, NULL) == 0)
00473 if ((ret =
00474 CDB___os_rename(dbenv, real_back, real_name)) != 0)
00475 goto out;
00476 }
00477
00478 *lsnp = argp->prev_lsn;
00479 ret = 0;
00480
00481 out: if (argp != NULL)
00482 CDB___os_free(argp, sizeof(*argp));
00483 if (backup != NULL)
00484 CDB___os_freestr(backup);
00485 if (real_back != NULL)
00486 CDB___os_freestr(real_back);
00487 if (real_name != NULL)
00488 CDB___os_freestr(real_name);
00489 return (ret);
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 int
00499 CDB___crdel_rename_recover(dbenv, dbtp, lsnp, op, info)
00500 DB_ENV *dbenv;
00501 DBT *dbtp;
00502 DB_LSN *lsnp;
00503 db_recops op;
00504 void *info;
00505 {
00506 DB *dbp;
00507 __crdel_rename_args *argp;
00508 char *new_name, *real_name;
00509 int ret, set;
00510
00511 COMPQUIET(info, NULL);
00512
00513 REC_PRINT(CDB___crdel_rename_print);
00514 if ((ret = CDB___crdel_rename_read(dbenv, dbtp->data, &argp)) != 0)
00515 goto out;
00516
00517 if ((ret = CDB___db_fileid_to_db(dbenv, &dbp, argp->fileid, 0)) != 0)
00518 goto out;
00519 if (DB_REDO(op)) {
00520
00521
00522
00523
00524 if ((ret = CDB___log_filelist_update(dbenv, NULL,
00525 argp->fileid, argp->newname.data, &set)) != 0)
00526 goto out;
00527 if (set != 0) {
00528 if ((ret = CDB___db_appname(dbenv, DB_APP_DATA,
00529 NULL, argp->name.data, 0, NULL, &real_name)) != 0)
00530 goto out;
00531 if (CDB___os_exists(real_name, NULL) == 0) {
00532 if ((ret = CDB___db_appname(dbenv,
00533 DB_APP_DATA, NULL, argp->newname.data,
00534 0, NULL, &new_name)) != 0)
00535 goto out;
00536
00537
00538
00539
00540
00541
00542
00543 (void)CDB___memp_fremove(dbp->mpf);
00544 if ((ret = CDB_memp_fclose(dbp->mpf)) != 0)
00545 goto out;
00546 dbp->mpf = NULL;
00547 if ((ret = CDB___os_rename(dbenv,
00548 real_name, new_name)) != 0)
00549 goto out;
00550 }
00551 }
00552 } else {
00553
00554
00555
00556
00557 if ((ret = CDB___log_filelist_update(dbenv, NULL,
00558 argp->fileid, argp->name.data, &set)) != 0)
00559 goto out;
00560 if (set != 0) {
00561 if ((ret = CDB___db_appname(dbenv, DB_APP_DATA,
00562 NULL, argp->newname.data, 0, NULL, &new_name)) != 0)
00563 goto out;
00564 if (CDB___os_exists(new_name, NULL) == 0) {
00565 if ((ret = CDB___db_appname(dbenv,
00566 DB_APP_DATA, NULL, argp->name.data,
00567 0, NULL, &real_name)) != 0)
00568 goto out;
00569
00570
00571
00572
00573
00574
00575 if (dbp->mpf != NULL) {
00576 (void)CDB___memp_fremove(dbp->mpf);
00577 if ((ret = CDB_memp_fclose(dbp->mpf)) != 0)
00578 goto out;
00579 dbp->mpf = NULL;
00580 }
00581 if ((ret = CDB___os_rename(dbenv,
00582 new_name, real_name)) != 0)
00583 goto out;
00584 }
00585 }
00586 }
00587
00588 *lsnp = argp->prev_lsn;
00589 ret = 0;
00590
00591 out: if (argp != NULL)
00592 CDB___os_free(argp, sizeof(*argp));
00593 return (ret);
00594 }