xref: /plan9/sys/src/cmd/disk/kfs/devmulti.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include "all.h"
2*7dd7cddfSDavid du Colombier 
3*7dd7cddfSDavid du Colombier enum{
4*7dd7cddfSDavid du Colombier 	MAXWREN = 7,
5*7dd7cddfSDavid du Colombier };
6*7dd7cddfSDavid du Colombier 
7*7dd7cddfSDavid du Colombier static char WMAGIC[] =	"kfs wren device\n";
8*7dd7cddfSDavid du Colombier static char MMAGIC[] =	"kfs multi-wren device %4d/%4d\n";
9*7dd7cddfSDavid du Colombier 
10*7dd7cddfSDavid du Colombier typedef struct Wren	Wren;
11*7dd7cddfSDavid du Colombier 
12*7dd7cddfSDavid du Colombier struct Wren{
13*7dd7cddfSDavid du Colombier 	QLock;
14*7dd7cddfSDavid du Colombier 	Device	dev;
15*7dd7cddfSDavid du Colombier 	ulong	nblocks;
16*7dd7cddfSDavid du Colombier 	int	fd;
17*7dd7cddfSDavid du Colombier };
18*7dd7cddfSDavid du Colombier 
19*7dd7cddfSDavid du Colombier static char	*wmagic = WMAGIC;
20*7dd7cddfSDavid du Colombier static Wren	*wrens;
21*7dd7cddfSDavid du Colombier static int	maxwren;
22*7dd7cddfSDavid du Colombier char		*wrenfile;
23*7dd7cddfSDavid du Colombier int		nwren;
24*7dd7cddfSDavid du Colombier int		badmagic;
25*7dd7cddfSDavid du Colombier 
26*7dd7cddfSDavid du Colombier static Wren *
27*7dd7cddfSDavid du Colombier wren(Device dev)
28*7dd7cddfSDavid du Colombier {
29*7dd7cddfSDavid du Colombier 	int i;
30*7dd7cddfSDavid du Colombier 
31*7dd7cddfSDavid du Colombier 	for(i = 0; i < maxwren; i++)
32*7dd7cddfSDavid du Colombier 		if(devcmp(dev, wrens[i].dev) == 0)
33*7dd7cddfSDavid du Colombier 			return &wrens[i];
34*7dd7cddfSDavid du Colombier 	panic("can't find wren for %D", dev);
35*7dd7cddfSDavid du Colombier 	return 0;
36*7dd7cddfSDavid du Colombier }
37*7dd7cddfSDavid du Colombier 
38*7dd7cddfSDavid du Colombier /*
39*7dd7cddfSDavid du Colombier  * find out the length of a file
40*7dd7cddfSDavid du Colombier  * given the mesg version of a stat buffer
41*7dd7cddfSDavid du Colombier  * we call this because convM2D is different
42*7dd7cddfSDavid du Colombier  * for the file system than in the os
43*7dd7cddfSDavid du Colombier  */
44*7dd7cddfSDavid du Colombier uvlong
45*7dd7cddfSDavid du Colombier statlen(char *ap)
46*7dd7cddfSDavid du Colombier {
47*7dd7cddfSDavid du Colombier 	uchar *p;
48*7dd7cddfSDavid du Colombier 	ulong ll, hl;
49*7dd7cddfSDavid du Colombier 
50*7dd7cddfSDavid du Colombier 	p = (uchar*)ap;
51*7dd7cddfSDavid du Colombier 	p += 3*NAMELEN+5*4;
52*7dd7cddfSDavid du Colombier 	ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
53*7dd7cddfSDavid du Colombier 	hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
54*7dd7cddfSDavid du Colombier 	return ll | ((uvlong) hl << 32);
55*7dd7cddfSDavid du Colombier }
56*7dd7cddfSDavid du Colombier 
57*7dd7cddfSDavid du Colombier static void
58*7dd7cddfSDavid du Colombier wrenpartinit(Device dev, int k)
59*7dd7cddfSDavid du Colombier {
60*7dd7cddfSDavid du Colombier 	char buf[8*1024], d[DIRREC];
61*7dd7cddfSDavid du Colombier 	char file[128], magic[64];
62*7dd7cddfSDavid du Colombier 	Wren *w;
63*7dd7cddfSDavid du Colombier 	int fd, i, nmagic;
64*7dd7cddfSDavid du Colombier 
65*7dd7cddfSDavid du Colombier 	if(wrens == 0)
66*7dd7cddfSDavid du Colombier 		wrens = ialloc(MAXWREN * sizeof *wrens);
67*7dd7cddfSDavid du Colombier 	w = &wrens[maxwren];
68*7dd7cddfSDavid du Colombier 	if(nwren > 0)
69*7dd7cddfSDavid du Colombier 		sprint(file, "%s%d", wrenfile, k);
70*7dd7cddfSDavid du Colombier 	else
71*7dd7cddfSDavid du Colombier 		strcpy(file, wrenfile);
72*7dd7cddfSDavid du Colombier 	fd = open(file, ORDWR);
73*7dd7cddfSDavid du Colombier 	if(fd < 0)
74*7dd7cddfSDavid du Colombier 		panic("can't open %s", file);
75*7dd7cddfSDavid du Colombier 	if(fstat(fd, d) < 0)
76*7dd7cddfSDavid du Colombier 		panic("can't stat %s\n", file);
77*7dd7cddfSDavid du Colombier 	seek(fd, 0, 0);
78*7dd7cddfSDavid du Colombier 	i = read(fd, buf, sizeof buf);
79*7dd7cddfSDavid du Colombier 	if(i < sizeof buf)
80*7dd7cddfSDavid du Colombier 		panic("can't read %s", file);
81*7dd7cddfSDavid du Colombier 	badmagic = 0;
82*7dd7cddfSDavid du Colombier 	RBUFSIZE = 1024;
83*7dd7cddfSDavid du Colombier 	sprint(magic, wmagic, k, nwren);
84*7dd7cddfSDavid du Colombier 	nmagic = strlen(magic);
85*7dd7cddfSDavid du Colombier 	if(strncmp(buf+256, magic, nmagic) == 0){
86*7dd7cddfSDavid du Colombier 		RBUFSIZE = atol(buf+256+nmagic);
87*7dd7cddfSDavid du Colombier 		if(RBUFSIZE % 512){
88*7dd7cddfSDavid du Colombier 			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
89*7dd7cddfSDavid du Colombier 			RBUFSIZE = 1024;
90*7dd7cddfSDavid du Colombier 		}
91*7dd7cddfSDavid du Colombier 	}else
92*7dd7cddfSDavid du Colombier 		badmagic = 1;
93*7dd7cddfSDavid du Colombier 	w->dev = dev;
94*7dd7cddfSDavid du Colombier 	w->nblocks = statlen(d)/RBUFSIZE;
95*7dd7cddfSDavid du Colombier 	if(k > 0)
96*7dd7cddfSDavid du Colombier 		w->nblocks -= 1;	/* don't count magic */
97*7dd7cddfSDavid du Colombier 	w->fd = fd;
98*7dd7cddfSDavid du Colombier 	maxwren++;
99*7dd7cddfSDavid du Colombier }
100*7dd7cddfSDavid du Colombier 
101*7dd7cddfSDavid du Colombier void
102*7dd7cddfSDavid du Colombier wreninit(Device dev)
103*7dd7cddfSDavid du Colombier {
104*7dd7cddfSDavid du Colombier 	int i;
105*7dd7cddfSDavid du Colombier 
106*7dd7cddfSDavid du Colombier 	if(nwren > 0)
107*7dd7cddfSDavid du Colombier 		wmagic = MMAGIC;
108*7dd7cddfSDavid du Colombier 	i = 0;
109*7dd7cddfSDavid du Colombier 	do{
110*7dd7cddfSDavid du Colombier 		wrenpartinit(dev, i);
111*7dd7cddfSDavid du Colombier 	}while(++i < nwren);
112*7dd7cddfSDavid du Colombier }
113*7dd7cddfSDavid du Colombier 
114*7dd7cddfSDavid du Colombier static void
115*7dd7cddfSDavid du Colombier wrenpartream(Device dev, int k)
116*7dd7cddfSDavid du Colombier {
117*7dd7cddfSDavid du Colombier 	Wren *w;
118*7dd7cddfSDavid du Colombier 	char buf[8*1024], magic[64];
119*7dd7cddfSDavid du Colombier 	int fd, i;
120*7dd7cddfSDavid du Colombier 
121*7dd7cddfSDavid du Colombier 	if(RBUFSIZE % 512)
122*7dd7cddfSDavid du Colombier 		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
123*7dd7cddfSDavid du Colombier 	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
124*7dd7cddfSDavid du Colombier 	w = wren(dev)+k;
125*7dd7cddfSDavid du Colombier 	fd = w->fd;
126*7dd7cddfSDavid du Colombier 	memset(buf, 0, sizeof buf);
127*7dd7cddfSDavid du Colombier 	sprint(magic, wmagic, k, nwren);
128*7dd7cddfSDavid du Colombier 	sprint(buf+256, "%s%d\n", magic, RBUFSIZE);
129*7dd7cddfSDavid du Colombier 	qlock(w);
130*7dd7cddfSDavid du Colombier 	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
131*7dd7cddfSDavid du Colombier 	qunlock(w);
132*7dd7cddfSDavid du Colombier 	if(i < 0)
133*7dd7cddfSDavid du Colombier 		panic("can't ream disk");
134*7dd7cddfSDavid du Colombier }
135*7dd7cddfSDavid du Colombier 
136*7dd7cddfSDavid du Colombier void
137*7dd7cddfSDavid du Colombier wrenream(Device dev)
138*7dd7cddfSDavid du Colombier {
139*7dd7cddfSDavid du Colombier 	int i;
140*7dd7cddfSDavid du Colombier 
141*7dd7cddfSDavid du Colombier 	i = 0;
142*7dd7cddfSDavid du Colombier 	do{
143*7dd7cddfSDavid du Colombier 		wrenpartream(dev, i);
144*7dd7cddfSDavid du Colombier 	}while(++i < nwren);
145*7dd7cddfSDavid du Colombier }
146*7dd7cddfSDavid du Colombier 
147*7dd7cddfSDavid du Colombier static int
148*7dd7cddfSDavid du Colombier wrentag(char *p, int tag, long qpath)
149*7dd7cddfSDavid du Colombier {
150*7dd7cddfSDavid du Colombier 	Tag *t;
151*7dd7cddfSDavid du Colombier 
152*7dd7cddfSDavid du Colombier 	t = (Tag*)(p+BUFSIZE);
153*7dd7cddfSDavid du Colombier 	return t->tag != tag || (qpath&~QPDIR) != t->path;
154*7dd7cddfSDavid du Colombier }
155*7dd7cddfSDavid du Colombier 
156*7dd7cddfSDavid du Colombier int
157*7dd7cddfSDavid du Colombier wrencheck(Device dev)
158*7dd7cddfSDavid du Colombier {
159*7dd7cddfSDavid du Colombier 	char buf[8*1024];
160*7dd7cddfSDavid du Colombier 
161*7dd7cddfSDavid du Colombier 	if(badmagic)
162*7dd7cddfSDavid du Colombier 		return 1;
163*7dd7cddfSDavid du Colombier 	if(RBUFSIZE > sizeof buf)
164*7dd7cddfSDavid du Colombier 		panic("bufsize too big");
165*7dd7cddfSDavid du Colombier 	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
166*7dd7cddfSDavid du Colombier 	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
167*7dd7cddfSDavid du Colombier 		return 1;
168*7dd7cddfSDavid du Colombier 	if(((Dentry *)buf)[0].mode & DALLOC)
169*7dd7cddfSDavid du Colombier 		return 0;
170*7dd7cddfSDavid du Colombier 	return 1;
171*7dd7cddfSDavid du Colombier }
172*7dd7cddfSDavid du Colombier 
173*7dd7cddfSDavid du Colombier long
174*7dd7cddfSDavid du Colombier wrensize(Device dev)
175*7dd7cddfSDavid du Colombier {
176*7dd7cddfSDavid du Colombier 	Wren *w;
177*7dd7cddfSDavid du Colombier 	int i, nb;
178*7dd7cddfSDavid du Colombier 
179*7dd7cddfSDavid du Colombier 	w = wren(dev);
180*7dd7cddfSDavid du Colombier 	nb = 0;
181*7dd7cddfSDavid du Colombier 	i = 0;
182*7dd7cddfSDavid du Colombier 	do{
183*7dd7cddfSDavid du Colombier 		nb += w[i].nblocks;
184*7dd7cddfSDavid du Colombier 	}while(++i < nwren);
185*7dd7cddfSDavid du Colombier 	return nb;
186*7dd7cddfSDavid du Colombier }
187*7dd7cddfSDavid du Colombier 
188*7dd7cddfSDavid du Colombier long
189*7dd7cddfSDavid du Colombier wrensuper(Device dev)
190*7dd7cddfSDavid du Colombier {
191*7dd7cddfSDavid du Colombier 	USED(dev);
192*7dd7cddfSDavid du Colombier 	return 1;
193*7dd7cddfSDavid du Colombier }
194*7dd7cddfSDavid du Colombier 
195*7dd7cddfSDavid du Colombier long
196*7dd7cddfSDavid du Colombier wrenroot(Device dev)
197*7dd7cddfSDavid du Colombier {
198*7dd7cddfSDavid du Colombier 	USED(dev);
199*7dd7cddfSDavid du Colombier 	return 2;
200*7dd7cddfSDavid du Colombier }
201*7dd7cddfSDavid du Colombier 
202*7dd7cddfSDavid du Colombier int
203*7dd7cddfSDavid du Colombier wrenread(Device dev, long addr, void *b)
204*7dd7cddfSDavid du Colombier {
205*7dd7cddfSDavid du Colombier 	Wren *w;
206*7dd7cddfSDavid du Colombier 	int fd, i;
207*7dd7cddfSDavid du Colombier 
208*7dd7cddfSDavid du Colombier 	w = wren(dev);
209*7dd7cddfSDavid du Colombier 	for(i=0; i<nwren; i++){
210*7dd7cddfSDavid du Colombier 		if(addr < w->nblocks)
211*7dd7cddfSDavid du Colombier 			break;
212*7dd7cddfSDavid du Colombier 		addr -= w->nblocks;
213*7dd7cddfSDavid du Colombier 		++w;
214*7dd7cddfSDavid du Colombier 	}
215*7dd7cddfSDavid du Colombier 	if(i > 0)
216*7dd7cddfSDavid du Colombier 		addr++;
217*7dd7cddfSDavid du Colombier 	fd = w->fd;
218*7dd7cddfSDavid du Colombier 	qlock(w);
219*7dd7cddfSDavid du Colombier 	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
220*7dd7cddfSDavid du Colombier 	qunlock(w);
221*7dd7cddfSDavid du Colombier 	return i;
222*7dd7cddfSDavid du Colombier }
223*7dd7cddfSDavid du Colombier 
224*7dd7cddfSDavid du Colombier int
225*7dd7cddfSDavid du Colombier wrenwrite(Device dev, long addr, void *b)
226*7dd7cddfSDavid du Colombier {
227*7dd7cddfSDavid du Colombier 	Wren *w;
228*7dd7cddfSDavid du Colombier 	int fd, i;
229*7dd7cddfSDavid du Colombier 
230*7dd7cddfSDavid du Colombier 	w = wren(dev);
231*7dd7cddfSDavid du Colombier 	for(i=0; i<nwren; i++){
232*7dd7cddfSDavid du Colombier 		if(addr < w->nblocks)
233*7dd7cddfSDavid du Colombier 			break;
234*7dd7cddfSDavid du Colombier 		addr -= w->nblocks;
235*7dd7cddfSDavid du Colombier 		++w;
236*7dd7cddfSDavid du Colombier 	}
237*7dd7cddfSDavid du Colombier 	if(i > 0)
238*7dd7cddfSDavid du Colombier 		addr++;
239*7dd7cddfSDavid du Colombier 	fd = w->fd;
240*7dd7cddfSDavid du Colombier 	qlock(w);
241*7dd7cddfSDavid du Colombier 	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
242*7dd7cddfSDavid du Colombier 	qunlock(w);
243*7dd7cddfSDavid du Colombier 	return i;
244*7dd7cddfSDavid du Colombier }
245