Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"all.h"
2
 
3
/*
4
 * multiple cat devices
5
 */
6
void
7
mcatinit(Device *d)
8
{
9
	Device *x, **list;
10
 
11
	d->cat.ndev = 0;
12
	for(x=d->cat.first; x; x=x->link) {
13
		devinit(x);
14
		d->cat.ndev++;
15
	}
16
 
17
	list = malloc(d->cat.ndev*sizeof(Device*));
18
	d->private = list;
19
	for(x=d->cat.first; x; x=x->link) {
20
		*list++ = x;
21
		x->size = devsize(x);
22
	}
23
}
24
 
25
Devsize
26
mcatsize(Device *d)
27
{
28
	Device *x;
29
	Devsize l, m;
30
 
31
	l = 0;
32
	for(x=d->cat.first; x; x=x->link) {
33
		m = x->size;
34
		if(m == 0) {
35
			m = devsize(x);
36
			x->size = m;
37
		}
38
		l += m;
39
	}
40
	return l;
41
}
42
 
43
int
44
mcatread(Device *d, Off b, void *c)
45
{
46
	Device *x;
47
	Devsize l, m;
48
 
49
	l = 0;
50
	for(x=d->cat.first; x; x=x->link) {
51
		m = x->size;
52
		if(m == 0) {
53
			m = devsize(x);
54
			x->size = m;
55
		}
56
		if(b < l+m)
57
			return devread(x, b-l, c);
58
		l += m;
59
	}
60
	print("mcatread past end: %Z block %lld, %lld beyond end\n",
61
		d, (Wideoff)b, (Wideoff)l);
62
	return 1;
63
}
64
 
65
int
66
mcatwrite(Device *d, Off b, void *c)
67
{
68
	Device *x;
69
	Devsize l, m;
70
 
71
	l = 0;
72
	for(x=d->cat.first; x; x=x->link) {
73
		m = x->size;
74
		if(m == 0) {
75
			m = devsize(x);
76
			x->size = m;
77
		}
78
		if(b < l+m)
79
			return devwrite(x, b-l, c);
80
		l += m;
81
	}
82
	print("mcatwrite past end: %Z block %lld, %lld beyond end\n",
83
		d, (Wideoff)b, (Wideoff)l);
84
	return 1;
85
}
86
 
87
/*
88
 * multiple interleave devices
89
 */
90
void
91
mlevinit(Device *d)
92
{
93
	Device *x;
94
 
95
	mcatinit(d);
96
	for(x=d->cat.first; x; x=x->link)
97
		x->size = devsize(x);
98
}
99
 
100
Devsize
101
mlevsize(Device *d)
102
{
103
	Device *x;
104
	int n;
105
	Devsize m, min;
106
 
107
	min = 0;
108
	n = 0;
109
	for(x=d->cat.first; x; x=x->link) {
110
		m = x->size;
111
		if(m == 0) {
112
			m = devsize(x);
113
			x->size = m;
114
		}
115
		if(min == 0 || m < min)
116
			min = m;
117
		n++;
118
	}
119
	return n * min;
120
}
121
 
122
int
123
mlevread(Device *d, Off b, void *c)
124
{
125
	int n;
126
	Device **list;
127
 
128
	n = d->cat.ndev;
129
	list = d->private;
130
	return devread(list[b%n], b/n, c);
131
}
132
 
133
int
134
mlevwrite(Device *d, Off b, void *c)
135
{
136
	int n;
137
	Device **list;
138
 
139
	n = d->cat.ndev;
140
	list = d->private;
141
	return devwrite(list[b%n], b/n, c);
142
}
143
 
144
/*
145
 * partition device
146
 */
147
void
148
partinit(Device *d)
149
{
150
 
151
	devinit(d->part.d);
152
	d->part.d->size = devsize(d->part.d);
153
}
154
 
