Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/venti/srv/lump.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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