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