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 %Z block %lld beyond end %lld\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 %Z block %lld beyond end %lld\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 %lld %lld\n", (Wideoff)b, (Wideoff)size); 180 return 1; 181 } 182 183 int 184 partwrite(Device *d, Off b, void *c) 185 { 186 Devsize base, size, l; 187 188 l = d->part.d->size / 100; 189 base = d->part.base * l; 190 size = d->part.size * l; 191 if(size == 0) 192 size = l*100; 193 if(b < size) 194 return devwrite(d->part.d, base+b, c); 195 print("partwrite %lld %lld\n", (Wideoff)b, (Wideoff)size); 196 return 1; 197 } 198 199 /* 200 * mirror device 201 */ 202 void 203 mirrinit(Device *d) 204 { 205 Device *x; 206 207 mcatinit(d); 208 for(x=d->cat.first; x; x=x->link) 209 x->size = devsize(x); 210 } 211 212 Devsize 213 mirrsize(Device *d) 214 { 215 Device *x; 216 int n; 217 Devsize m, min; 218 219 min = 0; 220 n = 0; 221 for(x=d->cat.first; x; x=x->link) { 222 m = x->size; 223 if(m == 0) { 224 m = devsize(x); 225 x->size = m; 226 } 227 if(min == 0 || m < min) 228 min = m; 229 n++; 230 } 231 return min; 232 } 233 234 int 235 mirrread(Device *d, Off b, void *c) 236 { 237 Device *x; 238 239 for(x=d->cat.first; x; x=x->link) { 240 if(x->size == 0) 241 x->size = devsize(x); 242 if (devread(x, b, c) == 0) /* okay? */ 243 return 0; 244 } 245 // DANGER WILL ROBINSON - all copies of this block were bad 246 print("mirrread %Z error at block %lld\n", d, (Wideoff)b); 247 return 1; 248 } 249 250 /* 251 * write the mirror(s) first so that a power outage, for example, will 252 * find the main device written only if the mirrors are too, thus 253 * checking the main device will also correctly check the mirror(s). 254 * 255 * devread and devwrite are synchronous; all buffering must be 256 * implemented at higher levels. 257 */ 258 static int 259 ewrite(Device *x, Off b, void *c) 260 { 261 if(x->size == 0) 262 x->size = devsize(x); 263 if (devwrite(x, b, c) != 0) { 264 print("mirrwrite %Z error at block %lld\n", x, (Wideoff)b); 265 return 1; 266 } 267 return 0; 268 } 269 270 static int 271 wrmirrs1st(Device *x, Off b, void *c) // write any mirrors of x, then x 272 { 273 int e; 274 275 if (x == nil) 276 return 0; 277 e = wrmirrs1st(x->link, b, c); 278 return e | ewrite(x, b, c); 279 } 280 281 int 282 mirrwrite(Device *d, Off b, void *c) 283 { 284 return wrmirrs1st(d->cat.first, b, c); 285 } 286