Blob


1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
5 static int
6 checkbucket(Index *ix, u32int buck, IBucket *ib)
7 {
8 ISect *is;
9 DBlock *eb;
10 IBucket eib;
11 IEntry ie, eie;
12 int i, ei, ok, c;
14 is = findisect(ix, buck);
15 if(is == nil){
16 seterr(EAdmin, "bad math in checkbuckets");
17 return -1;
18 }
19 buck -= is->start;
20 eb = getdblock(is->part, is->blockbase + ((u64int)buck << is->blocklog), 1);
21 if(eb == nil)
22 return -1;
23 unpackibucket(&eib, eb->data);
25 ok = 0;
26 ei = 0;
27 for(i = 0; i < ib->n; i++){
28 while(ei < eib.n){
29 c = ientrycmp(&ib->data[i * IEntrySize], &eib.data[ei * IEntrySize]);
30 if(c == 0){
31 unpackientry(&ie, &ib->data[i * IEntrySize]);
32 unpackientry(&eie, &eib.data[ei * IEntrySize]);
33 if(iaddrcmp(&ie.ia, &eie.ia) != 0){
34 fprint(2, "bad entry in index for score=%V\n", &ib->data[i * IEntrySize]);
35 fprint(2, "\taddr=%lld type=%d size=%d blocks=%d\n",
36 ie.ia.addr, ie.ia.type, ie.ia.size, ie.ia.blocks);
37 fprint(2, "\taddr=%lld type=%d size=%d blocks=%d\n",
38 eie.ia.addr, eie.ia.type, eie.ia.size, eie.ia.blocks);
39 }
40 ei++;
41 goto cont;
42 }
43 if(c < 0)
44 break;
45 if(1)
46 fprint(2, "spurious entry in index for score=%V type=%d\n",
47 &eib.data[ei * IEntrySize], eib.data[ei * IEntrySize + IEntryTypeOff]);
48 ei++;
49 ok = -1;
50 }
51 fprint(2, "missing entry in index for score=%V type=%d\n",
52 &ib->data[i * IEntrySize], ib->data[i * IEntrySize + IEntryTypeOff]);
53 ok = -1;
54 cont:;
55 }
56 for(; ei < eib.n; ei++){
57 if(1) fprint(2, "spurious entry in index for score=%V; found %d entries expected %d\n",
58 &eib.data[ei * IEntrySize], eib.n, ib->n);
59 ok = -1;
60 break;
61 }
62 putdblock(eb);
63 return ok;
64 }
66 int
67 checkindex(Index *ix, Part *part, u64int off, u64int clumps, int zero)
68 {
69 IEStream *ies;
70 IBucket ib, zib;
71 ZBlock *z, *b;
72 u32int next, buck;
73 int ok, bok;
74 u64int found = 0;
76 //ZZZ make buffer size configurable
77 b = alloczblock(ix->blocksize, 0);
78 z = alloczblock(ix->blocksize, 1);
79 ies = initiestream(part, off, clumps, 64*1024);
80 if(b == nil || z == nil || ies == nil){
81 ok = -1;
82 goto breakout;
83 return -1;
84 }
85 ok = 0;
86 next = 0;
87 ib.data = b->data;
88 zib.data = z->data;
89 zib.n = 0;
90 zib.next = 0;
91 for(;;){
92 buck = buildbucket(ix, ies, &ib);
93 found += ib.n;
94 if(zero){
95 for(; next != buck; next++){
96 if(next == ix->buckets){
97 if(buck != TWID32)
98 fprint(2, "bucket out of range\n");
99 goto breakout;
101 bok = checkbucket(ix, next, &zib);
102 if(bok < 0){
103 fprint(2, "bad bucket=%d found: %r\n", next);
104 ok = -1;
108 if(buck >= ix->buckets){
109 if(buck == TWID32)
110 break;
111 fprint(2, "bucket out of range\n");
112 ok = -1;
113 goto breakout;
115 bok = checkbucket(ix, buck, &ib);
116 if(bok < 0){
117 fprint(2, "bad bucket found=%lld: %r\n", found);
118 ok = -1;
120 next = buck + 1;
122 breakout:;
123 fprint(2, "found %lld entries in sorted list\n", found);
124 freeiestream(ies);
125 freezblock(z);
126 freezblock(b);
127 return ok;
130 void
131 usage(void)
133 fprint(2, "usage: checkindex [-f] [-B blockcachesize] config tmp\n");
134 threadexitsall(0);
137 void
138 threadmain(int argc, char *argv[])
140 Part *part;
141 u64int clumps, base;
142 u32int bcmem;
143 int fix, skipz;
145 fix = 0;
146 bcmem = 0;
147 skipz = 0;
148 ARGBEGIN{
149 case 'B':
150 bcmem = unittoull(ARGF());
151 break;
152 case 'f':
153 fix++;
154 break;
155 case 'Z':
156 skipz = 1;
157 break;
158 default:
159 usage();
160 break;
161 }ARGEND
163 if(!fix)
164 readonly = 1;
166 if(argc != 2)
167 usage();
169 if(initventi(argv[0]) < 0)
170 sysfatal("can't init venti: %r");
172 if(bcmem < maxblocksize * (mainindex->narenas + mainindex->nsects * 4 + 16))
173 bcmem = maxblocksize * (mainindex->narenas + mainindex->nsects * 4 + 16);
174 fprint(2, "initialize %d bytes of disk block cache\n", bcmem);
175 initdcache(bcmem);
177 part = initpart(argv[1], 1);
178 if(part == nil)
179 sysfatal("can't initialize temporary partition: %r");
181 clumps = sortrawientries(mainindex, part, &base);
182 if(clumps == TWID64)
183 sysfatal("can't build sorted index: %r");
184 fprint(2, "found and sorted index entries for clumps=%lld at %lld\n", clumps, base);
185 checkindex(mainindex, part, base, clumps, !skipz);
187 threadexitsall(0);