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

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_verify.c,v 1.17 2000/12/12 17:39:35 bostic Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #endif
  14. #include "db_int.h"
  15. #include "db_page.h"
  16. #include "db_verify.h"
  17. #include "qam.h"
  18. #include "db_ext.h"
  19. /*
  20.  * __qam_vrfy_meta --
  21.  * Verify the queue-specific part of a metadata page.
  22.  *
  23.  * PUBLIC: int __qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *,
  24.  * PUBLIC:     db_pgno_t, u_int32_t));
  25.  */
  26. int
  27. __qam_vrfy_meta(dbp, vdp, meta, pgno, flags)
  28. DB *dbp;
  29. VRFY_DBINFO *vdp;
  30. QMETA *meta;
  31. db_pgno_t pgno;
  32. u_int32_t flags;
  33. {
  34. VRFY_PAGEINFO *pip;
  35. int isbad, ret, t_ret;
  36. if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
  37. return (ret);
  38. isbad = 0;
  39. /*
  40.  * Queue can't be used in subdatabases, so if this isn't set
  41.  * something very odd is going on.
  42.  */
  43. if (!F_ISSET(pip, VRFY_INCOMPLETE))
  44. EPRINT((dbp->dbenv, "Queue databases must be one-per-file."));
  45. /*
  46.  * cur_recno/rec_page
  47.  * Cur_recno may be one beyond the end of the page and
  48.  * we start numbering from 1.
  49.  */
  50. if (vdp->last_pgno > 0 && meta->cur_recno > 0 &&
  51.     meta->cur_recno - 1 > meta->rec_page * vdp->last_pgno) {
  52. EPRINT((dbp->dbenv,
  53.     "Current recno %lu references record past last page number %lu",
  54.     meta->cur_recno, vdp->last_pgno));
  55. isbad = 1;
  56. }
  57. /*
  58.  * re_len:  If this is bad, we can't safely verify queue data pages, so
  59.  * return DB_VERIFY_FATAL
  60.  */
  61. if (ALIGN(meta->re_len + sizeof(QAMDATA) - 1, sizeof(u_int32_t)) *
  62.     meta->rec_page + sizeof(QPAGE) > dbp->pgsize) {
  63. EPRINT((dbp->dbenv,
  64.    "Queue record length %lu impossibly high for page size and records per page",
  65.     meta->re_len));
  66. ret = DB_VERIFY_FATAL;
  67. goto err;
  68. } else {
  69. vdp->re_len = meta->re_len;
  70. vdp->rec_page = meta->rec_page;
  71. }
  72. err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0)
  73. ret = t_ret;
  74. return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret);
  75. }
  76. /*
  77.  * __qam_vrfy_data --
  78.  * Verify a queue data page.
  79.  *
  80.  * PUBLIC: int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *,
  81.  * PUBLIC:     db_pgno_t, u_int32_t));
  82.  */
  83. int
  84. __qam_vrfy_data(dbp, vdp, h, pgno, flags)
  85. DB *dbp;
  86. VRFY_DBINFO *vdp;
  87. QPAGE *h;
  88. db_pgno_t pgno;
  89. u_int32_t flags;
  90. {
  91. DB fakedb;
  92. struct __queue fakeq;
  93. QAMDATA *qp;
  94. db_recno_t i;
  95. u_int8_t qflags;
  96. /*
  97.  * Not much to do here, except make sure that flags are reasonable.
  98.  *
  99.  * QAM_GET_RECORD assumes a properly initialized q_internal
  100.  * structure, however, and we don't have one, so we play
  101.  * some gross games to fake it out.
  102.  */
  103. fakedb.q_internal = &fakeq;
  104. fakeq.re_len = vdp->re_len;
  105. for (i = 0; i < vdp->rec_page; i++) {
  106. qp = QAM_GET_RECORD(&fakedb, h, i);
  107. if ((u_int8_t *)qp >= (u_int8_t *)h + dbp->pgsize) {
  108. EPRINT((dbp->dbenv,
  109.     "Queue record %lu extends past end of page %lu",
  110.     i, pgno));
  111. return (DB_VERIFY_BAD);
  112. }
  113. qflags = qp->flags;
  114. qflags &= !(QAM_VALID | QAM_SET);
  115. if (qflags != 0) {
  116. EPRINT((dbp->dbenv,
  117.     "Queue record %lu on page %lu has bad flags",
  118.     i, pgno));
  119. return (DB_VERIFY_BAD);
  120. }
  121. }
  122. return (0);
  123. }
  124. /*
  125.  * __qam_vrfy_structure --
  126.  * Verify a queue database structure, such as it is.
  127.  *
  128.  * PUBLIC: int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
  129.  */
  130. int
  131. __qam_vrfy_structure(dbp, vdp, flags)
  132. DB *dbp;
  133. VRFY_DBINFO *vdp;
  134. u_int32_t flags;
  135. {
  136. VRFY_PAGEINFO *pip;
  137. db_pgno_t i;
  138. int ret, isbad;
  139. isbad = 0;
  140. if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)
  141. return (ret);
  142. if (pip->type != P_QAMMETA) {
  143. EPRINT((dbp->dbenv,
  144.     "Queue database has no meta page"));
  145. isbad = 1;
  146. goto err;
  147. }
  148. if ((ret = __db_vrfy_pgset_inc(vdp->pgset, 0)) != 0)
  149. goto err;
  150. for (i = 1; i <= vdp->last_pgno; i++) {
  151. /* Send feedback to the application about our progress. */
  152. if (!LF_ISSET(DB_SALVAGE))
  153. __db_vrfy_struct_feedback(dbp, vdp);
  154. if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 ||
  155.     (ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
  156. return (ret);
  157. if (!F_ISSET(pip, VRFY_IS_ALLZEROES) &&
  158.     pip->type != P_QAMDATA) {
  159. EPRINT((dbp->dbenv,
  160.     "Queue database page %lu of incorrect type %lu",
  161.     i, pip->type));
  162. isbad = 1;
  163. goto err;
  164. } else if ((ret = __db_vrfy_pgset_inc(vdp->pgset, i)) != 0)
  165. goto err;
  166. }
  167. err: if ((ret = __db_vrfy_putpageinfo(vdp, pip)) != 0)
  168. return (ret);
  169. return (isbad == 1 ? DB_VERIFY_BAD : 0);
  170. }