xref: /plan9-contrib/sys/src/cmd/disk/kfs/devwren.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include "all.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier enum{
43e12c5d1SDavid du Colombier 	MAXWREN = 7,
53e12c5d1SDavid du Colombier };
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier #define WMAGIC	"kfs wren device\n"
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier typedef struct Wren	Wren;
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier struct Wren{
123e12c5d1SDavid du Colombier 	QLock;
133e12c5d1SDavid du Colombier 	Device	dev;
143e12c5d1SDavid du Colombier 	ulong	size;
153e12c5d1SDavid du Colombier 	int	fd;
163e12c5d1SDavid du Colombier };
173e12c5d1SDavid du Colombier 
183e12c5d1SDavid du Colombier static Wren	*wrens;
193e12c5d1SDavid du Colombier static int	maxwren;
203e12c5d1SDavid du Colombier char		*wrenfile;
213e12c5d1SDavid du Colombier int		badmagic;
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier static Wren *
243e12c5d1SDavid du Colombier wren(Device dev)
253e12c5d1SDavid du Colombier {
263e12c5d1SDavid du Colombier 	int i;
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier 	for(i = 0; i < maxwren; i++)
293e12c5d1SDavid du Colombier 		if(devcmp(dev, wrens[i].dev) == 0)
303e12c5d1SDavid du Colombier 			return &wrens[i];
313e12c5d1SDavid du Colombier 	panic("can't find wren for %D", dev);
323e12c5d1SDavid du Colombier 	return 0;
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier 
353e12c5d1SDavid du Colombier /*
363e12c5d1SDavid du Colombier  * find out the length of a file
373e12c5d1SDavid du Colombier  * given the mesg version of a stat buffer
383e12c5d1SDavid du Colombier  * we call this because convM2D is different
393e12c5d1SDavid du Colombier  * for the file system than in the os
403e12c5d1SDavid du Colombier  */
413e12c5d1SDavid du Colombier long
423e12c5d1SDavid du Colombier statlen(char *ap)
433e12c5d1SDavid du Colombier {
443e12c5d1SDavid du Colombier 	uchar *p;
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	p = (uchar*)ap;
473e12c5d1SDavid du Colombier 	p += 3*NAMELEN+5*4;
483e12c5d1SDavid du Colombier 	return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
493e12c5d1SDavid du Colombier }
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier void
523e12c5d1SDavid du Colombier wreninit(Device dev)
533e12c5d1SDavid du Colombier {
543e12c5d1SDavid du Colombier 	char buf[8*1024], d[DIRREC];
553e12c5d1SDavid du Colombier 	Wren *w;
563e12c5d1SDavid du Colombier 	int fd, i;
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier 	if(wrens == 0)
593e12c5d1SDavid du Colombier 		wrens = ialloc(MAXWREN * sizeof *wrens);
603e12c5d1SDavid du Colombier 	w = &wrens[maxwren];
613e12c5d1SDavid du Colombier 	fd = open(wrenfile, ORDWR);
623e12c5d1SDavid du Colombier 	if(fd < 0)
633e12c5d1SDavid du Colombier 		panic("can't open %s", wrenfile);
643e12c5d1SDavid du Colombier 	if(fstat(fd, d) < 0)
653e12c5d1SDavid du Colombier 		panic("can't stat %s\n", wrenfile);
663e12c5d1SDavid du Colombier 	seek(fd, 0, 0);
673e12c5d1SDavid du Colombier 	i = read(fd, buf, sizeof buf);
683e12c5d1SDavid du Colombier 	if(i < sizeof buf)
693e12c5d1SDavid du Colombier 		panic("can't read %s", wrenfile);
703e12c5d1SDavid du Colombier 	badmagic = 0;
713e12c5d1SDavid du Colombier 	RBUFSIZE = 1024;
723e12c5d1SDavid du Colombier 	if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
733e12c5d1SDavid du Colombier 		RBUFSIZE = atol(buf+256+strlen(WMAGIC));
743e12c5d1SDavid du Colombier 		if(RBUFSIZE % 512){
753e12c5d1SDavid du Colombier 			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
763e12c5d1SDavid du Colombier 			RBUFSIZE = 1024;
773e12c5d1SDavid du Colombier 		}
783e12c5d1SDavid du Colombier 	}else
793e12c5d1SDavid du Colombier 		badmagic = 1;
803e12c5d1SDavid du Colombier 	w->dev = dev;
813e12c5d1SDavid du Colombier 	w->size = statlen(d);
823e12c5d1SDavid du Colombier 	w->fd = fd;
833e12c5d1SDavid du Colombier 	maxwren++;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier void
873e12c5d1SDavid du Colombier wrenream(Device dev)
883e12c5d1SDavid du Colombier {
893e12c5d1SDavid du Colombier 	Wren *w;
903e12c5d1SDavid du Colombier 	char buf[8*1024];
913e12c5d1SDavid du Colombier 	int fd, i;
923e12c5d1SDavid du Colombier 
933e12c5d1SDavid du Colombier 	if(RBUFSIZE % 512)
943e12c5d1SDavid du Colombier 		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
953e12c5d1SDavid du Colombier 	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
963e12c5d1SDavid du Colombier 	w = wren(dev);
973e12c5d1SDavid du Colombier 	fd = w->fd;
98*219b2ee8SDavid du Colombier 	memset(buf, 0, sizeof buf);
993e12c5d1SDavid du Colombier 	sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
1003e12c5d1SDavid du Colombier 	qlock(w);
1013e12c5d1SDavid du Colombier 	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
1023e12c5d1SDavid du Colombier 	qunlock(w);
1033e12c5d1SDavid du Colombier 	if(i < 0)
1043e12c5d1SDavid du Colombier 		panic("can't ream disk");
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier 
1073e12c5d1SDavid du Colombier int
1083e12c5d1SDavid du Colombier wrentag(char *p, int tag, long qpath)
1093e12c5d1SDavid du Colombier {
1103e12c5d1SDavid du Colombier 	Tag *t;
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier 	t = (Tag*)(p+BUFSIZE);
1133e12c5d1SDavid du Colombier 	return t->tag != tag || (qpath&~QPDIR) != t->path;
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier int
1173e12c5d1SDavid du Colombier wrencheck(Device dev)
1183e12c5d1SDavid du Colombier {
1193e12c5d1SDavid du Colombier 	char buf[8*1024];
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier 	if(badmagic)
1223e12c5d1SDavid du Colombier 		return 1;
1233e12c5d1SDavid du Colombier 	if(RBUFSIZE > sizeof buf)
1243e12c5d1SDavid du Colombier 		panic("bufsize too big");
1253e12c5d1SDavid du Colombier 	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
1263e12c5d1SDavid du Colombier 	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
1273e12c5d1SDavid du Colombier 		return 1;
1283e12c5d1SDavid du Colombier 	if(((Dentry *)buf)[0].mode & DALLOC)
1293e12c5d1SDavid du Colombier 		return 0;
1303e12c5d1SDavid du Colombier 	return 1;
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier 
1333e12c5d1SDavid du Colombier long
1343e12c5d1SDavid du Colombier wrensize(Device dev)
1353e12c5d1SDavid du Colombier {
1363e12c5d1SDavid du Colombier 	return wren(dev)->size / RBUFSIZE;
1373e12c5d1SDavid du Colombier }
1383e12c5d1SDavid du Colombier 
1393e12c5d1SDavid du Colombier long
1403e12c5d1SDavid du Colombier wrensuper(Device dev)
1413e12c5d1SDavid du Colombier {
1423e12c5d1SDavid du Colombier 	USED(dev);
1433e12c5d1SDavid du Colombier 	return 1;
1443e12c5d1SDavid du Colombier }
1453e12c5d1SDavid du Colombier 
1463e12c5d1SDavid du Colombier long
1473e12c5d1SDavid du Colombier wrenroot(Device dev)
1483e12c5d1SDavid du Colombier {
1493e12c5d1SDavid du Colombier 	USED(dev);
1503e12c5d1SDavid du Colombier 	return 2;
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier int
1543e12c5d1SDavid du Colombier wrenread(Device dev, long addr, void *b)
1553e12c5d1SDavid du Colombier {
1563e12c5d1SDavid du Colombier 	Wren *w;
1573e12c5d1SDavid du Colombier 	int fd, i;
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier 	w = wren(dev);
1603e12c5d1SDavid du Colombier 	fd = w->fd;
1613e12c5d1SDavid du Colombier 	qlock(w);
1623e12c5d1SDavid du Colombier 	i = seek(fd, addr*RBUFSIZE, 0) < 0 || read(fd, b, RBUFSIZE) != RBUFSIZE;
1633e12c5d1SDavid du Colombier 	qunlock(w);
1643e12c5d1SDavid du Colombier 	return i;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier int
1683e12c5d1SDavid du Colombier wrenwrite(Device dev, long addr, void *b)
1693e12c5d1SDavid du Colombier {
1703e12c5d1SDavid du Colombier 	Wren *w;
1713e12c5d1SDavid du Colombier 	int fd, i;
1723e12c5d1SDavid du Colombier 
1733e12c5d1SDavid du Colombier 	w = wren(dev);
1743e12c5d1SDavid du Colombier 	fd = w->fd;
1753e12c5d1SDavid du Colombier 	qlock(w);
1763e12c5d1SDavid du Colombier 	i = seek(fd, addr*RBUFSIZE, 0) < 0 || write(fd, b, RBUFSIZE) != RBUFSIZE;
1773e12c5d1SDavid du Colombier 	qunlock(w);
1783e12c5d1SDavid du Colombier 	return i;
1793e12c5d1SDavid du Colombier }
180