xref: /plan9/sys/src/cmd/disk/kfs/devmulti.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
17dd7cddfSDavid du Colombier #include "all.h"
27dd7cddfSDavid du Colombier 
37dd7cddfSDavid du Colombier enum{
47dd7cddfSDavid du Colombier 	MAXWREN = 7,
57dd7cddfSDavid du Colombier };
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier static char WMAGIC[] =	"kfs wren device\n";
87dd7cddfSDavid du Colombier static char MMAGIC[] =	"kfs multi-wren device %4d/%4d\n";
97dd7cddfSDavid du Colombier 
107dd7cddfSDavid du Colombier typedef struct Wren	Wren;
117dd7cddfSDavid du Colombier 
127dd7cddfSDavid du Colombier struct Wren{
137dd7cddfSDavid du Colombier 	QLock;
147dd7cddfSDavid du Colombier 	Device	dev;
157dd7cddfSDavid du Colombier 	ulong	nblocks;
167dd7cddfSDavid du Colombier 	int	fd;
177dd7cddfSDavid du Colombier };
187dd7cddfSDavid du Colombier 
197dd7cddfSDavid du Colombier static char	*wmagic = WMAGIC;
207dd7cddfSDavid du Colombier static Wren	*wrens;
217dd7cddfSDavid du Colombier static int	maxwren;
227dd7cddfSDavid du Colombier char		*wrenfile;
237dd7cddfSDavid du Colombier int		nwren;
247dd7cddfSDavid du Colombier int		badmagic;
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier static Wren *
wren(Device dev)277dd7cddfSDavid du Colombier wren(Device dev)
287dd7cddfSDavid du Colombier {
297dd7cddfSDavid du Colombier 	int i;
307dd7cddfSDavid du Colombier 
317dd7cddfSDavid du Colombier 	for(i = 0; i < maxwren; i++)
327dd7cddfSDavid du Colombier 		if(devcmp(dev, wrens[i].dev) == 0)
337dd7cddfSDavid du Colombier 			return &wrens[i];
347dd7cddfSDavid du Colombier 	panic("can't find wren for %D", dev);
357dd7cddfSDavid du Colombier 	return 0;
367dd7cddfSDavid du Colombier }
377dd7cddfSDavid du Colombier 
387dd7cddfSDavid du Colombier /*
397dd7cddfSDavid du Colombier  * find out the length of a file
407dd7cddfSDavid du Colombier  * given the mesg version of a stat buffer
417dd7cddfSDavid du Colombier  * we call this because convM2D is different
427dd7cddfSDavid du Colombier  * for the file system than in the os
437dd7cddfSDavid du Colombier  */
447dd7cddfSDavid du Colombier uvlong
statlen(char * ap)457dd7cddfSDavid du Colombier statlen(char *ap)
467dd7cddfSDavid du Colombier {
477dd7cddfSDavid du Colombier 	uchar *p;
487dd7cddfSDavid du Colombier 	ulong ll, hl;
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier 	p = (uchar*)ap;
517dd7cddfSDavid du Colombier 	p += 3*NAMELEN+5*4;
527dd7cddfSDavid du Colombier 	ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
537dd7cddfSDavid du Colombier 	hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
547dd7cddfSDavid du Colombier 	return ll | ((uvlong) hl << 32);
557dd7cddfSDavid du Colombier }
567dd7cddfSDavid du Colombier 
577dd7cddfSDavid du Colombier static void
wrenpartinit(Device dev,int k)587dd7cddfSDavid du Colombier wrenpartinit(Device dev, int k)
597dd7cddfSDavid du Colombier {
60*9a747e4fSDavid du Colombier 	char buf[MAXBUFSIZE], d[DIRREC];
617dd7cddfSDavid du Colombier 	char file[128], magic[64];
627dd7cddfSDavid du Colombier 	Wren *w;
637dd7cddfSDavid du Colombier 	int fd, i, nmagic;
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier 	if(wrens == 0)
667dd7cddfSDavid du Colombier 		wrens = ialloc(MAXWREN * sizeof *wrens);
677dd7cddfSDavid du Colombier 	w = &wrens[maxwren];
687dd7cddfSDavid du Colombier 	if(nwren > 0)
697dd7cddfSDavid du Colombier 		sprint(file, "%s%d", wrenfile, k);
707dd7cddfSDavid du Colombier 	else
717dd7cddfSDavid du Colombier 		strcpy(file, wrenfile);
727dd7cddfSDavid du Colombier 	fd = open(file, ORDWR);
737dd7cddfSDavid du Colombier 	if(fd < 0)
747dd7cddfSDavid du Colombier 		panic("can't open %s", file);
757dd7cddfSDavid du Colombier 	if(fstat(fd, d) < 0)
767dd7cddfSDavid du Colombier 		panic("can't stat %s\n", file);
777dd7cddfSDavid du Colombier 	seek(fd, 0, 0);
787dd7cddfSDavid du Colombier 	i = read(fd, buf, sizeof buf);
797dd7cddfSDavid du Colombier 	if(i < sizeof buf)
807dd7cddfSDavid du Colombier 		panic("can't read %s", file);
817dd7cddfSDavid du Colombier 	badmagic = 0;
827dd7cddfSDavid du Colombier 	RBUFSIZE = 1024;
837dd7cddfSDavid du Colombier 	sprint(magic, wmagic, k, nwren);
847dd7cddfSDavid du Colombier 	nmagic = strlen(magic);
857dd7cddfSDavid du Colombier 	if(strncmp(buf+256, magic, nmagic) == 0){
867dd7cddfSDavid du Colombier 		RBUFSIZE = atol(buf+256+nmagic);
877dd7cddfSDavid du Colombier 		if(RBUFSIZE % 512){
887dd7cddfSDavid du Colombier 			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
897dd7cddfSDavid du Colombier 			RBUFSIZE = 1024;
907dd7cddfSDavid du Colombier 		}
917dd7cddfSDavid du Colombier 	}else
927dd7cddfSDavid du Colombier 		badmagic = 1;
937dd7cddfSDavid du Colombier 	w->dev = dev;
947dd7cddfSDavid du Colombier 	w->nblocks = statlen(d)/RBUFSIZE;
957dd7cddfSDavid du Colombier 	if(k > 0)
967dd7cddfSDavid du Colombier 		w->nblocks -= 1;	/* don't count magic */
977dd7cddfSDavid du Colombier 	w->fd = fd;
987dd7cddfSDavid du Colombier 	maxwren++;
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier 
1017dd7cddfSDavid du Colombier void
wreninit(Device dev)1027dd7cddfSDavid du Colombier wreninit(Device dev)
1037dd7cddfSDavid du Colombier {
1047dd7cddfSDavid du Colombier 	int i;
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier 	if(nwren > 0)
1077dd7cddfSDavid du Colombier 		wmagic = MMAGIC;
1087dd7cddfSDavid du Colombier 	i = 0;
1097dd7cddfSDavid du Colombier 	do{
1107dd7cddfSDavid du Colombier 		wrenpartinit(dev, i);
1117dd7cddfSDavid du Colombier 	}while(++i < nwren);
1127dd7cddfSDavid du Colombier }
1137dd7cddfSDavid du Colombier 
1147dd7cddfSDavid du Colombier static void
wrenpartream(Device dev,int k)1157dd7cddfSDavid du Colombier wrenpartream(Device dev, int k)
1167dd7cddfSDavid du Colombier {
1177dd7cddfSDavid du Colombier 	Wren *w;
118*9a747e4fSDavid du Colombier 	char buf[MAXBUFSIZE], magic[64];
1197dd7cddfSDavid du Colombier 	int fd, i;
1207dd7cddfSDavid du Colombier 
1217dd7cddfSDavid du Colombier 	if(RBUFSIZE % 512)
1227dd7cddfSDavid du Colombier 		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
1237dd7cddfSDavid du Colombier 	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
1247dd7cddfSDavid du Colombier 	w = wren(dev)+k;
1257dd7cddfSDavid du Colombier 	fd = w->fd;
1267dd7cddfSDavid du Colombier 	memset(buf, 0, sizeof buf);
1277dd7cddfSDavid du Colombier 	sprint(magic, wmagic, k, nwren);
1287dd7cddfSDavid du Colombier 	sprint(buf+256, "%s%d\n", magic, RBUFSIZE);
1297dd7cddfSDavid du Colombier 	qlock(w);
1307dd7cddfSDavid du Colombier 	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
1317dd7cddfSDavid du Colombier 	qunlock(w);
1327dd7cddfSDavid du Colombier 	if(i < 0)
1337dd7cddfSDavid du Colombier 		panic("can't ream disk");
1347dd7cddfSDavid du Colombier }
1357dd7cddfSDavid du Colombier 
1367dd7cddfSDavid du Colombier void
wrenream(Device dev)1377dd7cddfSDavid du Colombier wrenream(Device dev)
1387dd7cddfSDavid du Colombier {
1397dd7cddfSDavid du Colombier 	int i;
1407dd7cddfSDavid du Colombier 
1417dd7cddfSDavid du Colombier 	i = 0;
1427dd7cddfSDavid du Colombier 	do{
1437dd7cddfSDavid du Colombier 		wrenpartream(dev, i);
1447dd7cddfSDavid du Colombier 	}while(++i < nwren);
1457dd7cddfSDavid du Colombier }
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier static int
wrentag(char * p,int tag,long qpath)1487dd7cddfSDavid du Colombier wrentag(char *p, int tag, long qpath)
1497dd7cddfSDavid du Colombier {
1507dd7cddfSDavid du Colombier 	Tag *t;
1517dd7cddfSDavid du Colombier 
1527dd7cddfSDavid du Colombier 	t = (Tag*)(p+BUFSIZE);
1537dd7cddfSDavid du Colombier 	return t->tag != tag || (qpath&~QPDIR) != t->path;
1547dd7cddfSDavid du Colombier }
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier int
wrencheck(Device dev)1577dd7cddfSDavid du Colombier wrencheck(Device dev)
1587dd7cddfSDavid du Colombier {
159*9a747e4fSDavid du Colombier 	char buf[MAXBUFSIZE];
1607dd7cddfSDavid du Colombier 
1617dd7cddfSDavid du Colombier 	if(badmagic)
1627dd7cddfSDavid du Colombier 		return 1;
1637dd7cddfSDavid du Colombier 	if(RBUFSIZE > sizeof buf)
1647dd7cddfSDavid du Colombier 		panic("bufsize too big");
1657dd7cddfSDavid du Colombier 	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
1667dd7cddfSDavid du Colombier 	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
1677dd7cddfSDavid du Colombier 		return 1;
1687dd7cddfSDavid du Colombier 	if(((Dentry *)buf)[0].mode & DALLOC)
1697dd7cddfSDavid du Colombier 		return 0;
1707dd7cddfSDavid du Colombier 	return 1;
1717dd7cddfSDavid du Colombier }
1727dd7cddfSDavid du Colombier 
1737dd7cddfSDavid du Colombier long
wrensize(Device dev)1747dd7cddfSDavid du Colombier wrensize(Device dev)
1757dd7cddfSDavid du Colombier {
1767dd7cddfSDavid du Colombier 	Wren *w;
1777dd7cddfSDavid du Colombier 	int i, nb;
1787dd7cddfSDavid du Colombier 
1797dd7cddfSDavid du Colombier 	w = wren(dev);
1807dd7cddfSDavid du Colombier 	nb = 0;
1817dd7cddfSDavid du Colombier 	i = 0;
1827dd7cddfSDavid du Colombier 	do{
1837dd7cddfSDavid du Colombier 		nb += w[i].nblocks;
1847dd7cddfSDavid du Colombier 	}while(++i < nwren);
1857dd7cddfSDavid du Colombier 	return nb;
1867dd7cddfSDavid du Colombier }
1877dd7cddfSDavid du Colombier 
1887dd7cddfSDavid du Colombier long
wrensuper(Device dev)1897dd7cddfSDavid du Colombier wrensuper(Device dev)
1907dd7cddfSDavid du Colombier {
1917dd7cddfSDavid du Colombier 	USED(dev);
1927dd7cddfSDavid du Colombier 	return 1;
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier 
1957dd7cddfSDavid du Colombier long
wrenroot(Device dev)1967dd7cddfSDavid du Colombier wrenroot(Device dev)
1977dd7cddfSDavid du Colombier {
1987dd7cddfSDavid du Colombier 	USED(dev);
1997dd7cddfSDavid du Colombier 	return 2;
2007dd7cddfSDavid du Colombier }
2017dd7cddfSDavid du Colombier 
2027dd7cddfSDavid du Colombier int
wrenread(Device dev,long addr,void * b)2037dd7cddfSDavid du Colombier wrenread(Device dev, long addr, void *b)
2047dd7cddfSDavid du Colombier {
2057dd7cddfSDavid du Colombier 	Wren *w;
2067dd7cddfSDavid du Colombier 	int fd, i;
2077dd7cddfSDavid du Colombier 
2087dd7cddfSDavid du Colombier 	w = wren(dev);
2097dd7cddfSDavid du Colombier 	for(i=0; i<nwren; i++){
2107dd7cddfSDavid du Colombier 		if(addr < w->nblocks)
2117dd7cddfSDavid du Colombier 			break;
2127dd7cddfSDavid du Colombier 		addr -= w->nblocks;
2137dd7cddfSDavid du Colombier 		++w;
2147dd7cddfSDavid du Colombier 	}
2157dd7cddfSDavid du Colombier 	if(i > 0)
2167dd7cddfSDavid du Colombier 		addr++;
2177dd7cddfSDavid du Colombier 	fd = w->fd;
2187dd7cddfSDavid du Colombier 	qlock(w);
2197dd7cddfSDavid du Colombier 	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
2207dd7cddfSDavid du Colombier 	qunlock(w);
2217dd7cddfSDavid du Colombier 	return i;
2227dd7cddfSDavid du Colombier }
2237dd7cddfSDavid du Colombier 
2247dd7cddfSDavid du Colombier int
wrenwrite(Device dev,long addr,void * b)2257dd7cddfSDavid du Colombier wrenwrite(Device dev, long addr, void *b)
2267dd7cddfSDavid du Colombier {
2277dd7cddfSDavid du Colombier 	Wren *w;
2287dd7cddfSDavid du Colombier 	int fd, i;
2297dd7cddfSDavid du Colombier 
2307dd7cddfSDavid du Colombier 	w = wren(dev);
2317dd7cddfSDavid du Colombier 	for(i=0; i<nwren; i++){
2327dd7cddfSDavid du Colombier 		if(addr < w->nblocks)
2337dd7cddfSDavid du Colombier 			break;
2347dd7cddfSDavid du Colombier 		addr -= w->nblocks;
2357dd7cddfSDavid du Colombier 		++w;
2367dd7cddfSDavid du Colombier 	}
2377dd7cddfSDavid du Colombier 	if(i > 0)
2387dd7cddfSDavid du Colombier 		addr++;
2397dd7cddfSDavid du Colombier 	fd = w->fd;
2407dd7cddfSDavid du Colombier 	qlock(w);
2417dd7cddfSDavid du Colombier 	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
2427dd7cddfSDavid du Colombier 	qunlock(w);
2437dd7cddfSDavid du Colombier 	return i;
2447dd7cddfSDavid du Colombier }
245