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