qam_verify.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1999-2002
  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.30 2002/06/26 20:49:27 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 "dbinc/db_page.h"
  16. #include "dbinc/db_verify.h"
  17. #include "dbinc/qam.h"
  18. #include "dbinc/db_am.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,
  45.     "Page %lu: queue databases must be one-per-file",
  46.     (u_long)pgno));
  47. /*
  48.  * cur_recno/rec_page
  49.  * Cur_recno may be one beyond the end of the page and
  50.  * we start numbering from 1.
  51.  */
  52. if (vdp->last_pgno > 0 && meta->cur_recno > 0 &&
  53.     meta->cur_recno - 1 > meta->rec_page * vdp->last_pgno) {
  54. EPRINT((dbp->dbenv,
  55.     "Page %lu: current recno %lu references record past last page number %lu",
  56.     (u_long)pgno,
  57.     (u_long)meta->cur_recno, (u_long)vdp->last_pgno));
  58. isbad = 1;
  59. }
  60. /*
  61.  * re_len:  If this is bad, we can't safely verify queue data pages, so
  62.  * return DB_VERIFY_FATAL
  63.  */
  64. if (ALIGN(meta->re_len + sizeof(QAMDATA) - 1, sizeof(u_int32_t)) *
  65.     meta->rec_page + QPAGE_SZ(dbp) > dbp->pgsize) {
  66. EPRINT((dbp->dbenv,
  67.    "Page %lu: queue record length %lu too high for page size and recs/page",
  68.     (u_long)pgno, (u_long)meta->re_len));
  69. ret = DB_VERIFY_FATAL;
  70. goto err;
  71. } else {
  72. vdp->re_len = meta->re_len;
  73. vdp->rec_page = meta->rec_page;
  74. }
  75. err: if ((t_ret =
  76.     __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)
  77. ret = t_ret;
  78. return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret);
  79. }
  80. /*
  81.  * __qam_vrfy_data --
  82.  * Verify a queue data page.
  83.  *
  84.  * PUBLIC: int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *,
  85.  * PUBLIC:     db_pgno_t, u_int32_t));
  86.  */
  87. int
  88. __qam_vrfy_data(dbp, vdp, h, pgno, flags)
  89. DB *dbp;
  90. VRFY_DBINFO *vdp;
  91. QPAGE *h;
  92. db_pgno_t pgno;
  93. u_int32_t flags;
  94. {
  95. DB fakedb;
  96. struct __queue fakeq;
  97. QAMDATA *qp;
  98. db_recno_t i;
  99. u_int8_t qflags;
  100. /*
  101.  * Not much to do here, except make sure that flags are reasonable.
  102.  *
  103.  * QAM_GET_RECORD assumes a properly initialized q_internal
  104.  * structure, however, and we don't have one, so we play
  105.  * some gross games to fake it out.
  106.  */
  107. fakedb.q_internal = &fakeq;
  108. fakedb.flags = dbp->flags;
  109. fakeq.re_len = vdp->re_len;
  110. for (i = 0; i < vdp->rec_page; i++) {
  111. qp = QAM_GET_RECORD(&fakedb, h, i);
  112. if ((u_int8_t *)qp >= (u_int8_t *)h + dbp->pgsize) {
  113. EPRINT((dbp->dbenv,
  114.     "Page %lu: queue record %lu extends past end of page",
  115.     (u_long)pgno, (u_long)i));
  116. return (DB_VERIFY_BAD);
  117. }
  118. qflags = qp->flags;
  119. qflags &= !(QAM_VALID | QAM_SET);
  120. if (qflags != 0) {
  121. EPRINT((dbp->dbenv,
  122.     "Page %lu: queue record %lu has bad flags",
  123.     (u_long)pgno, (u_long)i));
  124. return (DB_VERIFY_BAD);
  125. }
  126. }
  127. return (0);
  128. }
  129. /*
  130.  * __qam_vrfy_structure --
  131.  * Verify a queue database structure, such as it is.
  132.  *
  133.  * PUBLIC: int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
  134.  */
  135. int
  136. __qam_vrfy_structure(dbp, vdp, flags)
  137. DB *dbp;
  138. VRFY_DBINFO *vdp;
  139. u_int32_t flags;
  140. {
  141. VRFY_PAGEINFO *pip;
  142. db_pgno_t i;
  143. int ret, isbad;
  144. isbad = 0;
  145. if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)
  146. return (ret);
  147. if (pip->type != P_QAMMETA) {
  148. EPRINT((dbp->dbenv,
  149.     "Page %lu: queue database has no meta page",
  150.     (u_long)PGNO_BASE_MD));
  151. isbad = 1;
  152. goto err;
  153. }
  154. if ((ret = __db_vrfy_pgset_inc(vdp->pgset, 0)) != 0)
  155. goto err;
  156. for (i = 1; i <= vdp->last_pgno; i++) {
  157. /* Send feedback to the application about our progress. */
  158. if (!LF_ISSET(DB_SALVAGE))
  159. __db_vrfy_struct_feedback(dbp, vdp);
  160. if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 ||
  161.     (ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
  162. return (ret);
  163. if (!F_ISSET(pip, VRFY_IS_ALLZEROES) &&
  164.     pip->type != P_QAMDATA) {
  165. EPRINT((dbp->dbenv,
  166.     "Page %lu: queue database page of incorrect type %lu",
  167.     (u_long)i, (u_long)pip->type));
  168. isbad = 1;
  169. goto err;
  170. } else if ((ret = __db_vrfy_pgset_inc(vdp->pgset, i)) != 0)
  171. goto err;
  172. }
  173. err: if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0)
  174. return (ret);
  175. return (isbad == 1 ? DB_VERIFY_BAD : 0);
  176. }