1 #include "all.h"
2
3 /*
4 * multiple cat devices
5 */
6 void
mcatinit(Device * d)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
mcatsize(Device * d)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
mcatread(Device * d,Off b,void * c)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
mcatwrite(Device * d,Off b,void * c)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
mlevinit(Device * d)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
mlevsize(Device * d)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
mlevread(Device * d,Off b,void * c)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
mlevwrite(Device * d,Off b,void * c)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
partinit(Device * d)148 partinit(Device *d)
149 {
150
151 devinit(d->part.d);
152 d->part.d->size = devsize(d->part.d);
153 }
154
155 Devsize
partsize(Device * d)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
partread(Device * d,Off b,void * c)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
partwrite(Device * d,Off b,void * c)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
mirrinit(Device * d)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
mirrsize(Device * d)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
mirrread(Device * d,Off b,void * c)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
ewrite(Device * x,Off b,void * c)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
wrmirrs1st(Device * x,Off b,void * c)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
mirrwrite(Device * d,Off b,void * c)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 }
297