Blame


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