13e12c5d1SDavid du Colombier #include "all.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier int sfd; 43e12c5d1SDavid du Colombier int rfd; 53e12c5d1SDavid du Colombier int chat; 63e12c5d1SDavid du Colombier extern char *wrenfile; 73e12c5d1SDavid du Colombier char *myname; 83e12c5d1SDavid du Colombier int cmdfd; 9bd389b36SDavid du Colombier int writeallow; /* never on; for compatibility with fs */ 10bd389b36SDavid du Colombier int wstatallow; 113e12c5d1SDavid du Colombier int srvfd(char*, int); 123e12c5d1SDavid du Colombier void usage(void); 133e12c5d1SDavid du Colombier void confinit(void); 143e12c5d1SDavid du Colombier Chan *chaninit(char*); 153e12c5d1SDavid du Colombier void consinit(void); 163e12c5d1SDavid du Colombier 173e12c5d1SDavid du Colombier void 183e12c5d1SDavid du Colombier main(int argc, char *argv[]) 193e12c5d1SDavid du Colombier { 203e12c5d1SDavid du Colombier Filsys *fs; 21*219b2ee8SDavid du Colombier int i, ream, fsok; 223e12c5d1SDavid du Colombier int newbufsize, nocheck; 233e12c5d1SDavid du Colombier char buf[NAMELEN]; 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier progname = "kfs"; 263e12c5d1SDavid du Colombier procname = "init"; 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier /* 293e12c5d1SDavid du Colombier * insulate from invokers environment 303e12c5d1SDavid du Colombier */ 313e12c5d1SDavid du Colombier rfork(RFNAMEG|RFNOTEG); 323e12c5d1SDavid du Colombier 333e12c5d1SDavid du Colombier confinit(); 343e12c5d1SDavid du Colombier sfd = -1; 353e12c5d1SDavid du Colombier ream = 0; 363e12c5d1SDavid du Colombier newbufsize = 0; 373e12c5d1SDavid du Colombier nocheck = 0; 38*219b2ee8SDavid du Colombier wrenfile = "/dev/sd0fs"; 393e12c5d1SDavid du Colombier buf[0] = '\0'; 403e12c5d1SDavid du Colombier ARGBEGIN{ 413e12c5d1SDavid du Colombier case 'b': 423e12c5d1SDavid du Colombier newbufsize = atol(ARGF()); 433e12c5d1SDavid du Colombier break; 443e12c5d1SDavid du Colombier case 'c': 453e12c5d1SDavid du Colombier nocheck = 1; 463e12c5d1SDavid du Colombier break; 473e12c5d1SDavid du Colombier case 'f': 483e12c5d1SDavid du Colombier wrenfile = ARGF(); 493e12c5d1SDavid du Colombier break; 503e12c5d1SDavid du Colombier case 'n': 513e12c5d1SDavid du Colombier strncpy(buf, ARGF(), NAMELEN-1); 523e12c5d1SDavid du Colombier buf[NAMELEN-1] = '\0'; 533e12c5d1SDavid du Colombier break; 543e12c5d1SDavid du Colombier case 'r': 553e12c5d1SDavid du Colombier ream = 1; 563e12c5d1SDavid du Colombier break; 573e12c5d1SDavid du Colombier case 's': 583e12c5d1SDavid du Colombier sfd = 0; 593e12c5d1SDavid du Colombier rfd = 1; 603e12c5d1SDavid du Colombier break; 61*219b2ee8SDavid du Colombier case 'B': 62*219b2ee8SDavid du Colombier conf.niobuf = strtoul(ARGF(), 0, 0); 63*219b2ee8SDavid du Colombier break; 643e12c5d1SDavid du Colombier case 'C': 653e12c5d1SDavid du Colombier chat = 1; 663e12c5d1SDavid du Colombier break; 673e12c5d1SDavid du Colombier default: 683e12c5d1SDavid du Colombier usage(); 693e12c5d1SDavid du Colombier }ARGEND 703e12c5d1SDavid du Colombier USED(argc, argv); 713e12c5d1SDavid du Colombier 72bd389b36SDavid du Colombier cmdfd = 2; 733e12c5d1SDavid du Colombier 743e12c5d1SDavid du Colombier formatinit(); 753e12c5d1SDavid du Colombier lockinit(); 763e12c5d1SDavid du Colombier lock(&newfplock); 773e12c5d1SDavid du Colombier unlock(&newfplock); 783e12c5d1SDavid du Colombier 793e12c5d1SDavid du Colombier if(buf[0]) 803e12c5d1SDavid du Colombier sprint(service, "kfs.%s", buf); 813e12c5d1SDavid du Colombier else 823e12c5d1SDavid du Colombier strcpy(service, "kfs"); 833e12c5d1SDavid du Colombier chan = chaninit(service); 843e12c5d1SDavid du Colombier consinit(); 853e12c5d1SDavid du Colombier files = ialloc(conf.nfile * sizeof(*files)); 863e12c5d1SDavid du Colombier for(i=0; i<conf.nfile; i++) { 873e12c5d1SDavid du Colombier qlock(&files[i]); 883e12c5d1SDavid du Colombier qunlock(&files[i]); 893e12c5d1SDavid du Colombier } 903e12c5d1SDavid du Colombier tlocks = ialloc(NTLOCK * sizeof *tlocks); 913e12c5d1SDavid du Colombier wpaths = ialloc(conf.nwpath * sizeof(*wpaths)); 923e12c5d1SDavid du Colombier uid = ialloc(conf.nuid * sizeof(*uid)); 933e12c5d1SDavid du Colombier uidspace = ialloc(conf.uidspace * sizeof(*uidspace)); 943e12c5d1SDavid du Colombier gidspace = ialloc(conf.gidspace * sizeof(*gidspace)); 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier /* 973e12c5d1SDavid du Colombier * init global locks 983e12c5d1SDavid du Colombier */ 993e12c5d1SDavid du Colombier wlock(&mainlock); wunlock(&mainlock); 1003e12c5d1SDavid du Colombier lock(&wpathlock); unlock(&wpathlock); 1013e12c5d1SDavid du Colombier 1023e12c5d1SDavid du Colombier /* 1033e12c5d1SDavid du Colombier * init the file system, ream it if needed, and get the block sizes 1043e12c5d1SDavid du Colombier */ 1053e12c5d1SDavid du Colombier ream = fsinit(ream, newbufsize); 1063e12c5d1SDavid du Colombier iobufinit(); 1073e12c5d1SDavid du Colombier for(fs=filsys; fs->name; fs++) 1083e12c5d1SDavid du Colombier if(fs->flags & FREAM){ /* set by fsinit if reamed */ 1093e12c5d1SDavid du Colombier ream++; 1103e12c5d1SDavid du Colombier rootream(fs->dev, getraddr(fs->dev)); 1113e12c5d1SDavid du Colombier superream(fs->dev, superaddr(fs->dev)); 1123e12c5d1SDavid du Colombier } 1133e12c5d1SDavid du Colombier 1143e12c5d1SDavid du Colombier boottime = time(); 1153e12c5d1SDavid du Colombier 1163e12c5d1SDavid du Colombier consserve(); 117*219b2ee8SDavid du Colombier fsok = superok(filsys[0].dev, superaddr(filsys[0].dev), 0); 118*219b2ee8SDavid du Colombier if(!nocheck && !ream && !fsok) 1193e12c5d1SDavid du Colombier cmd_exec("check fq"); 1203e12c5d1SDavid du Colombier 1213e12c5d1SDavid du Colombier /* 1223e12c5d1SDavid du Colombier * start up procs 1233e12c5d1SDavid du Colombier */ 1243e12c5d1SDavid du Colombier for(i=0; i<conf.nserve; i++) 1253e12c5d1SDavid du Colombier startproc(serve, "srv"); 1263e12c5d1SDavid du Colombier 1273e12c5d1SDavid du Colombier startproc(syncproc, "sync"); 1283e12c5d1SDavid du Colombier 1293e12c5d1SDavid du Colombier exits(0); 1303e12c5d1SDavid du Colombier } 1313e12c5d1SDavid du Colombier 1323e12c5d1SDavid du Colombier Chan * 1333e12c5d1SDavid du Colombier getmsg(char *buf, Fcall *f, int *n) 1343e12c5d1SDavid du Colombier { 1353e12c5d1SDavid du Colombier int fd; 1363e12c5d1SDavid du Colombier 1373e12c5d1SDavid du Colombier fd = chan->chan; 1383e12c5d1SDavid du Colombier for(;;){ 1393e12c5d1SDavid du Colombier *n = read(fd, buf, MAXMSG + MAXDAT); 140*219b2ee8SDavid du Colombier if(chat) 141*219b2ee8SDavid du Colombier print("read msg %d\n", *n); 1423e12c5d1SDavid du Colombier if(*n == 0){ 1433e12c5d1SDavid du Colombier continue; 1443e12c5d1SDavid du Colombier } 1453e12c5d1SDavid du Colombier if(*n < 0) 1463e12c5d1SDavid du Colombier return 0; 1473e12c5d1SDavid du Colombier if(convM2S(buf, f, *n)) 1483e12c5d1SDavid du Colombier return chan; 149*219b2ee8SDavid du Colombier if(chat) 150*219b2ee8SDavid du Colombier print("bad convM2S\n"); 1513e12c5d1SDavid du Colombier } 152*219b2ee8SDavid du Colombier return 0; 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier 1553e12c5d1SDavid du Colombier void 1563e12c5d1SDavid du Colombier send(Chan *c, char *buf, int n) 1573e12c5d1SDavid du Colombier { 1583e12c5d1SDavid du Colombier int fd, m; 1593e12c5d1SDavid du Colombier 1603e12c5d1SDavid du Colombier fd = c->chan; 1613e12c5d1SDavid du Colombier for(;;){ 1623e12c5d1SDavid du Colombier m = write(fd, buf, n); 1633e12c5d1SDavid du Colombier if(m == n) 1643e12c5d1SDavid du Colombier return; 1653e12c5d1SDavid du Colombier } 1663e12c5d1SDavid du Colombier } 1673e12c5d1SDavid du Colombier 1683e12c5d1SDavid du Colombier /* 1693e12c5d1SDavid du Colombier * main filesystem server loop. 1703e12c5d1SDavid du Colombier * entered by many processes. 1713e12c5d1SDavid du Colombier * they wait for messages and 1723e12c5d1SDavid du Colombier * then process them. 1733e12c5d1SDavid du Colombier */ 1743e12c5d1SDavid du Colombier void 1753e12c5d1SDavid du Colombier serve(void) 1763e12c5d1SDavid du Colombier { 1773e12c5d1SDavid du Colombier Chan *cp; 1783e12c5d1SDavid du Colombier Fcall fi, fo; 1793e12c5d1SDavid du Colombier char msgbuf[MAXMSG + MAXDAT]; 1803e12c5d1SDavid du Colombier int t, n; 1813e12c5d1SDavid du Colombier 1823e12c5d1SDavid du Colombier loop: 1833e12c5d1SDavid du Colombier cp = getmsg(msgbuf, &fi, &n); 1843e12c5d1SDavid du Colombier if(!cp) 1853e12c5d1SDavid du Colombier panic("input channel read error"); 1863e12c5d1SDavid du Colombier 1873e12c5d1SDavid du Colombier /* 1883e12c5d1SDavid du Colombier * simple syntax checks. 1893e12c5d1SDavid du Colombier */ 1903e12c5d1SDavid du Colombier t = fi.type; 1913e12c5d1SDavid du Colombier if(t < 0 || t >= MAXSYSCALL || (t&1) || !p9call[t]){ 1923e12c5d1SDavid du Colombier print("bad message type\n"); 1933e12c5d1SDavid du Colombier fo.tag = fi.tag; 1943e12c5d1SDavid du Colombier fo.type = Terror+1; 1953e12c5d1SDavid du Colombier strncpy(fo.ename, "unknown message type", sizeof(fo.ename)); 1963e12c5d1SDavid du Colombier goto reply; 1973e12c5d1SDavid du Colombier } 1983e12c5d1SDavid du Colombier 1993e12c5d1SDavid du Colombier /* 2003e12c5d1SDavid du Colombier * set up reply message 2013e12c5d1SDavid du Colombier */ 2023e12c5d1SDavid du Colombier fo.err = 0; 2033e12c5d1SDavid du Colombier if(t == Tread) 2043e12c5d1SDavid du Colombier fo.data = msgbuf + 8; 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier /* 2073e12c5d1SDavid du Colombier * stats 2083e12c5d1SDavid du Colombier */ 2093e12c5d1SDavid du Colombier cons.work.count++; 2103e12c5d1SDavid du Colombier cons.rate.count += n; 2113e12c5d1SDavid du Colombier 2123e12c5d1SDavid du Colombier /* 2133e12c5d1SDavid du Colombier * call the file system 2143e12c5d1SDavid du Colombier */ 2153e12c5d1SDavid du Colombier rlock(&mainlock); 2163e12c5d1SDavid du Colombier rlock(&cp->reflock); 2173e12c5d1SDavid du Colombier 2183e12c5d1SDavid du Colombier (*p9call[t])(cp, &fi, &fo); 2193e12c5d1SDavid du Colombier 2203e12c5d1SDavid du Colombier runlock(&cp->reflock); 2213e12c5d1SDavid du Colombier runlock(&mainlock); 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier fo.type = t + 1; 2243e12c5d1SDavid du Colombier fo.tag = fi.tag; 2253e12c5d1SDavid du Colombier 2263e12c5d1SDavid du Colombier if(fo.err) { 2273e12c5d1SDavid du Colombier if(CHAT(cp)) 2283e12c5d1SDavid du Colombier print(" error: %s\n", errstr[fo.err]); 2293e12c5d1SDavid du Colombier fo.type = Terror+1; 2303e12c5d1SDavid du Colombier strncpy(fo.ename, errstr[fo.err], sizeof(fo.ename)); 2313e12c5d1SDavid du Colombier } 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier reply: 2343e12c5d1SDavid du Colombier n = convS2M(&fo, msgbuf); 2353e12c5d1SDavid du Colombier if(!n) { 2363e12c5d1SDavid du Colombier print("bad S2M conversion\n"); 2373e12c5d1SDavid du Colombier print("type=%d count=%d\n", msgbuf[0], n); 2383e12c5d1SDavid du Colombier print(" %.2x %.2x %.2x %.2x\n", 2393e12c5d1SDavid du Colombier msgbuf[1]&0xff, msgbuf[2]&0xff, 2403e12c5d1SDavid du Colombier msgbuf[3]&0xff, msgbuf[4]&0xff); 2413e12c5d1SDavid du Colombier print(" %.2x %.2x %.2x %.2x\n", 2423e12c5d1SDavid du Colombier msgbuf[5]&0xff, msgbuf[6]&0xff, 2433e12c5d1SDavid du Colombier msgbuf[7]&0xff, msgbuf[8]&0xff); 2443e12c5d1SDavid du Colombier print(" %.2x %.2x %.2x %.2x\n", 2453e12c5d1SDavid du Colombier msgbuf[9]&0xff, msgbuf[10]&0xff, 2463e12c5d1SDavid du Colombier msgbuf[11]&0xff, msgbuf[12]&0xff); 2473e12c5d1SDavid du Colombier }else{ 2483e12c5d1SDavid du Colombier send(cp, msgbuf, n); 2493e12c5d1SDavid du Colombier cons.rate.count += n; 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier goto loop; 2523e12c5d1SDavid du Colombier } 2533e12c5d1SDavid du Colombier 2543e12c5d1SDavid du Colombier static 2553e12c5d1SDavid du Colombier struct 2563e12c5d1SDavid du Colombier { 2573e12c5d1SDavid du Colombier int nfilter; 2583e12c5d1SDavid du Colombier Filter* filters[100]; 2593e12c5d1SDavid du Colombier }f; 2603e12c5d1SDavid du Colombier 2613e12c5d1SDavid du Colombier void 2623e12c5d1SDavid du Colombier catchalarm(void *regs, char *msg) 2633e12c5d1SDavid du Colombier { 2643e12c5d1SDavid du Colombier USED(regs, msg); 2653e12c5d1SDavid du Colombier if(strcmp(msg, "alarm") == 0) 2663e12c5d1SDavid du Colombier noted(NCONT); 2673e12c5d1SDavid du Colombier else 2683e12c5d1SDavid du Colombier noted(NDFLT); 2693e12c5d1SDavid du Colombier } 2703e12c5d1SDavid du Colombier 2713e12c5d1SDavid du Colombier /* 2723e12c5d1SDavid du Colombier * process to synch blocks 2733e12c5d1SDavid du Colombier * it puts out a block/line every second 2743e12c5d1SDavid du Colombier * it waits 10 seconds if catches up. 2753e12c5d1SDavid du Colombier * in both cases, it takes about 10 seconds 2763e12c5d1SDavid du Colombier * to get up-to-date. 2773e12c5d1SDavid du Colombier * 2783e12c5d1SDavid du Colombier * it also updates the filter stats 2793e12c5d1SDavid du Colombier * and executes commands 2803e12c5d1SDavid du Colombier */ 2813e12c5d1SDavid du Colombier void 2823e12c5d1SDavid du Colombier syncproc(void) 2833e12c5d1SDavid du Colombier { 2843e12c5d1SDavid du Colombier char buf[4*1024]; 2853e12c5d1SDavid du Colombier Filter *ft; 2863e12c5d1SDavid du Colombier ulong c0, c1; 2873e12c5d1SDavid du Colombier long t, n, d; 2883e12c5d1SDavid du Colombier int i, p[2]; 2893e12c5d1SDavid du Colombier 2903e12c5d1SDavid du Colombier /* 2913e12c5d1SDavid du Colombier * make a pipe for commands 2923e12c5d1SDavid du Colombier */ 2933e12c5d1SDavid du Colombier if(pipe(p) < 0) 2943e12c5d1SDavid du Colombier panic("command pipe"); 2953e12c5d1SDavid du Colombier sprint(buf, "#s/%s.cmd", service); 2963e12c5d1SDavid du Colombier srvfd(buf, p[0]); 2973e12c5d1SDavid du Colombier close(p[0]); 2983e12c5d1SDavid du Colombier cmdfd = p[1]; 2993e12c5d1SDavid du Colombier notify(catchalarm); 3003e12c5d1SDavid du Colombier 3013e12c5d1SDavid du Colombier t = time(); 3023e12c5d1SDavid du Colombier for(;;){ 3033e12c5d1SDavid du Colombier i = syncblock(); 3043e12c5d1SDavid du Colombier alarm(i ? 1000: 10000); 3053e12c5d1SDavid du Colombier n = read(cmdfd, buf, sizeof buf - 1); 3063e12c5d1SDavid du Colombier alarm(0); 3073e12c5d1SDavid du Colombier if(n > 0){ 3083e12c5d1SDavid du Colombier buf[n] = '\0'; 3093e12c5d1SDavid du Colombier if(cmd_exec(buf)) 3103e12c5d1SDavid du Colombier fprint(cmdfd, "done"); 3113e12c5d1SDavid du Colombier else 3123e12c5d1SDavid du Colombier fprint(cmdfd, "unknown command"); 3133e12c5d1SDavid du Colombier } 3143e12c5d1SDavid du Colombier n = time(); 3153e12c5d1SDavid du Colombier d = n - t; 3163e12c5d1SDavid du Colombier if(d < 0 || d > 5*60) 3173e12c5d1SDavid du Colombier d = 0; 3183e12c5d1SDavid du Colombier while(d >= 1) { 3193e12c5d1SDavid du Colombier d -= 1; 3203e12c5d1SDavid du Colombier for(i=0; i<f.nfilter; i++) { 3213e12c5d1SDavid du Colombier ft = f.filters[i]; 3223e12c5d1SDavid du Colombier c0 = ft->count; 3233e12c5d1SDavid du Colombier c1 = c0 - ft->oldcount; 3243e12c5d1SDavid du Colombier ft->oldcount = c0; 3253e12c5d1SDavid du Colombier ft->filter[0] = famd(ft->filter[0], c1, 59, 60); 3263e12c5d1SDavid du Colombier ft->filter[1] = famd(ft->filter[1], c1, 599, 600); 3273e12c5d1SDavid du Colombier ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000); 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier } 3303e12c5d1SDavid du Colombier t = n; 3313e12c5d1SDavid du Colombier } 3323e12c5d1SDavid du Colombier } 3333e12c5d1SDavid du Colombier 3343e12c5d1SDavid du Colombier void 3353e12c5d1SDavid du Colombier dofilter(Filter *ft) 3363e12c5d1SDavid du Colombier { 3373e12c5d1SDavid du Colombier int i; 3383e12c5d1SDavid du Colombier 3393e12c5d1SDavid du Colombier i = f.nfilter; 3403e12c5d1SDavid du Colombier if(i >= sizeof f.filters / sizeof f.filters[0]) { 3413e12c5d1SDavid du Colombier print("dofilter: too many filters\n"); 3423e12c5d1SDavid du Colombier return; 3433e12c5d1SDavid du Colombier } 3443e12c5d1SDavid du Colombier f.filters[i] = ft; 3453e12c5d1SDavid du Colombier f.nfilter = i+1; 3463e12c5d1SDavid du Colombier } 3473e12c5d1SDavid du Colombier 3483e12c5d1SDavid du Colombier void 3493e12c5d1SDavid du Colombier startproc(void (*f)(void), char *name) 3503e12c5d1SDavid du Colombier { 3513e12c5d1SDavid du Colombier switch(rfork(RFMEM|RFFDG|RFPROC)){ 3523e12c5d1SDavid du Colombier case -1: 3533e12c5d1SDavid du Colombier panic("can't fork"); 3543e12c5d1SDavid du Colombier case 0: 3553e12c5d1SDavid du Colombier break; 3563e12c5d1SDavid du Colombier default: 3573e12c5d1SDavid du Colombier return; 3583e12c5d1SDavid du Colombier } 3593e12c5d1SDavid du Colombier procname = name; 3603e12c5d1SDavid du Colombier f(); 3613e12c5d1SDavid du Colombier } 3623e12c5d1SDavid du Colombier 3633e12c5d1SDavid du Colombier void 3643e12c5d1SDavid du Colombier confinit(void) 3653e12c5d1SDavid du Colombier { 3663e12c5d1SDavid du Colombier int mul; 3673e12c5d1SDavid du Colombier 368*219b2ee8SDavid du Colombier conf.niobuf = 0; 3693e12c5d1SDavid du Colombier conf.nuid = 300; 3703e12c5d1SDavid du Colombier conf.nserve = 2; 3713e12c5d1SDavid du Colombier conf.uidspace = conf.nuid*6; 3723e12c5d1SDavid du Colombier conf.gidspace = conf.nuid*3; 3733e12c5d1SDavid du Colombier 3743e12c5d1SDavid du Colombier /* 3753e12c5d1SDavid du Colombier * nfile should be close to conf.nchan for kernel 3763e12c5d1SDavid du Colombier */ 3773e12c5d1SDavid du Colombier mul = 1; 3783e12c5d1SDavid du Colombier conf.nfile = 250*mul; 3793e12c5d1SDavid du Colombier conf.nwpath = conf.nfile*8; 3803e12c5d1SDavid du Colombier 3813e12c5d1SDavid du Colombier cons.flags = 0; 3823e12c5d1SDavid du Colombier } 3833e12c5d1SDavid du Colombier 3843e12c5d1SDavid du Colombier Chan* 3853e12c5d1SDavid du Colombier chaninit(char *server) 3863e12c5d1SDavid du Colombier { 3873e12c5d1SDavid du Colombier Chan *cp; 3883e12c5d1SDavid du Colombier char buf[3*NAMELEN]; 3893e12c5d1SDavid du Colombier int p[2]; 3903e12c5d1SDavid du Colombier 3913e12c5d1SDavid du Colombier sprint(buf, "#s/%s", server); 3923e12c5d1SDavid du Colombier if(sfd < 0){ 3933e12c5d1SDavid du Colombier if(pipe(p) < 0) 3943e12c5d1SDavid du Colombier panic("can't make a pipe"); 3953e12c5d1SDavid du Colombier sfd = p[0]; 3963e12c5d1SDavid du Colombier rfd = p[1]; 3973e12c5d1SDavid du Colombier } 3983e12c5d1SDavid du Colombier srvfd(buf, sfd); 3993e12c5d1SDavid du Colombier close(sfd); 4003e12c5d1SDavid du Colombier cp = ialloc(sizeof *cp); 4013e12c5d1SDavid du Colombier cp->chan = rfd; 4023e12c5d1SDavid du Colombier strncpy(cp->whoname, "<none>", sizeof(cp->whoname)); 4033e12c5d1SDavid du Colombier fileinit(cp); 4043e12c5d1SDavid du Colombier wlock(&cp->reflock); 4053e12c5d1SDavid du Colombier wunlock(&cp->reflock); 4063e12c5d1SDavid du Colombier lock(&cp->flock); 4073e12c5d1SDavid du Colombier unlock(&cp->flock); 4083e12c5d1SDavid du Colombier return cp; 4093e12c5d1SDavid du Colombier } 4103e12c5d1SDavid du Colombier 4113e12c5d1SDavid du Colombier int 4123e12c5d1SDavid du Colombier srvfd(char *s, int sfd) 4133e12c5d1SDavid du Colombier { 4143e12c5d1SDavid du Colombier int fd; 4153e12c5d1SDavid du Colombier char buf[32]; 4163e12c5d1SDavid du Colombier 4173e12c5d1SDavid du Colombier fd = create(s, OWRITE, 0666); 4183e12c5d1SDavid du Colombier if(fd < 0){ 4193e12c5d1SDavid du Colombier remove(s); 4203e12c5d1SDavid du Colombier fd = create(s, OWRITE, 0666); 4213e12c5d1SDavid du Colombier if(fd < 0) 4223e12c5d1SDavid du Colombier panic(s); 4233e12c5d1SDavid du Colombier } 4243e12c5d1SDavid du Colombier sprint(buf, "%d", sfd); 4253e12c5d1SDavid du Colombier if(write(fd, buf, strlen(buf)) != strlen(buf)) 4263e12c5d1SDavid du Colombier panic("srv write"); 427*219b2ee8SDavid du Colombier close(fd); 4283e12c5d1SDavid du Colombier return sfd; 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier 4313e12c5d1SDavid du Colombier void 4323e12c5d1SDavid du Colombier consinit(void) 4333e12c5d1SDavid du Colombier { 4343e12c5d1SDavid du Colombier int i; 4353e12c5d1SDavid du Colombier 4363e12c5d1SDavid du Colombier cons.chan = ialloc(sizeof(Chan)); 4373e12c5d1SDavid du Colombier wlock(&cons.chan->reflock); 4383e12c5d1SDavid du Colombier wunlock(&cons.chan->reflock); 4393e12c5d1SDavid du Colombier lock(&cons.chan->flock); 4403e12c5d1SDavid du Colombier unlock(&cons.chan->flock); 4413e12c5d1SDavid du Colombier dofilter(&cons.work); 4423e12c5d1SDavid du Colombier dofilter(&cons.rate); 4433e12c5d1SDavid du Colombier dofilter(&cons.bhit); 4443e12c5d1SDavid du Colombier dofilter(&cons.bread); 4453e12c5d1SDavid du Colombier dofilter(&cons.binit); 4463e12c5d1SDavid du Colombier for(i = 0; i < MAXTAG; i++) 4473e12c5d1SDavid du Colombier dofilter(&cons.tags[i]); 4483e12c5d1SDavid du Colombier } 4493e12c5d1SDavid du Colombier 4503e12c5d1SDavid du Colombier /* 4513e12c5d1SDavid du Colombier * always called with mainlock locked 4523e12c5d1SDavid du Colombier */ 4533e12c5d1SDavid du Colombier void 4543e12c5d1SDavid du Colombier syncall(void) 4553e12c5d1SDavid du Colombier { 4563e12c5d1SDavid du Colombier for(;;) 4573e12c5d1SDavid du Colombier if(!syncblock()) 4583e12c5d1SDavid du Colombier return; 4593e12c5d1SDavid du Colombier } 4603e12c5d1SDavid du Colombier 4613e12c5d1SDavid du Colombier int 4623e12c5d1SDavid du Colombier askream(Filsys *fs) 4633e12c5d1SDavid du Colombier { 4643e12c5d1SDavid du Colombier char c; 4653e12c5d1SDavid du Colombier 4663e12c5d1SDavid du Colombier print("File system %s inconsistent\n", fs->name); 4673e12c5d1SDavid du Colombier print("Would you like to ream it (y/n)? "); 4683e12c5d1SDavid du Colombier read(0, &c, 1); 4693e12c5d1SDavid du Colombier return c == 'y'; 4703e12c5d1SDavid du Colombier } 4713e12c5d1SDavid du Colombier 472*219b2ee8SDavid du Colombier ulong 473*219b2ee8SDavid du Colombier memsize(void) 474*219b2ee8SDavid du Colombier { 475*219b2ee8SDavid du Colombier char *p, buf[128]; 476*219b2ee8SDavid du Colombier int fd, n, by2pg, secs; 477*219b2ee8SDavid du Colombier 478*219b2ee8SDavid du Colombier by2pg = 4*1024; 479*219b2ee8SDavid du Colombier p = getenv("cputype"); 480*219b2ee8SDavid du Colombier if(p && strcmp(p, "68020") == 0) 481*219b2ee8SDavid du Colombier by2pg = 8*1024; 482*219b2ee8SDavid du Colombier 483*219b2ee8SDavid du Colombier secs = 4*1024*1024; 484*219b2ee8SDavid du Colombier 485*219b2ee8SDavid du Colombier fd = open("/dev/swap", OREAD); 486*219b2ee8SDavid du Colombier if(fd < 0) 487*219b2ee8SDavid du Colombier return secs; 488*219b2ee8SDavid du Colombier n = read(fd, buf, sizeof(buf)-1); 489*219b2ee8SDavid du Colombier close(fd); 490*219b2ee8SDavid du Colombier if(n <= 0) 491*219b2ee8SDavid du Colombier return secs; 492*219b2ee8SDavid du Colombier buf[n] = 0; 493*219b2ee8SDavid du Colombier p = strchr(buf, '/'); 494*219b2ee8SDavid du Colombier if(p) 495*219b2ee8SDavid du Colombier secs = strtoul(p+1, 0, 0)*by2pg; 496*219b2ee8SDavid du Colombier return secs; 497*219b2ee8SDavid du Colombier } 498*219b2ee8SDavid du Colombier 4993e12c5d1SDavid du Colombier /* 5003e12c5d1SDavid du Colombier * init the devices 5013e12c5d1SDavid du Colombier * wipe some of the file systems, or all if ream is set 5023e12c5d1SDavid du Colombier * this code really assumes that only one file system exists 5033e12c5d1SDavid du Colombier */ 5043e12c5d1SDavid du Colombier int 5053e12c5d1SDavid du Colombier fsinit(int ream, int newbufsize) 5063e12c5d1SDavid du Colombier { 5073e12c5d1SDavid du Colombier Filsys *fs; 5083e12c5d1SDavid du Colombier 5093e12c5d1SDavid du Colombier RBUFSIZE = 4 * 1024; 5103e12c5d1SDavid du Colombier for(fs=filsys; fs->name; fs++) 5113e12c5d1SDavid du Colombier (*devcall[fs->dev.type].init)(fs->dev); 5123e12c5d1SDavid du Colombier if(newbufsize == 0) 5133e12c5d1SDavid du Colombier newbufsize = RBUFSIZE; 514*219b2ee8SDavid du Colombier 515*219b2ee8SDavid du Colombier if(conf.niobuf == 0) { 516*219b2ee8SDavid du Colombier conf.niobuf = memsize()/10; 517*219b2ee8SDavid du Colombier if(conf.niobuf > 2*1024*1024) 518*219b2ee8SDavid du Colombier conf.niobuf = 2*1024*1024; 519*219b2ee8SDavid du Colombier conf.niobuf /= newbufsize; 520*219b2ee8SDavid du Colombier if(conf.niobuf < 30) 521*219b2ee8SDavid du Colombier conf.niobuf = 30; 522*219b2ee8SDavid du Colombier } 523*219b2ee8SDavid du Colombier 5243e12c5d1SDavid du Colombier BUFSIZE = RBUFSIZE - sizeof(Tag); 5253e12c5d1SDavid du Colombier 5263e12c5d1SDavid du Colombier for(fs=filsys; fs->name; fs++) 5273e12c5d1SDavid du Colombier if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){ 5283e12c5d1SDavid du Colombier RBUFSIZE = newbufsize; 5293e12c5d1SDavid du Colombier BUFSIZE = RBUFSIZE - sizeof(Tag); 5303e12c5d1SDavid du Colombier (*devcall[fs->dev.type].ream)(fs->dev); 5313e12c5d1SDavid du Colombier fs->flags |= FREAM; 5323e12c5d1SDavid du Colombier ream = 1; 5333e12c5d1SDavid du Colombier } 5343e12c5d1SDavid du Colombier 5353e12c5d1SDavid du Colombier /* 5363e12c5d1SDavid du Colombier * set up the block size dependant variables 5373e12c5d1SDavid du Colombier */ 5383e12c5d1SDavid du Colombier BUFSIZE = RBUFSIZE - sizeof(Tag); 5393e12c5d1SDavid du Colombier DIRPERBUF = BUFSIZE / sizeof(Dentry); 5403e12c5d1SDavid du Colombier INDPERBUF = BUFSIZE / sizeof(long); 5413e12c5d1SDavid du Colombier INDPERBUF2 = INDPERBUF * INDPERBUF; 5423e12c5d1SDavid du Colombier FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long); 5433e12c5d1SDavid du Colombier return ream; 5443e12c5d1SDavid du Colombier } 5453e12c5d1SDavid du Colombier 5463e12c5d1SDavid du Colombier /* 5473e12c5d1SDavid du Colombier * allocate rest of mem 5483e12c5d1SDavid du Colombier * for io buffers. 5493e12c5d1SDavid du Colombier */ 5503e12c5d1SDavid du Colombier #define HWIDTH 5 /* buffers per hash */ 5513e12c5d1SDavid du Colombier void 5523e12c5d1SDavid du Colombier iobufinit(void) 5533e12c5d1SDavid du Colombier { 5543e12c5d1SDavid du Colombier long i; 5553e12c5d1SDavid du Colombier Iobuf *p, *q; 5563e12c5d1SDavid du Colombier Hiob *hp; 5573e12c5d1SDavid du Colombier 5583e12c5d1SDavid du Colombier i = conf.niobuf*RBUFSIZE; 5593e12c5d1SDavid du Colombier niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH); 5603e12c5d1SDavid du Colombier nhiob = niob / HWIDTH; 5613e12c5d1SDavid du Colombier while(!prime(nhiob)) 5623e12c5d1SDavid du Colombier nhiob++; 5633e12c5d1SDavid du Colombier if(chat) 5643e12c5d1SDavid du Colombier print(" %ld buffers; %ld hashes\n", niob, nhiob); 5653e12c5d1SDavid du Colombier hiob = ialloc(nhiob * sizeof(Hiob)); 5663e12c5d1SDavid du Colombier hp = hiob; 5673e12c5d1SDavid du Colombier for(i=0; i<nhiob; i++) { 5683e12c5d1SDavid du Colombier lock(hp); 5693e12c5d1SDavid du Colombier unlock(hp); 5703e12c5d1SDavid du Colombier hp++; 5713e12c5d1SDavid du Colombier } 5723e12c5d1SDavid du Colombier p = ialloc(niob * sizeof(Iobuf)); 5733e12c5d1SDavid du Colombier hp = hiob; 5743e12c5d1SDavid du Colombier for(i=0; i<niob; i++) { 5753e12c5d1SDavid du Colombier qlock(p); 5763e12c5d1SDavid du Colombier qunlock(p); 5773e12c5d1SDavid du Colombier if(hp == hiob) 5783e12c5d1SDavid du Colombier hp = hiob + nhiob; 5793e12c5d1SDavid du Colombier hp--; 5803e12c5d1SDavid du Colombier q = hp->link; 5813e12c5d1SDavid du Colombier if(q) { 5823e12c5d1SDavid du Colombier p->fore = q; 5833e12c5d1SDavid du Colombier p->back = q->back; 5843e12c5d1SDavid du Colombier q->back = p; 5853e12c5d1SDavid du Colombier p->back->fore = p; 5863e12c5d1SDavid du Colombier } else { 5873e12c5d1SDavid du Colombier hp->link = p; 5883e12c5d1SDavid du Colombier p->fore = p; 5893e12c5d1SDavid du Colombier p->back = p; 5903e12c5d1SDavid du Colombier } 5913e12c5d1SDavid du Colombier p->dev = devnone; 5923e12c5d1SDavid du Colombier p->addr = -1; 5933e12c5d1SDavid du Colombier p->xiobuf = ialloc(RBUFSIZE); 5943e12c5d1SDavid du Colombier p->iobuf = (char*)-1; 5953e12c5d1SDavid du Colombier p++; 5963e12c5d1SDavid du Colombier } 5973e12c5d1SDavid du Colombier } 5983e12c5d1SDavid du Colombier 599*219b2ee8SDavid du Colombier void 600*219b2ee8SDavid du Colombier usage(void) 601*219b2ee8SDavid du Colombier { 6023e12c5d1SDavid du Colombier fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n"); 6033e12c5d1SDavid du Colombier exits(0); 6043e12c5d1SDavid du Colombier } 605