1 a0d146ed 2005-07-12 devnull #include "stdinc.h"
2 a0d146ed 2005-07-12 devnull #include "dat.h"
3 a0d146ed 2005-07-12 devnull #include "fns.h"
5 e7e953b3 2012-04-22 rsc int bootstrap = 0;
6 28b49df3 2006-07-18 devnull int syncwrites = 0;
7 a0d146ed 2005-07-12 devnull int queuewrites = 0;
8 a0d146ed 2005-07-12 devnull int writestodevnull = 0;
9 27d28098 2007-04-21 devnull int verifywrites = 0;
11 7a400ee9 2007-09-25 rsc static Packet *readilump(Lump *u, IAddr *ia, u8int *score);
14 27d28098 2007-04-21 devnull * Some of this logic is duplicated in hdisk.c
17 a0d146ed 2005-07-12 devnull readlump(u8int *score, int type, u32int size, int *cached)
20 a0d146ed 2005-07-12 devnull Packet *p;
21 a0d146ed 2005-07-12 devnull IAddr ia;
22 a0d146ed 2005-07-12 devnull u32int n;
24 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump enter");
26 a0d146ed 2005-07-12 devnull qlock(&stats.lock);
27 a0d146ed 2005-07-12 devnull stats.lumpreads++;
28 a0d146ed 2005-07-12 devnull qunlock(&stats.lock);
30 a0d146ed 2005-07-12 devnull if(scorecmp(score, zeroscore) == 0)
31 a0d146ed 2005-07-12 devnull return packetalloc();
32 a0d146ed 2005-07-12 devnull u = lookuplump(score, type);
33 a0d146ed 2005-07-12 devnull if(u->data != nil){
34 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump lookuplump hit");
35 a0d146ed 2005-07-12 devnull if(cached)
36 a0d146ed 2005-07-12 devnull *cached = 1;
37 a0d146ed 2005-07-12 devnull n = packetsize(u->data);
38 a0d146ed 2005-07-12 devnull if(n > size){
39 a0d146ed 2005-07-12 devnull seterr(EOk, "read too small: asked for %d need at least %d", size, n);
40 a0d146ed 2005-07-12 devnull putlump(u);
42 a0d146ed 2005-07-12 devnull return nil;
44 a0d146ed 2005-07-12 devnull p = packetdup(u->data, 0, n);
45 a0d146ed 2005-07-12 devnull putlump(u);
46 a0d146ed 2005-07-12 devnull return p;
49 a0d146ed 2005-07-12 devnull if(cached)
50 a0d146ed 2005-07-12 devnull *cached = 0;
52 7a400ee9 2007-09-25 rsc if(lookupscore(score, type, &ia) < 0){
53 28b49df3 2006-07-18 devnull /* ZZZ place to check for someone trying to guess scores */
54 a0d146ed 2005-07-12 devnull seterr(EOk, "no block with score %V/%d exists", score, type);
56 a0d146ed 2005-07-12 devnull putlump(u);
57 a0d146ed 2005-07-12 devnull return nil;
59 a0d146ed 2005-07-12 devnull if(ia.size > size){
60 a0d146ed 2005-07-12 devnull seterr(EOk, "read too small 1: asked for %d need at least %d", size, ia.size);
62 a0d146ed 2005-07-12 devnull putlump(u);
63 a0d146ed 2005-07-12 devnull return nil;
66 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump readilump");
67 7a400ee9 2007-09-25 rsc p = readilump(u, &ia, score);
68 a0d146ed 2005-07-12 devnull putlump(u);
70 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump exit");
71 a0d146ed 2005-07-12 devnull return p;
75 a0d146ed 2005-07-12 devnull * save away a lump, and return it's score.
76 a0d146ed 2005-07-12 devnull * doesn't store duplicates, but checks that the data is really the same.
79 a0d146ed 2005-07-12 devnull writelump(Packet *p, u8int *score, int type, u32int creator, uint ms)
85 a0d146ed 2005-07-12 devnull qlock(&stats.lock);
86 a0d146ed 2005-07-12 devnull stats.lumpwrites++;
87 a0d146ed 2005-07-12 devnull qunlock(&stats.lock);
90 a0d146ed 2005-07-12 devnull packetsha1(p, score);
91 a0d146ed 2005-07-12 devnull if(packetsize(p) == 0 || writestodevnull==1){
92 a0d146ed 2005-07-12 devnull packetfree(p);
93 a0d146ed 2005-07-12 devnull return 0;
96 a0d146ed 2005-07-12 devnull u = lookuplump(score, type);
97 a0d146ed 2005-07-12 devnull if(u->data != nil){
99 a0d146ed 2005-07-12 devnull if(packetcmp(p, u->data) != 0){
100 28b49df3 2006-07-18 devnull uchar nscore[VtScoreSize];
102 28b49df3 2006-07-18 devnull packetsha1(u->data, nscore);
103 28b49df3 2006-07-18 devnull if(scorecmp(u->score, score) != 0)
104 28b49df3 2006-07-18 devnull seterr(EStrange, "lookuplump returned bad score %V not %V", u->score, score);
105 28b49df3 2006-07-18 devnull else if(scorecmp(u->score, nscore) != 0)
106 28b49df3 2006-07-18 devnull seterr(EStrange, "lookuplump returned bad data %V not %V", nscore, u->score);
108 28b49df3 2006-07-18 devnull seterr(EStrange, "score collision %V", score);
109 a0d146ed 2005-07-12 devnull ok = -1;
111 a0d146ed 2005-07-12 devnull packetfree(p);
112 a0d146ed 2005-07-12 devnull putlump(u);
113 a0d146ed 2005-07-12 devnull return ok;
116 a0d146ed 2005-07-12 devnull if(writestodevnull==2){
117 a0d146ed 2005-07-12 devnull packetfree(p);
118 a0d146ed 2005-07-12 devnull return 0;
121 a0d146ed 2005-07-12 devnull if(queuewrites)
122 a0d146ed 2005-07-12 devnull return queuewrite(u, p, creator, ms);
124 a0d146ed 2005-07-12 devnull ok = writeqlump(u, p, creator, ms);
126 a0d146ed 2005-07-12 devnull putlump(u);
127 a0d146ed 2005-07-12 devnull return ok;
131 a0d146ed 2005-07-12 devnull writeqlump(Lump *u, Packet *p, int creator, uint ms)
133 a0d146ed 2005-07-12 devnull ZBlock *flat;
134 a0d146ed 2005-07-12 devnull Packet *old;
135 a0d146ed 2005-07-12 devnull IAddr ia;
138 7a400ee9 2007-09-25 rsc if(lookupscore(u->score, u->type, &ia) == 0){
139 27d28098 2007-04-21 devnull if(verifywrites == 0){
140 27d28098 2007-04-21 devnull /* assume the data is here! */
141 27d28098 2007-04-21 devnull packetfree(p);
142 27d28098 2007-04-21 devnull ms = msec() - ms;
143 27d28098 2007-04-21 devnull addstat2(StatRpcWriteOld, 1, StatRpcWriteOldTime, ms);
144 27d28098 2007-04-21 devnull return 0;
148 a0d146ed 2005-07-12 devnull * if the read fails,
149 a0d146ed 2005-07-12 devnull * assume it was corrupted data and store the block again
151 7a400ee9 2007-09-25 rsc old = readilump(u, &ia, u->score);
152 a0d146ed 2005-07-12 devnull if(old != nil){
154 a0d146ed 2005-07-12 devnull if(packetcmp(p, old) != 0){
155 28b49df3 2006-07-18 devnull uchar nscore[VtScoreSize];
157 28b49df3 2006-07-18 devnull packetsha1(old, nscore);
158 28b49df3 2006-07-18 devnull if(scorecmp(u->score, nscore) != 0)
159 28b49df3 2006-07-18 devnull seterr(EStrange, "readilump returned bad data %V not %V", nscore, u->score);
161 28b49df3 2006-07-18 devnull seterr(EStrange, "score collision %V", u->score);
162 a0d146ed 2005-07-12 devnull ok = -1;
164 a0d146ed 2005-07-12 devnull packetfree(p);
165 a0d146ed 2005-07-12 devnull packetfree(old);
167 a0d146ed 2005-07-12 devnull ms = msec() - ms;
168 a0d146ed 2005-07-12 devnull addstat2(StatRpcWriteOld, 1, StatRpcWriteOldTime, ms);
169 a0d146ed 2005-07-12 devnull return ok;
171 a0d146ed 2005-07-12 devnull logerr(EAdmin, "writelump: read %V failed, rewriting: %r\n", u->score);
174 a0d146ed 2005-07-12 devnull flat = packet2zblock(p, packetsize(p));
175 a0d146ed 2005-07-12 devnull ok = storeclump(mainindex, flat, u->score, u->type, creator, &ia);
176 a0d146ed 2005-07-12 devnull freezblock(flat);
177 a0d146ed 2005-07-12 devnull if(ok == 0)
178 a0d146ed 2005-07-12 devnull insertlump(u, p);
180 a0d146ed 2005-07-12 devnull packetfree(p);
182 28b49df3 2006-07-18 devnull if(syncwrites){
183 28b49df3 2006-07-18 devnull flushdcache();
184 28b49df3 2006-07-18 devnull flushicache();
185 28b49df3 2006-07-18 devnull flushdcache();
188 a0d146ed 2005-07-12 devnull ms = msec() - ms;
189 a0d146ed 2005-07-12 devnull addstat2(StatRpcWriteNew, 1, StatRpcWriteNewTime, ms);
190 a0d146ed 2005-07-12 devnull return ok;
193 a0d146ed 2005-07-12 devnull static Packet*
194 7a400ee9 2007-09-25 rsc readilump(Lump *u, IAddr *ia, u8int *score)
196 a0d146ed 2005-07-12 devnull Arena *arena;
197 a0d146ed 2005-07-12 devnull ZBlock *zb;
198 a0d146ed 2005-07-12 devnull Packet *p, *pp;
199 a0d146ed 2005-07-12 devnull Clump cl;
201 a0d146ed 2005-07-12 devnull u8int sc[VtScoreSize];
203 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump enter");
204 a0d146ed 2005-07-12 devnull arena = amapitoa(mainindex, ia->addr, &aa);
205 a0d146ed 2005-07-12 devnull if(arena == nil){
206 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump amapitoa failed");
207 a0d146ed 2005-07-12 devnull return nil;
210 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump loadclump");
211 a0d146ed 2005-07-12 devnull zb = loadclump(arena, aa, ia->blocks, &cl, sc, paranoid);
212 a0d146ed 2005-07-12 devnull if(zb == nil){
213 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump loadclump failed");
214 a0d146ed 2005-07-12 devnull return nil;
217 a0d146ed 2005-07-12 devnull if(ia->size != cl.info.uncsize){
218 a0d146ed 2005-07-12 devnull seterr(EInconsist, "index and clump size mismatch");
219 a0d146ed 2005-07-12 devnull freezblock(zb);
220 a0d146ed 2005-07-12 devnull return nil;
222 a0d146ed 2005-07-12 devnull if(ia->type != cl.info.type){
223 a0d146ed 2005-07-12 devnull seterr(EInconsist, "index and clump type mismatch");
224 a0d146ed 2005-07-12 devnull freezblock(zb);
225 a0d146ed 2005-07-12 devnull return nil;
227 a0d146ed 2005-07-12 devnull if(scorecmp(score, sc) != 0){
228 a0d146ed 2005-07-12 devnull seterr(ECrash, "score mismatch");
229 a0d146ed 2005-07-12 devnull freezblock(zb);
230 a0d146ed 2005-07-12 devnull return nil;
233 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump success");
234 a0d146ed 2005-07-12 devnull p = zblock2packet(zb, cl.info.uncsize);
235 a0d146ed 2005-07-12 devnull freezblock(zb);
236 a0d146ed 2005-07-12 devnull pp = packetdup(p, 0, packetsize(p));
237 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump insertlump");
238 a0d146ed 2005-07-12 devnull insertlump(u, pp);
239 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump exit");
240 a0d146ed 2005-07-12 devnull return p;