Blame


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"
4 a0d146ed 2005-07-12 devnull
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;
10 a0d146ed 2005-07-12 devnull
11 7a400ee9 2007-09-25 rsc static Packet *readilump(Lump *u, IAddr *ia, u8int *score);
12 a0d146ed 2005-07-12 devnull
13 27d28098 2007-04-21 devnull /*
14 27d28098 2007-04-21 devnull * Some of this logic is duplicated in hdisk.c
15 27d28098 2007-04-21 devnull */
16 a0d146ed 2005-07-12 devnull Packet*
17 a0d146ed 2005-07-12 devnull readlump(u8int *score, int type, u32int size, int *cached)
18 a0d146ed 2005-07-12 devnull {
19 a0d146ed 2005-07-12 devnull Lump *u;
20 a0d146ed 2005-07-12 devnull Packet *p;
21 a0d146ed 2005-07-12 devnull IAddr ia;
22 a0d146ed 2005-07-12 devnull u32int n;
23 a0d146ed 2005-07-12 devnull
24 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump enter");
25 a0d146ed 2005-07-12 devnull /*
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);
29 a0d146ed 2005-07-12 devnull */
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);
41 a0d146ed 2005-07-12 devnull
42 a0d146ed 2005-07-12 devnull return nil;
43 a0d146ed 2005-07-12 devnull }
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;
47 a0d146ed 2005-07-12 devnull }
48 a0d146ed 2005-07-12 devnull
49 a0d146ed 2005-07-12 devnull if(cached)
50 a0d146ed 2005-07-12 devnull *cached = 0;
51 a0d146ed 2005-07-12 devnull
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);
55 a0d146ed 2005-07-12 devnull
56 a0d146ed 2005-07-12 devnull putlump(u);
57 a0d146ed 2005-07-12 devnull return nil;
58 a0d146ed 2005-07-12 devnull }
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);
61 a0d146ed 2005-07-12 devnull
62 a0d146ed 2005-07-12 devnull putlump(u);
63 a0d146ed 2005-07-12 devnull return nil;
64 a0d146ed 2005-07-12 devnull }
65 a0d146ed 2005-07-12 devnull
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);
69 a0d146ed 2005-07-12 devnull
70 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump exit");
71 a0d146ed 2005-07-12 devnull return p;
72 a0d146ed 2005-07-12 devnull }
73 a0d146ed 2005-07-12 devnull
74 a0d146ed 2005-07-12 devnull /*
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.
77 a0d146ed 2005-07-12 devnull */
78 a0d146ed 2005-07-12 devnull int
79 a0d146ed 2005-07-12 devnull writelump(Packet *p, u8int *score, int type, u32int creator, uint ms)
80 a0d146ed 2005-07-12 devnull {
81 a0d146ed 2005-07-12 devnull Lump *u;
82 a0d146ed 2005-07-12 devnull int ok;
83 a0d146ed 2005-07-12 devnull
84 a0d146ed 2005-07-12 devnull /*
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);
88 a0d146ed 2005-07-12 devnull */
89 a0d146ed 2005-07-12 devnull
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;
94 a0d146ed 2005-07-12 devnull }
95 a0d146ed 2005-07-12 devnull
96 a0d146ed 2005-07-12 devnull u = lookuplump(score, type);
97 a0d146ed 2005-07-12 devnull if(u->data != nil){
98 a0d146ed 2005-07-12 devnull ok = 0;
99 a0d146ed 2005-07-12 devnull if(packetcmp(p, u->data) != 0){
100 28b49df3 2006-07-18 devnull uchar nscore[VtScoreSize];
101 28b49df3 2006-07-18 devnull
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);
107 28b49df3 2006-07-18 devnull else
108 28b49df3 2006-07-18 devnull seterr(EStrange, "score collision %V", score);
109 a0d146ed 2005-07-12 devnull ok = -1;
110 a0d146ed 2005-07-12 devnull }
111 a0d146ed 2005-07-12 devnull packetfree(p);
112 a0d146ed 2005-07-12 devnull putlump(u);
113 a0d146ed 2005-07-12 devnull return ok;
114 a0d146ed 2005-07-12 devnull }
115 a0d146ed 2005-07-12 devnull
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;
119 a0d146ed 2005-07-12 devnull }
120 a0d146ed 2005-07-12 devnull
121 a0d146ed 2005-07-12 devnull if(queuewrites)
122 a0d146ed 2005-07-12 devnull return queuewrite(u, p, creator, ms);
123 a0d146ed 2005-07-12 devnull
124 a0d146ed 2005-07-12 devnull ok = writeqlump(u, p, creator, ms);
125 a0d146ed 2005-07-12 devnull
126 a0d146ed 2005-07-12 devnull putlump(u);
127 a0d146ed 2005-07-12 devnull return ok;
128 a0d146ed 2005-07-12 devnull }
129 a0d146ed 2005-07-12 devnull
130 a0d146ed 2005-07-12 devnull int
131 a0d146ed 2005-07-12 devnull writeqlump(Lump *u, Packet *p, int creator, uint ms)
132 a0d146ed 2005-07-12 devnull {
133 a0d146ed 2005-07-12 devnull ZBlock *flat;
134 a0d146ed 2005-07-12 devnull Packet *old;
135 a0d146ed 2005-07-12 devnull IAddr ia;
136 a0d146ed 2005-07-12 devnull int ok;
137 a0d146ed 2005-07-12 devnull
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;
145 27d28098 2007-04-21 devnull }
146 a0d146ed 2005-07-12 devnull
147 a0d146ed 2005-07-12 devnull /*
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
150 a0d146ed 2005-07-12 devnull */
151 7a400ee9 2007-09-25 rsc old = readilump(u, &ia, u->score);
152 a0d146ed 2005-07-12 devnull if(old != nil){
153 a0d146ed 2005-07-12 devnull ok = 0;
154 a0d146ed 2005-07-12 devnull if(packetcmp(p, old) != 0){
155 28b49df3 2006-07-18 devnull uchar nscore[VtScoreSize];
156 28b49df3 2006-07-18 devnull
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);
160 28b49df3 2006-07-18 devnull else
161 28b49df3 2006-07-18 devnull seterr(EStrange, "score collision %V", u->score);
162 a0d146ed 2005-07-12 devnull ok = -1;
163 a0d146ed 2005-07-12 devnull }
164 a0d146ed 2005-07-12 devnull packetfree(p);
165 a0d146ed 2005-07-12 devnull packetfree(old);
166 a0d146ed 2005-07-12 devnull
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;
170 a0d146ed 2005-07-12 devnull }
171 a0d146ed 2005-07-12 devnull logerr(EAdmin, "writelump: read %V failed, rewriting: %r\n", u->score);
172 a0d146ed 2005-07-12 devnull }
173 a0d146ed 2005-07-12 devnull
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);
179 a0d146ed 2005-07-12 devnull else
180 a0d146ed 2005-07-12 devnull packetfree(p);
181 fa325e9b 2020-01-10 cross
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();
186 28b49df3 2006-07-18 devnull }
187 a0d146ed 2005-07-12 devnull
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;
191 a0d146ed 2005-07-12 devnull }
192 a0d146ed 2005-07-12 devnull
193 a0d146ed 2005-07-12 devnull static Packet*
194 7a400ee9 2007-09-25 rsc readilump(Lump *u, IAddr *ia, u8int *score)
195 a0d146ed 2005-07-12 devnull {
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;
200 7a400ee9 2007-09-25 rsc u64int aa;
201 a0d146ed 2005-07-12 devnull u8int sc[VtScoreSize];
202 a0d146ed 2005-07-12 devnull
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;
208 a0d146ed 2005-07-12 devnull }
209 a0d146ed 2005-07-12 devnull
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;
215 a0d146ed 2005-07-12 devnull }
216 a0d146ed 2005-07-12 devnull
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;
221 a0d146ed 2005-07-12 devnull }
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;
226 a0d146ed 2005-07-12 devnull }
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;
231 a0d146ed 2005-07-12 devnull }
232 a0d146ed 2005-07-12 devnull
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;
241 a0d146ed 2005-07-12 devnull }