xref: /plan9/sys/src/cmd/disk/kfs/devwren.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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;
147dd7cddfSDavid du Colombier 	uvlong	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;
217dd7cddfSDavid du Colombier int		nwren;
223e12c5d1SDavid du Colombier int		badmagic;
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier static Wren *
wren(Device dev)253e12c5d1SDavid du Colombier wren(Device dev)
263e12c5d1SDavid du Colombier {
273e12c5d1SDavid du Colombier 	int i;
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier 	for(i = 0; i < maxwren; i++)
303e12c5d1SDavid du Colombier 		if(devcmp(dev, wrens[i].dev) == 0)
313e12c5d1SDavid du Colombier 			return &wrens[i];
323e12c5d1SDavid du Colombier 	panic("can't find wren for %D", dev);
333e12c5d1SDavid du Colombier 	return 0;
343e12c5d1SDavid du Colombier }
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier void
wreninit(Device dev)373e12c5d1SDavid du Colombier wreninit(Device dev)
383e12c5d1SDavid du Colombier {
39*9a747e4fSDavid du Colombier 	char buf[MAXBUFSIZE];
403e12c5d1SDavid du Colombier 	Wren *w;
41*9a747e4fSDavid du Colombier 	Dir *d;
423e12c5d1SDavid du Colombier 	int fd, i;
433e12c5d1SDavid du Colombier 
443e12c5d1SDavid du Colombier 	if(wrens == 0)
453e12c5d1SDavid du Colombier 		wrens = ialloc(MAXWREN * sizeof *wrens);
463e12c5d1SDavid du Colombier 	w = &wrens[maxwren];
473e12c5d1SDavid du Colombier 	fd = open(wrenfile, ORDWR);
483e12c5d1SDavid du Colombier 	if(fd < 0)
493e12c5d1SDavid du Colombier 		panic("can't open %s", wrenfile);
50*9a747e4fSDavid du Colombier 	if((d = dirfstat(fd)) == nil)
513e12c5d1SDavid du Colombier 		panic("can't stat %s\n", wrenfile);
523e12c5d1SDavid du Colombier 	seek(fd, 0, 0);
533e12c5d1SDavid du Colombier 	i = read(fd, buf, sizeof buf);
543e12c5d1SDavid du Colombier 	if(i < sizeof buf)
553e12c5d1SDavid du Colombier 		panic("can't read %s", wrenfile);
563e12c5d1SDavid du Colombier 	badmagic = 0;
573e12c5d1SDavid du Colombier 	RBUFSIZE = 1024;
583e12c5d1SDavid du Colombier 	if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
593e12c5d1SDavid du Colombier 		RBUFSIZE = atol(buf+256+strlen(WMAGIC));
603e12c5d1SDavid du Colombier 		if(RBUFSIZE % 512){
613e12c5d1SDavid du Colombier 			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
623e12c5d1SDavid du Colombier 			RBUFSIZE = 1024;
633e12c5d1SDavid du Colombier 		}
643e12c5d1SDavid du Colombier 	}else
653e12c5d1SDavid du Colombier 		badmagic = 1;
663e12c5d1SDavid du Colombier 	w->dev = dev;
67*9a747e4fSDavid du Colombier 	w->size = d->length;
68*9a747e4fSDavid du Colombier 	free(d);
693e12c5d1SDavid du Colombier 	w->fd = fd;
703e12c5d1SDavid du Colombier 	maxwren++;
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier void
wrenream(Device dev)743e12c5d1SDavid du Colombier wrenream(Device dev)
753e12c5d1SDavid du Colombier {
763e12c5d1SDavid du Colombier 	Wren *w;
77*9a747e4fSDavid du Colombier 	char buf[MAXBUFSIZE];
783e12c5d1SDavid du Colombier 	int fd, i;
793e12c5d1SDavid du Colombier 
803e12c5d1SDavid du Colombier 	if(RBUFSIZE % 512)
813e12c5d1SDavid du Colombier 		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
8259cc4ca5SDavid du Colombier 	if(RBUFSIZE > sizeof(buf))
8359cc4ca5SDavid du Colombier 		panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
8459cc4ca5SDavid du Colombier 
853e12c5d1SDavid du Colombier 	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
863e12c5d1SDavid du Colombier 	w = wren(dev);
873e12c5d1SDavid du Colombier 	fd = w->fd;
88219b2ee8SDavid du Colombier 	memset(buf, 0, sizeof buf);
893e12c5d1SDavid du Colombier 	sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
903e12c5d1SDavid du Colombier 	qlock(w);
913e12c5d1SDavid du Colombier 	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
923e12c5d1SDavid du Colombier 	qunlock(w);
933e12c5d1SDavid du Colombier 	if(i < 0)
943e12c5d1SDavid du Colombier 		panic("can't ream disk");
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier 
973e12c5d1SDavid du Colombier int
wrentag(char * p,int tag,long qpath)983e12c5d1SDavid du Colombier wrentag(char *p, int tag, long qpath)
993e12c5d1SDavid du Colombier {
1003e12c5d1SDavid du Colombier 	Tag *t;
1013e12c5d1SDavid du Colombier 
1023e12c5d1SDavid du Colombier 	t = (Tag*)(p+BUFSIZE);
1033e12c5d1SDavid du Colombier 	return t->tag != tag || (qpath&~QPDIR) != t->path;
1043e12c5d1SDavid du Colombier }
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier int
wrencheck(Device dev)1073e12c5d1SDavid du Colombier wrencheck(Device dev)
1083e12c5d1SDavid du Colombier {
109*9a747e4fSDavid du Colombier 	char buf[MAXBUFSIZE];
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier 	if(badmagic)
1123e12c5d1SDavid du Colombier 		return 1;
11359cc4ca5SDavid du Colombier 	if(RBUFSIZE > sizeof(buf))
11459cc4ca5SDavid du Colombier 		panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
11559cc4ca5SDavid du Colombier 
1163e12c5d1SDavid du Colombier 	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
1173e12c5d1SDavid du Colombier 	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
1183e12c5d1SDavid du Colombier 		return 1;
1193e12c5d1SDavid du Colombier 	if(((Dentry *)buf)[0].mode & DALLOC)
1203e12c5d1SDavid du Colombier 		return 0;
1213e12c5d1SDavid du Colombier 	return 1;
1223e12c5d1SDavid du Colombier }
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier long
wrensize(Device dev)1253e12c5d1SDavid du Colombier wrensize(Device dev)
1263e12c5d1SDavid du Colombier {
1273e12c5d1SDavid du Colombier 	return wren(dev)->size / RBUFSIZE;
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier long
wrensuper(Device dev)1313e12c5d1SDavid du Colombier wrensuper(Device dev)
1323e12c5d1SDavid du Colombier {
1333e12c5d1SDavid du Colombier 	USED(dev);
1343e12c5d1SDavid du Colombier 	return 1;
1353e12c5d1SDavid du Colombier }
1363e12c5d1SDavid du Colombier 
1373e12c5d1SDavid du Colombier long
wrenroot(Device dev)1383e12c5d1SDavid du Colombier wrenroot(Device dev)
1393e12c5d1SDavid du Colombier {
1403e12c5d1SDavid du Colombier 	USED(dev);
1413e12c5d1SDavid du Colombier 	return 2;
1423e12c5d1SDavid du Colombier }
1433e12c5d1SDavid du Colombier 
1443e12c5d1SDavid du Colombier int
wrenread(Device dev,long addr,void * b)1453e12c5d1SDavid du Colombier wrenread(Device dev, long addr, void *b)
1463e12c5d1SDavid du Colombier {
1473e12c5d1SDavid du Colombier 	Wren *w;
1483e12c5d1SDavid du Colombier 	int fd, i;
1493e12c5d1SDavid du Colombier 
1503e12c5d1SDavid du Colombier 	w = wren(dev);
1513e12c5d1SDavid du Colombier 	fd = w->fd;
1523e12c5d1SDavid du Colombier 	qlock(w);
1537dd7cddfSDavid du Colombier 	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
1543e12c5d1SDavid du Colombier 	qunlock(w);
15580ee5cbfSDavid du Colombier 	if(i)
15680ee5cbfSDavid du Colombier 		print("wrenread failed: %r\n");
1573e12c5d1SDavid du Colombier 	return i;
1583e12c5d1SDavid du Colombier }
1593e12c5d1SDavid du Colombier 
1603e12c5d1SDavid du Colombier int
wrenwrite(Device dev,long addr,void * b)1613e12c5d1SDavid du Colombier wrenwrite(Device dev, long addr, void *b)
1623e12c5d1SDavid du Colombier {
1633e12c5d1SDavid du Colombier 	Wren *w;
1643e12c5d1SDavid du Colombier 	int fd, i;
1653e12c5d1SDavid du Colombier 
1663e12c5d1SDavid du Colombier 	w = wren(dev);
1673e12c5d1SDavid du Colombier 	fd = w->fd;
1683e12c5d1SDavid du Colombier 	qlock(w);
1697dd7cddfSDavid du Colombier 	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
1703e12c5d1SDavid du Colombier 	qunlock(w);
17180ee5cbfSDavid du Colombier 	if(i)
17280ee5cbfSDavid du Colombier 		print("wrenwrite failed: %r\n");
1733e12c5d1SDavid du Colombier 	return i;
1743e12c5d1SDavid du Colombier }
175