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 #include "whack.h"
5 7a4ee46d 2003-11-23 devnull
6 7a4ee46d 2003-11-23 devnull /*
7 7a4ee46d 2003-11-23 devnull * writes a lump to disk
8 7a4ee46d 2003-11-23 devnull * returns the address in amap of the clump
9 7a4ee46d 2003-11-23 devnull */
10 7a4ee46d 2003-11-23 devnull int
11 7a4ee46d 2003-11-23 devnull storeclump(Index *ix, ZBlock *zb, u8int *sc, int type, u32int creator, IAddr *ia)
12 7a4ee46d 2003-11-23 devnull {
13 7a4ee46d 2003-11-23 devnull ZBlock *cb;
14 7a4ee46d 2003-11-23 devnull Clump cl;
15 7a4ee46d 2003-11-23 devnull u64int a;
16 7a4ee46d 2003-11-23 devnull u8int bh[VtScoreSize];
17 7a4ee46d 2003-11-23 devnull int size, dsize;
18 7a4ee46d 2003-11-23 devnull
19 7a4ee46d 2003-11-23 devnull if(0)print("storeclump %08x %p\n", mainindex->arenas[0], &cl);
20 7a4ee46d 2003-11-23 devnull size = zb->len;
21 7a4ee46d 2003-11-23 devnull if(size > VtMaxLumpSize){
22 7a4ee46d 2003-11-23 devnull seterr(EStrange, "lump too large");
23 7a4ee46d 2003-11-23 devnull return -1;
24 7a4ee46d 2003-11-23 devnull }
25 7a4ee46d 2003-11-23 devnull if(vttypevalid(type) < 0){
26 7a4ee46d 2003-11-23 devnull seterr(EStrange, "invalid lump type");
27 7a4ee46d 2003-11-23 devnull return -1;
28 7a4ee46d 2003-11-23 devnull }
29 7a4ee46d 2003-11-23 devnull
30 7a4ee46d 2003-11-23 devnull if(1){
31 7a4ee46d 2003-11-23 devnull scoremem(bh, zb->data, size);
32 7a4ee46d 2003-11-23 devnull if(scorecmp(sc, bh) != 0){
33 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "storing clump: corrupted; expected=%V got=%V, size=%d", sc, bh, size);
34 7a4ee46d 2003-11-23 devnull return -1;
35 7a4ee46d 2003-11-23 devnull }
36 7a4ee46d 2003-11-23 devnull }
37 7a4ee46d 2003-11-23 devnull
38 7a4ee46d 2003-11-23 devnull cb = alloczblock(size + ClumpSize, 0);
39 7a4ee46d 2003-11-23 devnull if(cb == nil)
40 7a4ee46d 2003-11-23 devnull return -1;
41 7a4ee46d 2003-11-23 devnull
42 7a4ee46d 2003-11-23 devnull cl.info.type = type;
43 7a4ee46d 2003-11-23 devnull cl.info.uncsize = size;
44 7a4ee46d 2003-11-23 devnull cl.creator = creator;
45 7a4ee46d 2003-11-23 devnull cl.time = now();
46 7a4ee46d 2003-11-23 devnull scorecp(cl.info.score, sc);
47 7a4ee46d 2003-11-23 devnull
48 7a4ee46d 2003-11-23 devnull if(0)print("whackblock %08x %p\n", mainindex->arenas[0], &cl);
49 333c1dcc 2004-03-13 devnull dsize=0; // dsize = whackblock(&cb->data[ClumpSize], zb->data, size);
50 7a4ee46d 2003-11-23 devnull if(0)print("whackedblock %08x %p\n", mainindex->arenas[0], &cl);
51 7a4ee46d 2003-11-23 devnull if(dsize > 0 && dsize < size){
52 7a4ee46d 2003-11-23 devnull cl.encoding = ClumpECompress;
53 7a4ee46d 2003-11-23 devnull }else{
54 7a4ee46d 2003-11-23 devnull cl.encoding = ClumpENone;
55 7a4ee46d 2003-11-23 devnull dsize = size;
56 7a4ee46d 2003-11-23 devnull memmove(&cb->data[ClumpSize], zb->data, size);
57 7a4ee46d 2003-11-23 devnull }
58 7a4ee46d 2003-11-23 devnull cl.info.size = dsize;
59 7a4ee46d 2003-11-23 devnull
60 7a4ee46d 2003-11-23 devnull a = writeiclump(ix, &cl, cb->data);
61 7a4ee46d 2003-11-23 devnull
62 7a4ee46d 2003-11-23 devnull freezblock(cb);
63 9ffbb5ad 2004-03-12 devnull if(a == TWID64)
64 7a4ee46d 2003-11-23 devnull return -1;
65 7a4ee46d 2003-11-23 devnull
66 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
67 7a4ee46d 2003-11-23 devnull stats.clumpwrites++;
68 7a4ee46d 2003-11-23 devnull stats.clumpbwrites += size;
69 7a4ee46d 2003-11-23 devnull stats.clumpbcomp += dsize;
70 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
71 7a4ee46d 2003-11-23 devnull
72 7a4ee46d 2003-11-23 devnull ia->addr = a;
73 7a4ee46d 2003-11-23 devnull ia->type = type;
74 7a4ee46d 2003-11-23 devnull ia->size = size;
75 7a4ee46d 2003-11-23 devnull ia->blocks = (dsize + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog;
76 7a4ee46d 2003-11-23 devnull
77 7a4ee46d 2003-11-23 devnull return 0;
78 7a4ee46d 2003-11-23 devnull }
79 7a4ee46d 2003-11-23 devnull
80 7a4ee46d 2003-11-23 devnull u32int
81 7a4ee46d 2003-11-23 devnull clumpmagic(Arena *arena, u64int aa)
82 7a4ee46d 2003-11-23 devnull {
83 7a4ee46d 2003-11-23 devnull u8int buf[U32Size];
84 7a4ee46d 2003-11-23 devnull
85 7a4ee46d 2003-11-23 devnull if(readarena(arena, aa, buf, U32Size) < 0)
86 7a4ee46d 2003-11-23 devnull return TWID32;
87 7a4ee46d 2003-11-23 devnull return unpackmagic(buf);
88 7a4ee46d 2003-11-23 devnull }
89 7a4ee46d 2003-11-23 devnull
90 7a4ee46d 2003-11-23 devnull /*
91 7a4ee46d 2003-11-23 devnull * fetch a block based at addr.
92 7a4ee46d 2003-11-23 devnull * score is filled in with the block's score.
93 7a4ee46d 2003-11-23 devnull * blocks is roughly the length of the clump on disk;
94 7a4ee46d 2003-11-23 devnull * if zero, the length is unknown.
95 7a4ee46d 2003-11-23 devnull */
96 7a4ee46d 2003-11-23 devnull ZBlock*
97 7a4ee46d 2003-11-23 devnull loadclump(Arena *arena, u64int aa, int blocks, Clump *cl, u8int *score, int verify)
98 7a4ee46d 2003-11-23 devnull {
99 7a4ee46d 2003-11-23 devnull Unwhack uw;
100 7a4ee46d 2003-11-23 devnull ZBlock *zb, *cb;
101 7a4ee46d 2003-11-23 devnull u8int bh[VtScoreSize], *buf;
102 7a4ee46d 2003-11-23 devnull u32int n;
103 7a4ee46d 2003-11-23 devnull int nunc;
104 7a4ee46d 2003-11-23 devnull
105 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
106 7a4ee46d 2003-11-23 devnull stats.clumpreads++;
107 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
108 7a4ee46d 2003-11-23 devnull
109 7a4ee46d 2003-11-23 devnull if(blocks <= 0)
110 7a4ee46d 2003-11-23 devnull blocks = 1;
111 7a4ee46d 2003-11-23 devnull
112 7a4ee46d 2003-11-23 devnull cb = alloczblock(blocks << ABlockLog, 0);
113 7a4ee46d 2003-11-23 devnull if(cb == nil)
114 7a4ee46d 2003-11-23 devnull return nil;
115 7a4ee46d 2003-11-23 devnull n = readarena(arena, aa, cb->data, blocks << ABlockLog);
116 7a4ee46d 2003-11-23 devnull if(n < ClumpSize){
117 7a4ee46d 2003-11-23 devnull if(n != 0)
118 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "loadclump read less than a header");
119 7a4ee46d 2003-11-23 devnull freezblock(cb);
120 7a4ee46d 2003-11-23 devnull return nil;
121 7a4ee46d 2003-11-23 devnull }
122 7a4ee46d 2003-11-23 devnull if(unpackclump(cl, cb->data) < 0){
123 7a4ee46d 2003-11-23 devnull freezblock(cb);
124 7a4ee46d 2003-11-23 devnull return nil;
125 7a4ee46d 2003-11-23 devnull }
126 7a4ee46d 2003-11-23 devnull n -= ClumpSize;
127 7a4ee46d 2003-11-23 devnull if(n < cl->info.size){
128 7a4ee46d 2003-11-23 devnull freezblock(cb);
129 7a4ee46d 2003-11-23 devnull n = cl->info.size;
130 7a4ee46d 2003-11-23 devnull cb = alloczblock(n, 0);
131 7a4ee46d 2003-11-23 devnull if(cb == nil)
132 7a4ee46d 2003-11-23 devnull return nil;
133 7a4ee46d 2003-11-23 devnull if(readarena(arena, aa + ClumpSize, cb->data, n) != n){
134 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "loadclump read too little data");
135 7a4ee46d 2003-11-23 devnull freezblock(cb);
136 7a4ee46d 2003-11-23 devnull return nil;
137 7a4ee46d 2003-11-23 devnull }
138 7a4ee46d 2003-11-23 devnull buf = cb->data;
139 7a4ee46d 2003-11-23 devnull }else
140 7a4ee46d 2003-11-23 devnull buf = cb->data + ClumpSize;
141 7a4ee46d 2003-11-23 devnull
142 7a4ee46d 2003-11-23 devnull scorecp(score, cl->info.score);
143 7a4ee46d 2003-11-23 devnull
144 7a4ee46d 2003-11-23 devnull zb = alloczblock(cl->info.uncsize, 0);
145 7a4ee46d 2003-11-23 devnull if(zb == nil){
146 7a4ee46d 2003-11-23 devnull freezblock(cb);
147 7a4ee46d 2003-11-23 devnull return nil;
148 7a4ee46d 2003-11-23 devnull }
149 7a4ee46d 2003-11-23 devnull switch(cl->encoding){
150 7a4ee46d 2003-11-23 devnull case ClumpECompress:
151 7a4ee46d 2003-11-23 devnull unwhackinit(&uw);
152 7a4ee46d 2003-11-23 devnull nunc = unwhack(&uw, zb->data, cl->info.uncsize, buf, cl->info.size);
153 7a4ee46d 2003-11-23 devnull if(nunc != cl->info.uncsize){
154 7a4ee46d 2003-11-23 devnull if(nunc < 0)
155 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "decompression failed: %s", uw.err);
156 7a4ee46d 2003-11-23 devnull else
157 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "decompression gave partial block: %d/%d\n", nunc, cl->info.uncsize);
158 7a4ee46d 2003-11-23 devnull freezblock(cb);
159 7a4ee46d 2003-11-23 devnull freezblock(zb);
160 7a4ee46d 2003-11-23 devnull return nil;
161 7a4ee46d 2003-11-23 devnull }
162 7a4ee46d 2003-11-23 devnull break;
163 7a4ee46d 2003-11-23 devnull case ClumpENone:
164 7a4ee46d 2003-11-23 devnull if(cl->info.size != cl->info.uncsize){
165 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "loading clump: bad uncompressed size for uncompressed block");
166 7a4ee46d 2003-11-23 devnull freezblock(cb);
167 7a4ee46d 2003-11-23 devnull freezblock(zb);
168 7a4ee46d 2003-11-23 devnull return nil;
169 7a4ee46d 2003-11-23 devnull }
170 7a4ee46d 2003-11-23 devnull memmove(zb->data, buf, cl->info.uncsize);
171 7a4ee46d 2003-11-23 devnull break;
172 7a4ee46d 2003-11-23 devnull default:
173 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "unknown encoding in loadlump");
174 7a4ee46d 2003-11-23 devnull freezblock(cb);
175 7a4ee46d 2003-11-23 devnull freezblock(zb);
176 7a4ee46d 2003-11-23 devnull return nil;
177 7a4ee46d 2003-11-23 devnull }
178 7a4ee46d 2003-11-23 devnull freezblock(cb);
179 7a4ee46d 2003-11-23 devnull
180 7a4ee46d 2003-11-23 devnull if(verify){
181 7a4ee46d 2003-11-23 devnull scoremem(bh, zb->data, cl->info.uncsize);
182 7a4ee46d 2003-11-23 devnull if(scorecmp(cl->info.score, bh) != 0){
183 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "loading clump: corrupted; expected=%V got=%V", cl->info.score, bh);
184 7a4ee46d 2003-11-23 devnull freezblock(zb);
185 7a4ee46d 2003-11-23 devnull return nil;
186 7a4ee46d 2003-11-23 devnull }
187 7a4ee46d 2003-11-23 devnull if(vttypevalid(cl->info.type) < 0){
188 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "loading lump: invalid lump type %d", cl->info.type);
189 7a4ee46d 2003-11-23 devnull freezblock(zb);
190 7a4ee46d 2003-11-23 devnull return nil;
191 7a4ee46d 2003-11-23 devnull }
192 7a4ee46d 2003-11-23 devnull }
193 7a4ee46d 2003-11-23 devnull
194 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
195 7a4ee46d 2003-11-23 devnull stats.clumpbreads += cl->info.size;
196 7a4ee46d 2003-11-23 devnull stats.clumpbuncomp += cl->info.uncsize;
197 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
198 7a4ee46d 2003-11-23 devnull
199 7a4ee46d 2003-11-23 devnull return zb;
200 7a4ee46d 2003-11-23 devnull }