1*7dd7cddfSDavid du Colombier #include "all.h" 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier enum{ 4*7dd7cddfSDavid du Colombier MAXWREN = 7, 5*7dd7cddfSDavid du Colombier }; 6*7dd7cddfSDavid du Colombier 7*7dd7cddfSDavid du Colombier static char WMAGIC[] = "kfs wren device\n"; 8*7dd7cddfSDavid du Colombier static char MMAGIC[] = "kfs multi-wren device %4d/%4d\n"; 9*7dd7cddfSDavid du Colombier 10*7dd7cddfSDavid du Colombier typedef struct Wren Wren; 11*7dd7cddfSDavid du Colombier 12*7dd7cddfSDavid du Colombier struct Wren{ 13*7dd7cddfSDavid du Colombier QLock; 14*7dd7cddfSDavid du Colombier Device dev; 15*7dd7cddfSDavid du Colombier ulong nblocks; 16*7dd7cddfSDavid du Colombier int fd; 17*7dd7cddfSDavid du Colombier }; 18*7dd7cddfSDavid du Colombier 19*7dd7cddfSDavid du Colombier static char *wmagic = WMAGIC; 20*7dd7cddfSDavid du Colombier static Wren *wrens; 21*7dd7cddfSDavid du Colombier static int maxwren; 22*7dd7cddfSDavid du Colombier char *wrenfile; 23*7dd7cddfSDavid du Colombier int nwren; 24*7dd7cddfSDavid du Colombier int badmagic; 25*7dd7cddfSDavid du Colombier 26*7dd7cddfSDavid du Colombier static Wren * 27*7dd7cddfSDavid du Colombier wren(Device dev) 28*7dd7cddfSDavid du Colombier { 29*7dd7cddfSDavid du Colombier int i; 30*7dd7cddfSDavid du Colombier 31*7dd7cddfSDavid du Colombier for(i = 0; i < maxwren; i++) 32*7dd7cddfSDavid du Colombier if(devcmp(dev, wrens[i].dev) == 0) 33*7dd7cddfSDavid du Colombier return &wrens[i]; 34*7dd7cddfSDavid du Colombier panic("can't find wren for %D", dev); 35*7dd7cddfSDavid du Colombier return 0; 36*7dd7cddfSDavid du Colombier } 37*7dd7cddfSDavid du Colombier 38*7dd7cddfSDavid du Colombier /* 39*7dd7cddfSDavid du Colombier * find out the length of a file 40*7dd7cddfSDavid du Colombier * given the mesg version of a stat buffer 41*7dd7cddfSDavid du Colombier * we call this because convM2D is different 42*7dd7cddfSDavid du Colombier * for the file system than in the os 43*7dd7cddfSDavid du Colombier */ 44*7dd7cddfSDavid du Colombier uvlong 45*7dd7cddfSDavid du Colombier statlen(char *ap) 46*7dd7cddfSDavid du Colombier { 47*7dd7cddfSDavid du Colombier uchar *p; 48*7dd7cddfSDavid du Colombier ulong ll, hl; 49*7dd7cddfSDavid du Colombier 50*7dd7cddfSDavid du Colombier p = (uchar*)ap; 51*7dd7cddfSDavid du Colombier p += 3*NAMELEN+5*4; 52*7dd7cddfSDavid du Colombier ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); 53*7dd7cddfSDavid du Colombier hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24); 54*7dd7cddfSDavid du Colombier return ll | ((uvlong) hl << 32); 55*7dd7cddfSDavid du Colombier } 56*7dd7cddfSDavid du Colombier 57*7dd7cddfSDavid du Colombier static void 58*7dd7cddfSDavid du Colombier wrenpartinit(Device dev, int k) 59*7dd7cddfSDavid du Colombier { 60*7dd7cddfSDavid du Colombier char buf[8*1024], d[DIRREC]; 61*7dd7cddfSDavid du Colombier char file[128], magic[64]; 62*7dd7cddfSDavid du Colombier Wren *w; 63*7dd7cddfSDavid du Colombier int fd, i, nmagic; 64*7dd7cddfSDavid du Colombier 65*7dd7cddfSDavid du Colombier if(wrens == 0) 66*7dd7cddfSDavid du Colombier wrens = ialloc(MAXWREN * sizeof *wrens); 67*7dd7cddfSDavid du Colombier w = &wrens[maxwren]; 68*7dd7cddfSDavid du Colombier if(nwren > 0) 69*7dd7cddfSDavid du Colombier sprint(file, "%s%d", wrenfile, k); 70*7dd7cddfSDavid du Colombier else 71*7dd7cddfSDavid du Colombier strcpy(file, wrenfile); 72*7dd7cddfSDavid du Colombier fd = open(file, ORDWR); 73*7dd7cddfSDavid du Colombier if(fd < 0) 74*7dd7cddfSDavid du Colombier panic("can't open %s", file); 75*7dd7cddfSDavid du Colombier if(fstat(fd, d) < 0) 76*7dd7cddfSDavid du Colombier panic("can't stat %s\n", file); 77*7dd7cddfSDavid du Colombier seek(fd, 0, 0); 78*7dd7cddfSDavid du Colombier i = read(fd, buf, sizeof buf); 79*7dd7cddfSDavid du Colombier if(i < sizeof buf) 80*7dd7cddfSDavid du Colombier panic("can't read %s", file); 81*7dd7cddfSDavid du Colombier badmagic = 0; 82*7dd7cddfSDavid du Colombier RBUFSIZE = 1024; 83*7dd7cddfSDavid du Colombier sprint(magic, wmagic, k, nwren); 84*7dd7cddfSDavid du Colombier nmagic = strlen(magic); 85*7dd7cddfSDavid du Colombier if(strncmp(buf+256, magic, nmagic) == 0){ 86*7dd7cddfSDavid du Colombier RBUFSIZE = atol(buf+256+nmagic); 87*7dd7cddfSDavid du Colombier if(RBUFSIZE % 512){ 88*7dd7cddfSDavid du Colombier fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE); 89*7dd7cddfSDavid du Colombier RBUFSIZE = 1024; 90*7dd7cddfSDavid du Colombier } 91*7dd7cddfSDavid du Colombier }else 92*7dd7cddfSDavid du Colombier badmagic = 1; 93*7dd7cddfSDavid du Colombier w->dev = dev; 94*7dd7cddfSDavid du Colombier w->nblocks = statlen(d)/RBUFSIZE; 95*7dd7cddfSDavid du Colombier if(k > 0) 96*7dd7cddfSDavid du Colombier w->nblocks -= 1; /* don't count magic */ 97*7dd7cddfSDavid du Colombier w->fd = fd; 98*7dd7cddfSDavid du Colombier maxwren++; 99*7dd7cddfSDavid du Colombier } 100*7dd7cddfSDavid du Colombier 101*7dd7cddfSDavid du Colombier void 102*7dd7cddfSDavid du Colombier wreninit(Device dev) 103*7dd7cddfSDavid du Colombier { 104*7dd7cddfSDavid du Colombier int i; 105*7dd7cddfSDavid du Colombier 106*7dd7cddfSDavid du Colombier if(nwren > 0) 107*7dd7cddfSDavid du Colombier wmagic = MMAGIC; 108*7dd7cddfSDavid du Colombier i = 0; 109*7dd7cddfSDavid du Colombier do{ 110*7dd7cddfSDavid du Colombier wrenpartinit(dev, i); 111*7dd7cddfSDavid du Colombier }while(++i < nwren); 112*7dd7cddfSDavid du Colombier } 113*7dd7cddfSDavid du Colombier 114*7dd7cddfSDavid du Colombier static void 115*7dd7cddfSDavid du Colombier wrenpartream(Device dev, int k) 116*7dd7cddfSDavid du Colombier { 117*7dd7cddfSDavid du Colombier Wren *w; 118*7dd7cddfSDavid du Colombier char buf[8*1024], magic[64]; 119*7dd7cddfSDavid du Colombier int fd, i; 120*7dd7cddfSDavid du Colombier 121*7dd7cddfSDavid du Colombier if(RBUFSIZE % 512) 122*7dd7cddfSDavid du Colombier panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE); 123*7dd7cddfSDavid du Colombier print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE); 124*7dd7cddfSDavid du Colombier w = wren(dev)+k; 125*7dd7cddfSDavid du Colombier fd = w->fd; 126*7dd7cddfSDavid du Colombier memset(buf, 0, sizeof buf); 127*7dd7cddfSDavid du Colombier sprint(magic, wmagic, k, nwren); 128*7dd7cddfSDavid du Colombier sprint(buf+256, "%s%d\n", magic, RBUFSIZE); 129*7dd7cddfSDavid du Colombier qlock(w); 130*7dd7cddfSDavid du Colombier i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE; 131*7dd7cddfSDavid du Colombier qunlock(w); 132*7dd7cddfSDavid du Colombier if(i < 0) 133*7dd7cddfSDavid du Colombier panic("can't ream disk"); 134*7dd7cddfSDavid du Colombier } 135*7dd7cddfSDavid du Colombier 136*7dd7cddfSDavid du Colombier void 137*7dd7cddfSDavid du Colombier wrenream(Device dev) 138*7dd7cddfSDavid du Colombier { 139*7dd7cddfSDavid du Colombier int i; 140*7dd7cddfSDavid du Colombier 141*7dd7cddfSDavid du Colombier i = 0; 142*7dd7cddfSDavid du Colombier do{ 143*7dd7cddfSDavid du Colombier wrenpartream(dev, i); 144*7dd7cddfSDavid du Colombier }while(++i < nwren); 145*7dd7cddfSDavid du Colombier } 146*7dd7cddfSDavid du Colombier 147*7dd7cddfSDavid du Colombier static int 148*7dd7cddfSDavid du Colombier wrentag(char *p, int tag, long qpath) 149*7dd7cddfSDavid du Colombier { 150*7dd7cddfSDavid du Colombier Tag *t; 151*7dd7cddfSDavid du Colombier 152*7dd7cddfSDavid du Colombier t = (Tag*)(p+BUFSIZE); 153*7dd7cddfSDavid du Colombier return t->tag != tag || (qpath&~QPDIR) != t->path; 154*7dd7cddfSDavid du Colombier } 155*7dd7cddfSDavid du Colombier 156*7dd7cddfSDavid du Colombier int 157*7dd7cddfSDavid du Colombier wrencheck(Device dev) 158*7dd7cddfSDavid du Colombier { 159*7dd7cddfSDavid du Colombier char buf[8*1024]; 160*7dd7cddfSDavid du Colombier 161*7dd7cddfSDavid du Colombier if(badmagic) 162*7dd7cddfSDavid du Colombier return 1; 163*7dd7cddfSDavid du Colombier if(RBUFSIZE > sizeof buf) 164*7dd7cddfSDavid du Colombier panic("bufsize too big"); 165*7dd7cddfSDavid du Colombier if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER) 166*7dd7cddfSDavid du Colombier || wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT)) 167*7dd7cddfSDavid du Colombier return 1; 168*7dd7cddfSDavid du Colombier if(((Dentry *)buf)[0].mode & DALLOC) 169*7dd7cddfSDavid du Colombier return 0; 170*7dd7cddfSDavid du Colombier return 1; 171*7dd7cddfSDavid du Colombier } 172*7dd7cddfSDavid du Colombier 173*7dd7cddfSDavid du Colombier long 174*7dd7cddfSDavid du Colombier wrensize(Device dev) 175*7dd7cddfSDavid du Colombier { 176*7dd7cddfSDavid du Colombier Wren *w; 177*7dd7cddfSDavid du Colombier int i, nb; 178*7dd7cddfSDavid du Colombier 179*7dd7cddfSDavid du Colombier w = wren(dev); 180*7dd7cddfSDavid du Colombier nb = 0; 181*7dd7cddfSDavid du Colombier i = 0; 182*7dd7cddfSDavid du Colombier do{ 183*7dd7cddfSDavid du Colombier nb += w[i].nblocks; 184*7dd7cddfSDavid du Colombier }while(++i < nwren); 185*7dd7cddfSDavid du Colombier return nb; 186*7dd7cddfSDavid du Colombier } 187*7dd7cddfSDavid du Colombier 188*7dd7cddfSDavid du Colombier long 189*7dd7cddfSDavid du Colombier wrensuper(Device dev) 190*7dd7cddfSDavid du Colombier { 191*7dd7cddfSDavid du Colombier USED(dev); 192*7dd7cddfSDavid du Colombier return 1; 193*7dd7cddfSDavid du Colombier } 194*7dd7cddfSDavid du Colombier 195*7dd7cddfSDavid du Colombier long 196*7dd7cddfSDavid du Colombier wrenroot(Device dev) 197*7dd7cddfSDavid du Colombier { 198*7dd7cddfSDavid du Colombier USED(dev); 199*7dd7cddfSDavid du Colombier return 2; 200*7dd7cddfSDavid du Colombier } 201*7dd7cddfSDavid du Colombier 202*7dd7cddfSDavid du Colombier int 203*7dd7cddfSDavid du Colombier wrenread(Device dev, long addr, void *b) 204*7dd7cddfSDavid du Colombier { 205*7dd7cddfSDavid du Colombier Wren *w; 206*7dd7cddfSDavid du Colombier int fd, i; 207*7dd7cddfSDavid du Colombier 208*7dd7cddfSDavid du Colombier w = wren(dev); 209*7dd7cddfSDavid du Colombier for(i=0; i<nwren; i++){ 210*7dd7cddfSDavid du Colombier if(addr < w->nblocks) 211*7dd7cddfSDavid du Colombier break; 212*7dd7cddfSDavid du Colombier addr -= w->nblocks; 213*7dd7cddfSDavid du Colombier ++w; 214*7dd7cddfSDavid du Colombier } 215*7dd7cddfSDavid du Colombier if(i > 0) 216*7dd7cddfSDavid du Colombier addr++; 217*7dd7cddfSDavid du Colombier fd = w->fd; 218*7dd7cddfSDavid du Colombier qlock(w); 219*7dd7cddfSDavid du Colombier i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE; 220*7dd7cddfSDavid du Colombier qunlock(w); 221*7dd7cddfSDavid du Colombier return i; 222*7dd7cddfSDavid du Colombier } 223*7dd7cddfSDavid du Colombier 224*7dd7cddfSDavid du Colombier int 225*7dd7cddfSDavid du Colombier wrenwrite(Device dev, long addr, void *b) 226*7dd7cddfSDavid du Colombier { 227*7dd7cddfSDavid du Colombier Wren *w; 228*7dd7cddfSDavid du Colombier int fd, i; 229*7dd7cddfSDavid du Colombier 230*7dd7cddfSDavid du Colombier w = wren(dev); 231*7dd7cddfSDavid du Colombier for(i=0; i<nwren; i++){ 232*7dd7cddfSDavid du Colombier if(addr < w->nblocks) 233*7dd7cddfSDavid du Colombier break; 234*7dd7cddfSDavid du Colombier addr -= w->nblocks; 235*7dd7cddfSDavid du Colombier ++w; 236*7dd7cddfSDavid du Colombier } 237*7dd7cddfSDavid du Colombier if(i > 0) 238*7dd7cddfSDavid du Colombier addr++; 239*7dd7cddfSDavid du Colombier fd = w->fd; 240*7dd7cddfSDavid du Colombier qlock(w); 241*7dd7cddfSDavid du Colombier i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE; 242*7dd7cddfSDavid du Colombier qunlock(w); 243*7dd7cddfSDavid du Colombier return i; 244*7dd7cddfSDavid du Colombier } 245