155
Devsize
156
partsize(Device *d)
157
{
158
	Devsize size, l;
159
 
160
	l = d->part.d->size / 100;
161
	size = d->part.size * l;
162
	if(size == 0)
163
		size = l*100;
164
	return size;
165
}
166
 
167
int
168
partread(Device *d, Off b, void *c)
169
{
170
	Devsize base, size, l;
171
 
172
	l = d->part.d->size / 100;
173
	base = d->part.base * l;
174
	size = d->part.size * l;
175
	if(size == 0)
176
		size = l*100;
177
	if(b < size)
178
		return devread(d->part.d, base+b, c);
179
	print("partread past end: %Z blk %lld size %lld\n",
180
		d, (Wideoff)b, (Wideoff)size);
181
	return 1;
182
}
183
 
184
int
185
partwrite(Device *d, Off b, void *c)
186
{
187
	Devsize base, size, l;
188
 
189
	l = d->part.d->size / 100;
190
	base = d->part.base * l;
191
	size = d->part.size * l;
192
	if(size == 0)
193
		size = l*100;
194
	if(b < size)
195
		return devwrite(d->part.d, base+b, c);
196
	print("partwrite past end: %Z blk %lld size %lld\n",
197
		d, (Wideoff)b, (Wideoff)size);
198
	return 1;
199
}
200
 
201
/*
202
 * mirror device
203
 */
204
void
205
mirrinit(Device *d)
206
{
207
	Device *x;
208
 
209
	mcatinit(d);
210
	for(x=d->cat.first; x; x=x->link)
211
		x->size = devsize(x);
212
}
213
 
214
Devsize
215
mirrsize(Device *d)
216
{
217
	Device *x;
218
	int n;
219
	Devsize m, min;
220
 
221
	min = 0;
222
	n = 0;
223
	for(x=d->cat.first; x; x=x->link) {
224
		m = x->size;
225
		if(m == 0) {
226
			m = devsize(x);
227
			x->size = m;
228
		}
229
		if(min == 0 || m < min)
230
			min = m;
231
		n++;
232
	}
233
	return min;
234
}
235
 
236
int
237
mirrread(Device *d, Off b, void *c)
238
{
239
	Device *x;
240
 
241
	if (d->cat.first == nil) {
242
		print("mirrread: empty mirror %Z\n", d);
243
		return 1;
244
	}
245
	for(x=d->cat.first; x; x=x->link) {
246
		if(x->size == 0)
247
			x->size = devsize(x);
248
		if (devread(x, b, c) == 0)	/* okay? */
249
			return 0;
250
	}
251
	// DANGER WILL ROBINSON
252
	print("mirrread: all mirrors of %Z block %lld are bad\n",
253
		d, (Wideoff)b);
254
	return 1;
255
}
256
 
257
/*
258
 * write the mirror(s) first so that a power outage, for example, will
259
 * find the main device written only if the mirrors are too, thus
260
 * checking the main device will also correctly check the mirror(s).
261
 *
262
 * devread and devwrite are synchronous; all buffering must be
263
 * implemented at higher levels.
264
 */
265
static int
266
ewrite(Device *x, Off b, void *c)
267
{
268
	if(x->size == 0)
269
		x->size = devsize(x);
270
	if (devwrite(x, b, c) != 0) {
271
		print("mirrwrite: error at %Z block %lld\n", x, (Wideoff)b);
272
		return 1;
273
	}
274
	return 0;
275
}
276
 
277
static int
278
wrmirrs1st(Device *x, Off b, void *c)	// write any mirrors of x, then x
279
{
280
	int e;
281
 
282
	if (x == nil)
283
		return 0;
284
	e = wrmirrs1st(x->link, b, c);
285
	return e | ewrite(x, b, c);
286
}
287
 
288
int
289
mirrwrite(Device *d, Off b, void *c)
290
{
291
	if (d->cat.first == nil) {
292
		print("mirrwrite: empty mirror %Z\n", d);
293
		return 1;
294
	}
295
	return wrmirrs1st(d->cat.first, b, c);
296
}