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 } 297