~vlad-lesin/percona-server/mysql-5.0.33-original

« back to all changes in this revision

Viewing changes to bdb/qam/qam_verify.c

  • Committer: Vlad Lesin
  • Date: 2012-07-31 09:21:34 UTC
  • Revision ID: vladislav.lesin@percona.com-20120731092134-zfodx022b7992wsi
VirginĀ 5.0.33

Show diffs side-by-side

added added

removed removed

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