237 lines · 3.4 KB · C
RawDownload
#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);}