qam_rec.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:17k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: qam_rec.c,v 11.34 2001/01/19 18:01:59 bostic Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <string.h>
  14. #endif
  15. #include "db_int.h"
  16. #include "db_page.h"
  17. #include "db_shash.h"
  18. #include "lock.h"
  19. #include "db_am.h"
  20. #include "qam.h"
  21. #include "log.h"
  22. /*
  23.  * __qam_inc_recover --
  24.  * Recovery function for inc.
  25.  *
  26.  * PUBLIC: int __qam_inc_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  27.  */
  28. int
  29. __qam_inc_recover(dbenv, dbtp, lsnp, op, info)
  30. DB_ENV *dbenv;
  31. DBT *dbtp;
  32. DB_LSN *lsnp;
  33. db_recops op;
  34. void *info;
  35. {
  36. __qam_inc_args *argp;
  37. DB *file_dbp;
  38. DBC *dbc;
  39. DB_LOCK lock;
  40. DB_MPOOLFILE *mpf;
  41. QMETA *meta;
  42. db_pgno_t metapg;
  43. int cmp_p, modified, ret;
  44. COMPQUIET(info, NULL);
  45. REC_PRINT(__qam_inc_print);
  46. REC_INTRO(__qam_inc_read, 1);
  47. metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
  48. if ((ret = __db_lget(dbc,
  49.     LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
  50. goto done;
  51. if ((ret = memp_fget(mpf, &metapg, 0, &meta)) != 0) {
  52. if (DB_REDO(op)) {
  53. if ((ret = memp_fget(mpf,
  54.     &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
  55. (void)__LPUT(dbc, lock);
  56. goto out;
  57. }
  58. meta->dbmeta.pgno = metapg;
  59. meta->dbmeta.type = P_QAMMETA;
  60. } else {
  61. *lsnp = argp->prev_lsn;
  62. ret = 0;
  63. (void)__LPUT(dbc, lock);
  64. goto out;
  65. }
  66. }
  67. modified = 0;
  68. cmp_p = log_compare(&LSN(meta), &argp->lsn);
  69. CHECK_LSN(op, cmp_p, &LSN(meta), &argp->lsn);
  70. /*
  71.  * The cur_recno never goes backwards.  It is a point of
  72.  * contention among appenders.  If one fails cur_recno will
  73.  * most likely be beyond that one when it aborts.
  74.  * We move it ahead on either an abort or a commit
  75.  * and make the LSN reflect that fact.
  76.  */
  77. if (cmp_p == 0) {
  78. modified = 1;
  79. meta->cur_recno++;
  80. if (meta->cur_recno == RECNO_OOB)
  81. meta->cur_recno++;
  82. meta->dbmeta.lsn = *lsnp;
  83. }
  84. if ((ret = memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)))
  85. goto out;
  86. (void)__LPUT(dbc, lock);
  87. done: *lsnp = argp->prev_lsn;
  88. ret = 0;
  89. out: REC_CLOSE;
  90. }
  91. /*
  92.  * __qam_incfirst_recover --
  93.  * Recovery function for incfirst.
  94.  *
  95.  * PUBLIC: int __qam_incfirst_recover
  96.  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  97.  */
  98. int
  99. __qam_incfirst_recover(dbenv, dbtp, lsnp, op, info)
  100. DB_ENV *dbenv;
  101. DBT *dbtp;
  102. DB_LSN *lsnp;
  103. db_recops op;
  104. void *info;
  105. {
  106. __qam_incfirst_args *argp;
  107. DB *file_dbp;
  108. DBC *dbc;
  109. DB_LOCK lock;
  110. DB_MPOOLFILE *mpf;
  111. QMETA *meta;
  112. QUEUE_CURSOR *cp;
  113. db_pgno_t metapg;
  114. int exact, modified, ret, rec_ext;
  115. COMPQUIET(info, NULL);
  116. REC_PRINT(__qam_incfirst_print);
  117. REC_INTRO(__qam_incfirst_read, 1);
  118. metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
  119. if ((ret = __db_lget(dbc,
  120.     LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
  121. goto done;
  122. if ((ret = memp_fget(mpf, &metapg, 0, &meta)) != 0) {
  123. if (DB_REDO(op)) {
  124. if ((ret = memp_fget(mpf,
  125.     &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
  126. (void)__LPUT(dbc, lock);
  127. goto out;
  128. }
  129. meta->dbmeta.pgno = metapg;
  130. meta->dbmeta.type = P_QAMMETA;
  131. } else {
  132. *lsnp = argp->prev_lsn;
  133. ret = 0;
  134. (void)__LPUT(dbc, lock);
  135. goto out;
  136. }
  137. }
  138. modified = 0;
  139. /*
  140.  * Only move first_recno backwards so we pick up the aborted delete.
  141.  * When going forward we need to be careful since
  142.  * we may have bumped over a locked record.
  143.  */
  144. if (DB_UNDO(op)) {
  145. if (QAM_BEFORE_FIRST(meta, argp->recno)) {
  146. meta->first_recno = argp->recno;
  147. modified = 1;
  148. }
  149. } else {
  150. if (log_compare(&LSN(meta), lsnp) < 0) {
  151. LSN(meta) = *lsnp;
  152. modified = 1;
  153. }
  154. rec_ext = 0;
  155. if (meta->page_ext != 0)
  156. rec_ext = meta->page_ext * meta->rec_page;
  157. cp = (QUEUE_CURSOR *)dbc->internal;
  158. if (meta->first_recno == RECNO_OOB)
  159. meta->first_recno++;
  160. while (meta->first_recno != meta->cur_recno
  161.     && !QAM_BEFORE_FIRST(meta, argp->recno + 1)) {
  162. if ((ret = __qam_position(dbc,
  163.     &meta->first_recno, QAM_READ, &exact)) != 0)
  164. goto out;
  165. if (cp->page != NULL)
  166. __qam_fput(file_dbp, cp->pgno, cp->page, 0);
  167. if (exact == 1)
  168. break;
  169. if (cp->page != NULL &&
  170.     rec_ext != 0 && meta->first_recno % rec_ext == 0)
  171. if ((ret =
  172.     __qam_fremove(file_dbp, cp->pgno)) != 0)
  173. goto out;
  174. meta->first_recno++;
  175. if (meta->first_recno == RECNO_OOB)
  176. meta->first_recno++;
  177. modified = 1;
  178. }
  179. }
  180. if ((ret = memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)))
  181. goto out;
  182. (void)__LPUT(dbc, lock);
  183. done: *lsnp = argp->prev_lsn;
  184. ret = 0;
  185. out: REC_CLOSE;
  186. }
  187. /*
  188.  * __qam_mvptr_recover --
  189.  * Recovery function for mvptr.
  190.  *
  191.  * PUBLIC: int __qam_mvptr_recover
  192.  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  193.  */
  194. int
  195. __qam_mvptr_recover(dbenv, dbtp, lsnp, op, info)
  196. DB_ENV *dbenv;
  197. DBT *dbtp;
  198. DB_LSN *lsnp;
  199. db_recops op;
  200. void *info;
  201. {
  202. __qam_mvptr_args *argp;
  203. DB *file_dbp;
  204. DBC *dbc;
  205. DB_LOCK lock;
  206. DB_MPOOLFILE *mpf;
  207. QMETA *meta;
  208. db_pgno_t metapg;
  209. int cmp_p, modified, ret;
  210. COMPQUIET(info, NULL);
  211. REC_PRINT(__qam_mvptr_print);
  212. REC_INTRO(__qam_mvptr_read, 1);
  213. metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
  214. if ((ret = __db_lget(dbc,
  215.     LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
  216. goto done;
  217. if ((ret = memp_fget(mpf, &metapg, 0, &meta)) != 0) {
  218. if (DB_REDO(op)) {
  219. if ((ret = memp_fget(mpf,
  220.     &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
  221. (void)__LPUT(dbc, lock);
  222. goto out;
  223. }
  224. meta->dbmeta.pgno = metapg;
  225. meta->dbmeta.type = P_QAMMETA;
  226. } else {
  227. *lsnp = argp->prev_lsn;
  228. ret = 0;
  229. (void)__LPUT(dbc, lock);
  230. goto out;
  231. }
  232. }
  233. modified = 0;
  234. cmp_p = log_compare(&meta->dbmeta.lsn, &argp->metalsn);
  235. /*
  236.  * We never undo a movement of one of the pointers.
  237.  * Just move them along regardless of abort/commit.
  238.  */
  239. if (cmp_p == 0) {
  240. if (argp->opcode & QAM_SETFIRST)
  241. meta->first_recno = argp->new_first;
  242. if (argp->opcode & QAM_SETCUR)
  243. meta->cur_recno = argp->new_cur;
  244. modified = 1;
  245. meta->dbmeta.lsn = *lsnp;
  246. }
  247. if ((ret = memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)))
  248. goto out;
  249. (void)__LPUT(dbc, lock);
  250. done: *lsnp = argp->prev_lsn;
  251. ret = 0;
  252. out: REC_CLOSE;
  253. }
  254. /*
  255.  * __qam_del_recover --
  256.  * Recovery function for del.
  257.  * Non-extent version or if there is no data (zero len).
  258.  *
  259.  * PUBLIC: int __qam_del_recover
  260.  * PUBLIC:     __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  261.  */
  262. int
  263. __qam_del_recover(dbenv, dbtp, lsnp, op, info)
  264. DB_ENV *dbenv;
  265. DBT *dbtp;
  266. DB_LSN *lsnp;
  267. db_recops op;
  268. void *info;
  269. {
  270. __qam_del_args *argp;
  271. DB *file_dbp;
  272. DBC *dbc;
  273. DB_LOCK lock;
  274. DB_MPOOLFILE *mpf;
  275. QAMDATA *qp;
  276. QMETA *meta;
  277. QPAGE *pagep;
  278. db_pgno_t metapg;
  279. int cmp_n, modified, ret;
  280. COMPQUIET(info, NULL);
  281. REC_PRINT(__qam_del_print);
  282. REC_INTRO(__qam_del_read, 1);
  283. if ((ret = __qam_fget(file_dbp,
  284.      &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
  285. goto out;
  286. modified = 0;
  287. if (pagep->pgno == PGNO_INVALID) {
  288. pagep->pgno = argp->pgno;
  289. pagep->type = P_QAMDATA;
  290. modified = 1;
  291. }
  292. cmp_n = log_compare(lsnp, &LSN(pagep));
  293. if (DB_UNDO(op)) {
  294. /* make sure first is behind us */
  295. metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
  296. if ((ret = __db_lget(dbc,
  297.     LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0)
  298. return (ret);
  299. if ((ret = memp_fget(file_dbp->mpf, &metapg, 0, &meta)) != 0) {
  300. (void)__LPUT(dbc, lock);
  301. goto done;
  302. }
  303. if (meta->first_recno == RECNO_OOB ||
  304.     (QAM_BEFORE_FIRST(meta, argp->recno)
  305.     && (meta->first_recno <= meta->cur_recno
  306.     || meta->first_recno -
  307.     argp->recno < argp->recno - meta->cur_recno))) {
  308. meta->first_recno = argp->recno;
  309. (void)memp_fput(file_dbp->mpf, meta, DB_MPOOL_DIRTY);
  310. } else
  311. (void)memp_fput(file_dbp->mpf, meta, 0);
  312. (void)__LPUT(dbc, lock);
  313. /* Need to undo delete - mark the record as present */
  314. qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
  315. F_SET(qp, QAM_VALID);
  316. /*
  317.  * Move the LSN back to this point;  do not move it forward.
  318.  * Only move it back if we're in recovery.  If we're in
  319.  * an abort, because we don't hold a page lock, we could
  320.  * foul up a concurrent put.  Having too late an LSN
  321.  * is harmless in queue except when we're determining
  322.  * what we need to roll forward during recovery.  [#2588]
  323.  */
  324. if (op == DB_TXN_BACKWARD_ROLL && cmp_n < 0)
  325. LSN(pagep) = argp->lsn;
  326. modified = 1;
  327. } else if (cmp_n > 0 && DB_REDO(op)) {
  328. /* Need to redo delete - clear the valid bit */
  329. qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
  330. F_CLR(qp, QAM_VALID);
  331. LSN(pagep) = *lsnp;
  332. modified = 1;
  333. }
  334. if ((ret = __qam_fput(file_dbp,
  335.     argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)))
  336. goto out;
  337. done: *lsnp = argp->prev_lsn;
  338. ret = 0;
  339. out: REC_CLOSE;
  340. }
  341. /*
  342.  * __qam_delext_recover --
  343.  * Recovery function for del in an extent based queue.
  344.  *
  345.  * PUBLIC: int __qam_delext_recover __P((DB_ENV *,
  346.  * PUBLIC:     DBT *, DB_LSN *, db_recops, void *));
  347.  */
  348. int
  349. __qam_delext_recover(dbenv, dbtp, lsnp, op, info)
  350. DB_ENV *dbenv;
  351. DBT *dbtp;
  352. DB_LSN *lsnp;
  353. db_recops op;
  354. void *info;
  355. {
  356. __qam_delext_args *argp;
  357. DB *file_dbp;
  358. DBC *dbc;
  359. DB_LOCK lock;
  360. DB_MPOOLFILE *mpf;
  361. QAMDATA *qp;
  362. QMETA *meta;
  363. QPAGE *pagep;
  364. db_pgno_t metapg;
  365. int cmp_n, modified, ret;
  366. COMPQUIET(info, NULL);
  367. REC_PRINT(__qam_delext_print);
  368. REC_INTRO(__qam_delext_read, 1);
  369. if ((ret = __qam_fget(file_dbp,
  370.      &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
  371. goto out;
  372. modified = 0;
  373. if (pagep->pgno == PGNO_INVALID) {
  374. pagep->pgno = argp->pgno;
  375. pagep->type = P_QAMDATA;
  376. modified = 1;
  377. }
  378. cmp_n = log_compare(lsnp, &LSN(pagep));
  379. if (DB_UNDO(op)) {
  380. /* make sure first is behind us */
  381. metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
  382. if ((ret = __db_lget(dbc,
  383.     LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0)
  384. return (ret);
  385. if ((ret = memp_fget(file_dbp->mpf, &metapg, 0, &meta)) != 0) {
  386. (void)__LPUT(dbc, lock);
  387. goto done;
  388. }
  389. if (meta->first_recno == RECNO_OOB ||
  390.     (QAM_BEFORE_FIRST(meta, argp->recno)
  391.     && (meta->first_recno <= meta->cur_recno
  392.     || meta->first_recno -
  393.     argp->recno < argp->recno - meta->cur_recno))) {
  394. meta->first_recno = argp->recno;
  395. (void)memp_fput(file_dbp->mpf, meta, DB_MPOOL_DIRTY);
  396. } else
  397. (void)memp_fput(file_dbp->mpf, meta, 0);
  398. (void)__LPUT(dbc, lock);
  399. if ((ret = __qam_pitem(dbc, pagep,
  400.     argp->indx, argp->recno, &argp->data)) != 0)
  401. goto done;
  402. /*
  403.  * Move the LSN back to this point;  do not move it forward.
  404.  * Only move it back if we're in recovery.  If we're in
  405.  * an abort, because we don't hold a page lock, we could
  406.  * foul up a concurrent put.  Having too late an LSN
  407.  * is harmless in queue except when we're determining
  408.  * what we need to roll forward during recovery.  [#2588]
  409.  */
  410. if (op == DB_TXN_BACKWARD_ROLL && cmp_n < 0)
  411. LSN(pagep) = argp->lsn;
  412. modified = 1;
  413. } else if (cmp_n > 0 && DB_REDO(op)) {
  414. /* Need to redo delete - clear the valid bit */
  415. qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
  416. F_CLR(qp, QAM_VALID);
  417. LSN(pagep) = *lsnp;
  418. modified = 1;
  419. }
  420. if ((ret = __qam_fput(file_dbp,
  421.     argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)))
  422. goto out;
  423. done: *lsnp = argp->prev_lsn;
  424. ret = 0;
  425. out: REC_CLOSE;
  426. }
  427. /*
  428.  * __qam_add_recover --
  429.  * Recovery function for add.
  430.  *
  431.  * PUBLIC: int __qam_add_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  432.  */
  433. int
  434. __qam_add_recover(dbenv, dbtp, lsnp, op, info)
  435. DB_ENV *dbenv;
  436. DBT *dbtp;
  437. DB_LSN *lsnp;
  438. db_recops op;
  439. void *info;
  440. {
  441. __qam_add_args *argp;
  442. DB *file_dbp;
  443. DBC *dbc;
  444. DB_MPOOLFILE *mpf;
  445. QAMDATA *qp;
  446. QMETA *meta;
  447. QPAGE *pagep;
  448. db_pgno_t metapg;
  449. int cmp_n, modified, ret;
  450. COMPQUIET(info, NULL);
  451. REC_PRINT(__qam_add_print);
  452. REC_INTRO(__qam_add_read, 1);
  453. modified = 0;
  454. if ((ret = __qam_fget(file_dbp,
  455.     &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
  456. goto out;
  457. if (pagep->pgno == PGNO_INVALID) {
  458. pagep->pgno = argp->pgno;
  459. pagep->type = P_QAMDATA;
  460. modified = 1;
  461. }
  462. cmp_n = log_compare(lsnp, &LSN(pagep));
  463. if (cmp_n > 0 && DB_REDO(op)) {
  464. /* Need to redo add - put the record on page */
  465. if ((ret = __qam_pitem(dbc, pagep, argp->indx, argp->recno,
  466. &argp->data)) != 0)
  467. goto err;
  468. LSN(pagep) = *lsnp;
  469. modified = 1;
  470. /* Make sure first pointer includes this record. */
  471. metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
  472. if ((ret = memp_fget(mpf, &metapg, 0, &meta)) != 0)
  473. goto err;
  474. if (QAM_BEFORE_FIRST(meta, argp->recno)) {
  475. meta->first_recno = argp->recno;
  476. if ((ret = memp_fput(mpf, meta, DB_MPOOL_DIRTY)) != 0)
  477. goto err;
  478. } else
  479. if ((ret = memp_fput(mpf, meta, 0)) != 0)
  480. goto err;
  481. } else if (DB_UNDO(op)) {
  482. /*
  483.  * Need to undo add
  484.  * If this was an overwrite, put old record back.
  485.  * Otherwise just clear the valid bit
  486.  */
  487. if (argp->olddata.size != 0) {
  488. if ((ret = __qam_pitem(dbc, pagep,
  489.     argp->indx, argp->recno, &argp->olddata)) != 0)
  490. goto err;
  491. if (!(argp->vflag & QAM_VALID)) {
  492. qp = QAM_GET_RECORD(
  493.     file_dbp, pagep, argp->indx);
  494. F_CLR(qp, QAM_VALID);
  495. }
  496. modified = 1;
  497. } else {
  498. qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
  499. qp->flags = 0;
  500. modified = 1;
  501. }
  502. /*
  503.  * Move the LSN back to this point;  do not move it forward.
  504.  * Only move it back if we're in recovery.  If we're in
  505.  * an abort, because we don't hold a page lock, we could
  506.  * foul up a concurrent put.  Having too late an LSN
  507.  * is harmless in queue except when we're determining
  508.  * what we need to roll forward during recovery.  [#2588]
  509.  */
  510. if (op == DB_TXN_BACKWARD_ROLL && cmp_n < 0)
  511. LSN(pagep) = argp->lsn;
  512. }
  513. err: if ((ret = __qam_fput(file_dbp,
  514.     argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)))
  515. goto out;
  516. done: *lsnp = argp->prev_lsn;
  517. ret = 0;
  518. out: REC_CLOSE;
  519. }
  520. /*
  521.  * __qam_delete_recover --
  522.  * Recovery function for delete of an extent.
  523.  *
  524.  * PUBLIC: int __qam_delete_recover
  525.  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  526.  */
  527. int
  528. __qam_delete_recover(dbenv, dbtp, lsnp, op, info)
  529. DB_ENV *dbenv;
  530. DBT *dbtp;
  531. DB_LSN *lsnp;
  532. db_recops op;
  533. void *info;
  534. {
  535. __qam_delete_args *argp;
  536. int ret;
  537. char *backup, *real_back, *real_name;
  538. COMPQUIET(info, NULL);
  539. REC_PRINT(__qam_delete_print);
  540. backup = real_back = real_name = NULL;
  541. if ((ret = __qam_delete_read(dbenv, dbtp->data, &argp)) != 0)
  542. goto out;
  543. if (DB_REDO(op)) {
  544. /*
  545.  * On a recovery, as we recreate what was going on, we
  546.  * recreate the creation of the file.  And so, even though
  547.  * it committed, we need to delete it.  Try to delete it,
  548.  * but it is not an error if that delete fails.
  549.  */
  550. if ((ret = __db_appname(dbenv, DB_APP_DATA,
  551.     NULL, argp->name.data, 0, NULL, &real_name)) != 0)
  552. goto out;
  553. if (__os_exists(real_name, NULL) == 0) {
  554. if ((ret = __os_unlink(dbenv, real_name)) != 0)
  555. goto out;
  556. }
  557. } else if (DB_UNDO(op)) {
  558. /*
  559.  * Trying to undo.  File may or may not have been deleted.
  560.  * Try to move the backup to the original.  If the backup
  561.  * exists, then this is right.  If it doesn't exist, then
  562.  * nothing will happen and that's OK.
  563.  */
  564. if ((ret =  __db_backup_name(dbenv, argp->name.data,
  565.     &backup, &argp->lsn)) != 0)
  566. goto out;
  567. if ((ret = __db_appname(dbenv,
  568.     DB_APP_DATA, NULL, backup, 0, NULL, &real_back)) != 0)
  569. goto out;
  570. if ((ret = __db_appname(dbenv, DB_APP_DATA,
  571.     NULL, argp->name.data, 0, NULL, &real_name)) != 0)
  572. goto out;
  573. if (__os_exists(real_back, NULL) == 0)
  574. if ((ret =
  575.      __os_rename(dbenv, real_back, real_name)) != 0)
  576. goto out;
  577. }
  578. *lsnp = argp->prev_lsn;
  579. ret = 0;
  580. out: if (argp != NULL)
  581. __os_free(argp, 0);
  582. if (backup != NULL)
  583. __os_freestr(backup);
  584. if (real_back != NULL)
  585. __os_freestr(real_back);
  586. if (real_name != NULL)
  587. __os_freestr(real_name);
  588. return (ret);
  589. }
  590. /*
  591.  * __qam_rename_recover --
  592.  * Recovery function for rename.
  593.  *
  594.  * PUBLIC: int __qam_rename_recover
  595.  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
  596.  */
  597. int
  598. __qam_rename_recover(dbenv, dbtp, lsnp, op, info)
  599. DB_ENV *dbenv;
  600. DBT *dbtp;
  601. DB_LSN *lsnp;
  602. db_recops op;
  603. void *info;
  604. {
  605. __qam_rename_args *argp;
  606. char *new_name, *real_name;
  607. int ret;
  608. COMPQUIET(info, NULL);
  609. REC_PRINT(__qam_rename_print);
  610. new_name = real_name = NULL;
  611. if ((ret = __qam_rename_read(dbenv, dbtp->data, &argp)) != 0)
  612. goto out;
  613. if (DB_REDO(op)) {
  614. if ((ret = __db_appname(dbenv, DB_APP_DATA,
  615.     NULL, argp->name.data, 0, NULL, &real_name)) != 0)
  616. goto out;
  617. if (__os_exists(real_name, NULL) == 0) {
  618. if ((ret = __db_appname(dbenv,
  619.     DB_APP_DATA, NULL, argp->newname.data,
  620.     0, NULL, &new_name)) != 0)
  621. goto out;
  622. if ((ret = __os_rename(dbenv,
  623.     real_name, new_name)) != 0)
  624. goto out;
  625. }
  626. } else {
  627. if ((ret = __db_appname(dbenv, DB_APP_DATA,
  628.     NULL, argp->newname.data, 0, NULL, &new_name)) != 0)
  629. goto out;
  630. if (__os_exists(new_name, NULL) == 0) {
  631. if ((ret = __db_appname(dbenv,
  632.     DB_APP_DATA, NULL, argp->name.data,
  633.     0, NULL, &real_name)) != 0)
  634. goto out;
  635. if ((ret = __os_rename(dbenv,
  636.     new_name, real_name)) != 0)
  637. goto out;
  638. }
  639. }
  640. *lsnp = argp->prev_lsn;
  641. ret = 0;
  642. out: if (argp != NULL)
  643. __os_free(argp, 0);
  644. if (new_name != NULL)
  645. __os_free(new_name, 0);
  646. if (real_name != NULL)
  647. __os_free(real_name, 0);
  648. return (ret);
  649. }