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 a0d146ed 2005-07-12 devnull int queuewrites = 0;
6 a0d146ed 2005-07-12 devnull int writestodevnull = 0;
7 a0d146ed 2005-07-12 devnull
8 a0d146ed 2005-07-12 devnull static Packet *readilump(Lump *u, IAddr *ia, u8int *score, int rac);
9 a0d146ed 2005-07-12 devnull
10 a0d146ed 2005-07-12 devnull Packet*
11 a0d146ed 2005-07-12 devnull readlump(u8int *score, int type, u32int size, int *cached)
12 a0d146ed 2005-07-12 devnull {
13 a0d146ed 2005-07-12 devnull Lump *u;
14 a0d146ed 2005-07-12 devnull Packet *p;
15 a0d146ed 2005-07-12 devnull IAddr ia;
16 a0d146ed 2005-07-12 devnull u32int n;
17 a0d146ed 2005-07-12 devnull int rac;
18 a0d146ed 2005-07-12 devnull
19 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump enter");
20 a0d146ed 2005-07-12 devnull /*
21 a0d146ed 2005-07-12 devnull qlock(&stats.lock);
22 a0d146ed 2005-07-12 devnull stats.lumpreads++;
23 a0d146ed 2005-07-12 devnull qunlock(&stats.lock);
24 a0d146ed 2005-07-12 devnull */
25 a0d146ed 2005-07-12 devnull if(scorecmp(score, zeroscore) == 0)
26 a0d146ed 2005-07-12 devnull return packetalloc();
27 a0d146ed 2005-07-12 devnull u = lookuplump(score, type);
28 a0d146ed 2005-07-12 devnull if(u->data != nil){
29 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump lookuplump hit");
30 a0d146ed 2005-07-12 devnull if(cached)
31 a0d146ed 2005-07-12 devnull *cached = 1;
32 a0d146ed 2005-07-12 devnull n = packetsize(u->data);
33 a0d146ed 2005-07-12 devnull if(n > size){
34 a0d146ed 2005-07-12 devnull seterr(EOk, "read too small: asked for %d need at least %d", size, n);
35 a0d146ed 2005-07-12 devnull putlump(u);
36 a0d146ed 2005-07-12 devnull
37 a0d146ed 2005-07-12 devnull return nil;
38 a0d146ed 2005-07-12 devnull }
39 a0d146ed 2005-07-12 devnull p = packetdup(u->data, 0, n);
40 a0d146ed 2005-07-12 devnull putlump(u);
41 a0d146ed 2005-07-12 devnull return p;
42 a0d146ed 2005-07-12 devnull }
43 a0d146ed 2005-07-12 devnull
44 a0d146ed 2005-07-12 devnull if(cached)
45 a0d146ed 2005-07-12 devnull *cached = 0;
46 a0d146ed 2005-07-12 devnull
47 a0d146ed 2005-07-12 devnull if(lookupscore(score, type, &ia, &rac) < 0){
48 a0d146ed 2005-07-12 devnull //ZZZ place to check for someone trying to guess scores
49 a0d146ed 2005-07-12 devnull seterr(EOk, "no block with score %V/%d exists", score, type);
50 a0d146ed 2005-07-12 devnull
51 a0d146ed 2005-07-12 devnull putlump(u);
52 a0d146ed 2005-07-12 devnull return nil;
53 a0d146ed 2005-07-12 devnull }
54 a0d146ed 2005-07-12 devnull if(ia.size > size){
55 a0d146ed 2005-07-12 devnull seterr(EOk, "read too small 1: asked for %d need at least %d", size, ia.size);
56 a0d146ed 2005-07-12 devnull
57 a0d146ed 2005-07-12 devnull putlump(u);
58 a0d146ed 2005-07-12 devnull return nil;
59 a0d146ed 2005-07-12 devnull }
60 a0d146ed 2005-07-12 devnull
61 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump readilump");
62 a0d146ed 2005-07-12 devnull p = readilump(u, &ia, score, rac);
63 a0d146ed 2005-07-12 devnull putlump(u);
64 a0d146ed 2005-07-12 devnull
65 a0d146ed 2005-07-12 devnull trace(TraceLump, "readlump exit");
66 a0d146ed 2005-07-12 devnull return p;
67 a0d146ed 2005-07-12 devnull }
68 a0d146ed 2005-07-12 devnull
69 a0d146ed 2005-07-12 devnull /*
70 a0d146ed 2005-07-12 devnull * save away a lump, and return it's score.
71 a0d146ed 2005-07-12 devnull * doesn't store duplicates, but checks that the data is really the same.
72 a0d146ed 2005-07-12 devnull */
73 a0d146ed 2005-07-12 devnull int
74 a0d146ed 2005-07-12 devnull writelump(Packet *p, u8int *score, int type, u32int creator, uint ms)
75 a0d146ed 2005-07-12 devnull {
76 a0d146ed 2005-07-12 devnull Lump *u;
77 a0d146ed 2005-07-12 devnull int ok;
78 a0d146ed 2005-07-12 devnull
79 a0d146ed 2005-07-12 devnull /*
80 a0d146ed 2005-07-12 devnull qlock(&stats.lock);
81 a0d146ed 2005-07-12 devnull stats.lumpwrites++;
82 a0d146ed 2005-07-12 devnull qunlock(&stats.lock);
83 a0d146ed 2005-07-12 devnull */
84 a0d146ed 2005-07-12 devnull
85 a0d146ed 2005-07-12 devnull packetsha1(p, score);
86 a0d146ed 2005-07-12 devnull if(packetsize(p) == 0 || writestodevnull==1){
87 a0d146ed 2005-07-12 devnull packetfree(p);
88 a0d146ed 2005-07-12 devnull return 0;
89 a0d146ed 2005-07-12 devnull }
90 a0d146ed 2005-07-12 devnull
91 a0d146ed 2005-07-12 devnull u = lookuplump(score, type);
92 a0d146ed 2005-07-12 devnull if(u->data != nil){
93 a0d146ed 2005-07-12 devnull ok = 0;
94 a0d146ed 2005-07-12 devnull if(packetcmp(p, u->data) != 0){
95 a0d146ed 2005-07-12 devnull seterr(EStrange, "score collision");
96 a0d146ed 2005-07-12 devnull ok = -1;
97 a0d146ed 2005-07-12 devnull }
98 a0d146ed 2005-07-12 devnull packetfree(p);
99 a0d146ed 2005-07-12 devnull putlump(u);
100 a0d146ed 2005-07-12 devnull return ok;
101 a0d146ed 2005-07-12 devnull }
102 a0d146ed 2005-07-12 devnull
103 a0d146ed 2005-07-12 devnull if(writestodevnull==2){
104 a0d146ed 2005-07-12 devnull packetfree(p);
105 a0d146ed 2005-07-12 devnull return 0;
106 a0d146ed 2005-07-12 devnull }
107 a0d146ed 2005-07-12 devnull
108 a0d146ed 2005-07-12 devnull if(queuewrites)
109 a0d146ed 2005-07-12 devnull return queuewrite(u, p, creator, ms);
110 a0d146ed 2005-07-12 devnull
111 a0d146ed 2005-07-12 devnull ok = writeqlump(u, p, creator, ms);
112 a0d146ed 2005-07-12 devnull
113 a0d146ed 2005-07-12 devnull putlump(u);
114 a0d146ed 2005-07-12 devnull return ok;
115 a0d146ed 2005-07-12 devnull }
116 a0d146ed 2005-07-12 devnull
117 a0d146ed 2005-07-12 devnull int
118 a0d146ed 2005-07-12 devnull writeqlump(Lump *u, Packet *p, int creator, uint ms)
119 a0d146ed 2005-07-12 devnull {
120 a0d146ed 2005-07-12 devnull ZBlock *flat;
121 a0d146ed 2005-07-12 devnull Packet *old;
122 a0d146ed 2005-07-12 devnull IAddr ia;
123 a0d146ed 2005-07-12 devnull int ok;
124 a0d146ed 2005-07-12 devnull int rac;
125 a0d146ed 2005-07-12 devnull
126 a0d146ed 2005-07-12 devnull if(lookupscore(u->score, u->type, &ia, &rac) == 0){
127 a0d146ed 2005-07-12 devnull /* assume the data is here! XXX */
128 a0d146ed 2005-07-12 devnull packetfree(p);
129 a0d146ed 2005-07-12 devnull ms = msec() - ms;
130 a0d146ed 2005-07-12 devnull addstat2(StatRpcWriteOld, 1, StatRpcWriteOldTime, ms);
131 a0d146ed 2005-07-12 devnull return 0;
132 a0d146ed 2005-07-12 devnull
133 a0d146ed 2005-07-12 devnull /*
134 a0d146ed 2005-07-12 devnull * if the read fails,
135 a0d146ed 2005-07-12 devnull * assume it was corrupted data and store the block again
136 a0d146ed 2005-07-12 devnull */
137 a0d146ed 2005-07-12 devnull old = readilump(u, &ia, u->score, rac);
138 a0d146ed 2005-07-12 devnull if(old != nil){
139 a0d146ed 2005-07-12 devnull ok = 0;
140 a0d146ed 2005-07-12 devnull if(packetcmp(p, old) != 0){
141 a0d146ed 2005-07-12 devnull seterr(EStrange, "score collision");
142 a0d146ed 2005-07-12 devnull ok = -1;
143 a0d146ed 2005-07-12 devnull }
144 a0d146ed 2005-07-12 devnull packetfree(p);
145 a0d146ed 2005-07-12 devnull packetfree(old);
146 a0d146ed 2005-07-12 devnull
147 a0d146ed 2005-07-12 devnull ms = msec() - ms;
148 a0d146ed 2005-07-12 devnull addstat2(StatRpcWriteOld, 1, StatRpcWriteOldTime, ms);
149 a0d146ed 2005-07-12 devnull return ok;
150 a0d146ed 2005-07-12 devnull }
151 a0d146ed 2005-07-12 devnull logerr(EAdmin, "writelump: read %V failed, rewriting: %r\n", u->score);
152 a0d146ed 2005-07-12 devnull }
153 a0d146ed 2005-07-12 devnull
154 a0d146ed 2005-07-12 devnull flat = packet2zblock(p, packetsize(p));
155 a0d146ed 2005-07-12 devnull ok = storeclump(mainindex, flat, u->score, u->type, creator, &ia);
156 a0d146ed 2005-07-12 devnull freezblock(flat);
157 a0d146ed 2005-07-12 devnull if(ok == 0)
158 a0d146ed 2005-07-12 devnull ok = insertscore(u->score, &ia, 1);
159 a0d146ed 2005-07-12 devnull if(ok == 0)
160 a0d146ed 2005-07-12 devnull insertlump(u, p);
161 a0d146ed 2005-07-12 devnull else
162 a0d146ed 2005-07-12 devnull packetfree(p);
163 a0d146ed 2005-07-12 devnull
164 a0d146ed 2005-07-12 devnull ms = msec() - ms;
165 a0d146ed 2005-07-12 devnull addstat2(StatRpcWriteNew, 1, StatRpcWriteNewTime, ms);
166 a0d146ed 2005-07-12 devnull return ok;
167 a0d146ed 2005-07-12 devnull }
168 a0d146ed 2005-07-12 devnull
169 a0d146ed 2005-07-12 devnull static void
170 a0d146ed 2005-07-12 devnull lreadahead(u64int a, Arena *arena, u64int aa, int n)
171 a0d146ed 2005-07-12 devnull {
172 a0d146ed 2005-07-12 devnull u8int buf[ClumpSize];
173 a0d146ed 2005-07-12 devnull Clump cl;
174 a0d146ed 2005-07-12 devnull IAddr ia;
175 a0d146ed 2005-07-12 devnull
176 a0d146ed 2005-07-12 devnull while(n > 0) {
177 a0d146ed 2005-07-12 devnull if (aa >= arena->memstats.used)
178 a0d146ed 2005-07-12 devnull break;
179 a0d146ed 2005-07-12 devnull if(readarena(arena, aa, buf, ClumpSize) < ClumpSize)
180 a0d146ed 2005-07-12 devnull break;
181 a0d146ed 2005-07-12 devnull if(unpackclump(&cl, buf, arena->clumpmagic) < 0)
182 a0d146ed 2005-07-12 devnull break;
183 a0d146ed 2005-07-12 devnull ia.addr = a;
184 a0d146ed 2005-07-12 devnull ia.type = cl.info.type;
185 a0d146ed 2005-07-12 devnull ia.size = cl.info.uncsize;
186 a0d146ed 2005-07-12 devnull ia.blocks = (cl.info.size + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog;
187 a0d146ed 2005-07-12 devnull insertscore(cl.info.score, &ia, 0);
188 a0d146ed 2005-07-12 devnull a += ClumpSize + cl.info.size;
189 a0d146ed 2005-07-12 devnull aa += ClumpSize + cl.info.size;
190 a0d146ed 2005-07-12 devnull n--;
191 a0d146ed 2005-07-12 devnull }
192 a0d146ed 2005-07-12 devnull }
193 a0d146ed 2005-07-12 devnull
194 a0d146ed 2005-07-12 devnull static Packet*
195 a0d146ed 2005-07-12 devnull readilump(Lump *u, IAddr *ia, u8int *score, int rac)
196 a0d146ed 2005-07-12 devnull {
197 a0d146ed 2005-07-12 devnull Arena *arena;
198 a0d146ed 2005-07-12 devnull ZBlock *zb;
199 a0d146ed 2005-07-12 devnull Packet *p, *pp;
200 a0d146ed 2005-07-12 devnull Clump cl;
201 a0d146ed 2005-07-12 devnull u64int a, aa;
202 a0d146ed 2005-07-12 devnull u8int sc[VtScoreSize];
203 a0d146ed 2005-07-12 devnull
204 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump enter");
205 a0d146ed 2005-07-12 devnull arena = amapitoa(mainindex, ia->addr, &aa);
206 a0d146ed 2005-07-12 devnull if(arena == nil){
207 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump amapitoa failed");
208 a0d146ed 2005-07-12 devnull return nil;
209 a0d146ed 2005-07-12 devnull }
210 a0d146ed 2005-07-12 devnull
211 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump loadclump");
212 a0d146ed 2005-07-12 devnull zb = loadclump(arena, aa, ia->blocks, &cl, sc, paranoid);
213 a0d146ed 2005-07-12 devnull if(zb == nil){
214 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump loadclump failed");
215 a0d146ed 2005-07-12 devnull return nil;
216 a0d146ed 2005-07-12 devnull }
217 a0d146ed 2005-07-12 devnull
218 a0d146ed 2005-07-12 devnull if(ia->size != cl.info.uncsize){
219 a0d146ed 2005-07-12 devnull seterr(EInconsist, "index and clump size mismatch");
220 a0d146ed 2005-07-12 devnull freezblock(zb);
221 a0d146ed 2005-07-12 devnull return nil;
222 a0d146ed 2005-07-12 devnull }
223 a0d146ed 2005-07-12 devnull if(ia->type != cl.info.type){
224 a0d146ed 2005-07-12 devnull seterr(EInconsist, "index and clump type mismatch");
225 a0d146ed 2005-07-12 devnull freezblock(zb);
226 a0d146ed 2005-07-12 devnull return nil;
227 a0d146ed 2005-07-12 devnull }
228 a0d146ed 2005-07-12 devnull if(scorecmp(score, sc) != 0){
229 a0d146ed 2005-07-12 devnull seterr(ECrash, "score mismatch");
230 a0d146ed 2005-07-12 devnull freezblock(zb);
231 a0d146ed 2005-07-12 devnull return nil;
232 a0d146ed 2005-07-12 devnull }
233 a0d146ed 2005-07-12 devnull
234 a0d146ed 2005-07-12 devnull if(rac == 0) {
235 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump readahead");
236 a0d146ed 2005-07-12 devnull a = ia->addr + ClumpSize + cl.info.size;
237 a0d146ed 2005-07-12 devnull aa += ClumpSize + cl.info.size;
238 a0d146ed 2005-07-12 devnull lreadahead(a, arena, aa, 20);
239 a0d146ed 2005-07-12 devnull }
240 a0d146ed 2005-07-12 devnull
241 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump success");
242 a0d146ed 2005-07-12 devnull p = zblock2packet(zb, cl.info.uncsize);
243 a0d146ed 2005-07-12 devnull freezblock(zb);
244 a0d146ed 2005-07-12 devnull pp = packetdup(p, 0, packetsize(p));
245 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump insertlump");
246 a0d146ed 2005-07-12 devnull insertlump(u, pp);
247 a0d146ed 2005-07-12 devnull trace(TraceLump, "readilump exit");
248 a0d146ed 2005-07-12 devnull return p;
249 a0d146ed 2005-07-12 devnull }