#include "all.h" voidmwormream(Device *d, int){ Device *l; for(l=d->cat.first; l; l=l->link) devream(l, 0);} /* * multiple cat devices */voidmcatinit(Device *d){ Device *x, **list; d->cat.ndev = 0; for(x=d->cat.first; x; x=x->link) { devinit(x); d->cat.ndev++; } list = ialloc(d->cat.ndev*sizeof(Device*), 0); d->private = list; for(x=d->cat.first; x; x=x->link) { *list++ = x; x->size = devsize(x); }} Devsizemcatsize(Device *d){ Device *x; Devsize l, m; l = 0; for(x=d->cat.first; x; x=x->link) { m = x->size; if(m == 0) { m = devsize(x); x->size = m; } l += m; } return l;} intmcatread(Device *d, Off b, void *c){ Device *x; Devsize l, m; l = 0; for(x=d->cat.first; x; x=x->link) { m = x->size; if(m == 0) { m = devsize(x); x->size = m; } if(b < l+m) return devread(x, b-l, c); l += m; } print("mcatread %lld %lld\n", (Wideoff)b, (Wideoff)l); return 1;} intmcatwrite(Device *d, Off b, void *c){ Device *x; Devsize l, m; l = 0; for(x=d->cat.first; x; x=x->link) { m = x->size; if(m == 0) { m = devsize(x); x->size = m; } if(b < l+m) return devwrite(x, b-l, c); l += m; } print("mcatwrite %lld %lld\n", (Wideoff)b, (Wideoff)l); return 1;} /* * multiple interleave devices */voidmlevinit(Device *d){ Device *x; mcatinit(d); for(x=d->cat.first; x; x=x->link) x->size = devsize(x);} Devsizemlevsize(Device *d){ Device *x; int n; Devsize m, min; min = 0; n = 0; for(x=d->cat.first; x; x=x->link) { m = x->size; if(m == 0) { m = devsize(x); x->size = m; } if(min == 0 || m < min) min = m; n++; } return n * min;} intmlevread(Device *d, Off b, void *c){ int n; Device **list; n = d->cat.ndev; list = d->private; return devread(list[b%n], b/n, c);} intmlevwrite(Device *d, Off b, void *c){ int n; Device **list; n = d->cat.ndev; list = d->private; return devwrite(list[b%n], b/n, c);} /* * mirror device */voidmirrinit(Device *d){ Device *x; mcatinit(d); for(x=d->cat.first; x; x=x->link) x->size = devsize(x);} Devsizemirrsize(Device *d){ Device *x; int n; Devsize m, min; min = 0; n = 0; for(x=d->cat.first; x; x=x->link) { m = x->size; if(m == 0) { m = devsize(x); x->size = m; } if(min == 0 || m < min) min = m; n++; } return min;} intmirrread(Device *d, Off b, void *c){ Device *x; for(x=d->cat.first; x; x=x->link) { if(x->size == 0) x->size = devsize(x); if (devread(x, b, c) == 0) /* okay? */ return 0; } // DANGER WILL ROBINSON - all copies of this block were bad print("mirrread %Z error at block %lld\n", d, (Wideoff)b); return 1;} /* * write the mirror(s) first so that a power outage, for example, will * find the main device written only if the mirrors are too, thus * checking the main device will also correctly check the mirror(s). * * devread and devwrite are synchronous; all buffering must be * implemented at higher levels. */static intewrite(Device *x, Off b, void *c){ if(x->size == 0) x->size = devsize(x); if (devwrite(x, b, c) != 0) { print("mirrwrite %Z error at block %lld\n", x, (Wideoff)b); return 1; } return 0;} static intwrmirrs1st(Device *x, Off b, void *c) // write any mirrors of x, then x{ int e; if (x == nil) return 0; e = wrmirrs1st(x->link, b, c); return e | ewrite(x, b, c);} intmirrwrite(Device *d, Off b, void *c){ return wrmirrs1st(d->cat.first, b, c);}
#include "all.h"
void
mwormream(Device *d, int)
{
Device *l;
for(l=d->cat.first; l; l=l->link)
devream(l, 0);
}
/*
* multiple cat devices
*/
void
mcatinit(Device *d)
{
Device *x, **list;
d->cat.ndev = 0;
for(x=d->cat.first; x; x=x->link) {
devinit(x);
d->cat.ndev++;
}
list = ialloc(d->cat.ndev*sizeof(Device*), 0);
d->private = list;
for(x=d->cat.first; x; x=x->link) {
*list++ = x;
x->size = devsize(x);
}
}
Devsize
mcatsize(Device *d)
{
Device *x;
Devsize l, m;
l = 0;
for(x=d->cat.first; x; x=x->link) {
m = x->size;
if(m == 0) {
m = devsize(x);
x->size = m;
}
l += m;
}
return l;
}
int
mcatread(Device *d, Off b, void *c)
{
Device *x;
Devsize l, m;
l = 0;
for(x=d->cat.first; x; x=x->link) {
m = x->size;
if(m == 0) {
m = devsize(x);
x->size = m;
}
if(b < l+m)
return devread(x, b-l, c);
l += m;
}
print("mcatread %lld %lld\n", (Wideoff)b, (Wideoff)l);
return 1;
}
int
mcatwrite(Device *d, Off b, void *c)
{
Device *x;
Devsize l, m;
l = 0;
for(x=d->cat.first; x; x=x->link) {
m = x->size;
if(m == 0) {
m = devsize(x);
x->size = m;
}
if(b < l+m)
return devwrite(x, b-l, c);
l += m;
}
print("mcatwrite %lld %lld\n", (Wideoff)b, (Wideoff)l);
return 1;
}
/*
* multiple interleave devices
*/
void
mlevinit(Device *d)
{
Device *x;
mcatinit(d);
for(x=d->cat.first; x; x=x->link)
x->size = devsize(x);
}
Devsize
mlevsize(Device *d)
{
Device *x;
int n;
Devsize m, min;
min = 0;
n = 0;
for(x=d->cat.first; x; x=x->link) {
m = x->size;
if(m == 0) {
m = devsize(x);
x->size = m;
}
if(min == 0 || m < min)
min = m;
n++;
}
return n * min;
}
int
mlevread(Device *d, Off b, void *c)
{
int n;
Device **list;
n = d->cat.ndev;
list = d->private;
return devread(list[b%n], b/n, c);
}
int
mlevwrite(Device *d, Off b, void *c)
{
int n;
Device **list;
n = d->cat.ndev;
list = d->private;
return devwrite(list[b%n], b/n, c);
}
/*
* mirror device
*/
void
mirrinit(Device *d)
{
Device *x;
mcatinit(d);
for(x=d->cat.first; x; x=x->link)
x->size = devsize(x);
}
Devsize
mirrsize(Device *d)
{
Device *x;
int n;
Devsize m, min;
min = 0;
n = 0;
for(x=d->cat.first; x; x=x->link) {
m = x->size;
if(m == 0) {
m = devsize(x);
x->size = m;
}
if(min == 0 || m < min)
min = m;
n++;
}
return min;
}
int
mirrread(Device *d, Off b, void *c)
{
Device *x;
for(x=d->cat.first; x; x=x->link) {
if(x->size == 0)
x->size = devsize(x);
if (devread(x, b, c) == 0) /* okay? */
return 0;
}
// DANGER WILL ROBINSON - all copies of this block were bad
print("mirrread %Z error at block %lld\n", d, (Wideoff)b);
return 1;
}
/*
* write the mirror(s) first so that a power outage, for example, will
* find the main device written only if the mirrors are too, thus
* checking the main device will also correctly check the mirror(s).
*
* devread and devwrite are synchronous; all buffering must be
* implemented at higher levels.
*/
static int
ewrite(Device *x, Off b, void *c)
{
if(x->size == 0)
x->size = devsize(x);
if (devwrite(x, b, c) != 0) {
print("mirrwrite %Z error at block %lld\n", x, (Wideoff)b);
return 1;
}
return 0;
}
static int
wrmirrs1st(Device *x, Off b, void *c) // write any mirrors of x, then x
{
int e;
if (x == nil)
return 0;
e = wrmirrs1st(x->link, b, c);
return e | ewrite(x, b, c);
}
int
mirrwrite(Device *d, Off b, void *c)
{
return wrmirrs1st(d->cat.first, b, c);
}