13e12c5d1SDavid du Colombier #include "all.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier int sfd;
47dd7cddfSDavid du Colombier int cmdmode = 0660;
53e12c5d1SDavid du Colombier int rfd;
63e12c5d1SDavid du Colombier int chat;
73e12c5d1SDavid du Colombier extern char *wrenfile;
87dd7cddfSDavid du Colombier extern int nwren;
93e12c5d1SDavid du Colombier char *myname;
103e12c5d1SDavid du Colombier int cmdfd;
11bd389b36SDavid du Colombier int writeallow; /* never on; for compatibility with fs */
12bd389b36SDavid du Colombier int wstatallow;
135d459b5aSDavid du Colombier int writegroup;
149a747e4fSDavid du Colombier int allownone;
159a747e4fSDavid du Colombier int noatime;
167dd7cddfSDavid du Colombier int srvfd(char*, int, int);
173e12c5d1SDavid du Colombier void usage(void);
183e12c5d1SDavid du Colombier void confinit(void);
193e12c5d1SDavid du Colombier Chan *chaninit(char*);
203e12c5d1SDavid du Colombier void consinit(void);
219a747e4fSDavid du Colombier void forkserve(void);
223e12c5d1SDavid du Colombier
233e12c5d1SDavid du Colombier void
main(int argc,char * argv[])243e12c5d1SDavid du Colombier main(int argc, char *argv[])
253e12c5d1SDavid du Colombier {
263e12c5d1SDavid du Colombier Filsys *fs;
279a747e4fSDavid du Colombier int ream, fsok;
283e12c5d1SDavid du Colombier int newbufsize, nocheck;
293e12c5d1SDavid du Colombier char buf[NAMELEN];
30b7b24591SDavid du Colombier int pid, ctl;
313e12c5d1SDavid du Colombier
323e12c5d1SDavid du Colombier progname = "kfs";
333e12c5d1SDavid du Colombier procname = "init";
343e12c5d1SDavid du Colombier
353e12c5d1SDavid du Colombier /*
36b7b24591SDavid du Colombier * insulate from invoker's environment and keep it from swapping
373e12c5d1SDavid du Colombier */
387dd7cddfSDavid du Colombier rfork(RFNAMEG|RFNOTEG|RFREND);
393e12c5d1SDavid du Colombier
403e12c5d1SDavid du Colombier confinit();
413e12c5d1SDavid du Colombier sfd = -1;
423e12c5d1SDavid du Colombier ream = 0;
433e12c5d1SDavid du Colombier newbufsize = 0;
443e12c5d1SDavid du Colombier nocheck = 0;
457dd7cddfSDavid du Colombier wrenfile = "/dev/sdC0/fs";
46b7b24591SDavid du Colombier
47b7b24591SDavid du Colombier pid = getpid();
48b7b24591SDavid du Colombier snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
49b7b24591SDavid du Colombier ctl = open(buf, OWRITE);
50b7b24591SDavid du Colombier fprint(ctl, "noswap\n");
51b7b24591SDavid du Colombier close(ctl);
52b7b24591SDavid du Colombier
533e12c5d1SDavid du Colombier buf[0] = '\0';
54b7b24591SDavid du Colombier
553e12c5d1SDavid du Colombier ARGBEGIN{
563e12c5d1SDavid du Colombier case 'b':
573e12c5d1SDavid du Colombier newbufsize = atol(ARGF());
583e12c5d1SDavid du Colombier break;
593e12c5d1SDavid du Colombier case 'c':
603e12c5d1SDavid du Colombier nocheck = 1;
613e12c5d1SDavid du Colombier break;
623e12c5d1SDavid du Colombier case 'f':
633e12c5d1SDavid du Colombier wrenfile = ARGF();
643e12c5d1SDavid du Colombier break;
657dd7cddfSDavid du Colombier case 'm':
667dd7cddfSDavid du Colombier nwren = atol(ARGF());
677dd7cddfSDavid du Colombier break;
683e12c5d1SDavid du Colombier case 'n':
693e12c5d1SDavid du Colombier strncpy(buf, ARGF(), NAMELEN-1);
703e12c5d1SDavid du Colombier buf[NAMELEN-1] = '\0';
713e12c5d1SDavid du Colombier break;
727dd7cddfSDavid du Colombier case 'p':
737dd7cddfSDavid du Colombier cmdmode = atol(ARGF());
747dd7cddfSDavid du Colombier break;
753e12c5d1SDavid du Colombier case 'r':
763e12c5d1SDavid du Colombier ream = 1;
773e12c5d1SDavid du Colombier break;
783e12c5d1SDavid du Colombier case 's':
793e12c5d1SDavid du Colombier sfd = 0;
8080ee5cbfSDavid du Colombier rfd = dup(1, -1);
8180ee5cbfSDavid du Colombier close(1);
8280ee5cbfSDavid du Colombier if(open("/dev/cons", OWRITE) < 0)
8380ee5cbfSDavid du Colombier open("#c/cons", OWRITE);
843e12c5d1SDavid du Colombier break;
85219b2ee8SDavid du Colombier case 'B':
86219b2ee8SDavid du Colombier conf.niobuf = strtoul(ARGF(), 0, 0);
87219b2ee8SDavid du Colombier break;
883e12c5d1SDavid du Colombier case 'C':
893e12c5d1SDavid du Colombier chat = 1;
903e12c5d1SDavid du Colombier break;
913e12c5d1SDavid du Colombier default:
923e12c5d1SDavid du Colombier usage();
933e12c5d1SDavid du Colombier }ARGEND
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier if(argc != 0)
967dd7cddfSDavid du Colombier usage();
973e12c5d1SDavid du Colombier
98bd389b36SDavid du Colombier cmdfd = 2;
993e12c5d1SDavid du Colombier
10027e10919SDavid du Colombier if (access(wrenfile, AREAD|AWRITE) == -1)
101*14cc0f53SDavid du Colombier sysfatal("%s cannot access device", wrenfile);
10227e10919SDavid du Colombier
1033e12c5d1SDavid du Colombier formatinit();
1047dd7cddfSDavid du Colombier sublockinit();
1053e12c5d1SDavid du Colombier
1063e12c5d1SDavid du Colombier if(buf[0])
1073e12c5d1SDavid du Colombier sprint(service, "kfs.%s", buf);
1083e12c5d1SDavid du Colombier else
1093e12c5d1SDavid du Colombier strcpy(service, "kfs");
1103e12c5d1SDavid du Colombier chan = chaninit(service);
1113e12c5d1SDavid du Colombier consinit();
1123e12c5d1SDavid du Colombier tlocks = ialloc(NTLOCK * sizeof *tlocks);
1133e12c5d1SDavid du Colombier uid = ialloc(conf.nuid * sizeof(*uid));
1143e12c5d1SDavid du Colombier uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
1153e12c5d1SDavid du Colombier gidspace = ialloc(conf.gidspace * sizeof(*gidspace));
1163e12c5d1SDavid du Colombier
1173e12c5d1SDavid du Colombier /*
1183e12c5d1SDavid du Colombier * init global locks
1193e12c5d1SDavid du Colombier */
1203e12c5d1SDavid du Colombier wlock(&mainlock); wunlock(&mainlock);
1213e12c5d1SDavid du Colombier
1223e12c5d1SDavid du Colombier /*
1233e12c5d1SDavid du Colombier * init the file system, ream it if needed, and get the block sizes
1243e12c5d1SDavid du Colombier */
1253e12c5d1SDavid du Colombier ream = fsinit(ream, newbufsize);
1263e12c5d1SDavid du Colombier iobufinit();
1277dd7cddfSDavid du Colombier for(fs=filesys; fs->name; fs++)
1283e12c5d1SDavid du Colombier if(fs->flags & FREAM){ /* set by fsinit if reamed */
1293e12c5d1SDavid du Colombier ream++;
1303e12c5d1SDavid du Colombier rootream(fs->dev, getraddr(fs->dev));
1313e12c5d1SDavid du Colombier superream(fs->dev, superaddr(fs->dev));
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier
1347dd7cddfSDavid du Colombier boottime = time(nil);
1353e12c5d1SDavid du Colombier
1363e12c5d1SDavid du Colombier consserve();
1377dd7cddfSDavid du Colombier fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0);
138219b2ee8SDavid du Colombier if(!nocheck && !ream && !fsok)
1393e12c5d1SDavid du Colombier cmd_exec("check fq");
1403e12c5d1SDavid du Colombier
1419a747e4fSDavid du Colombier startproc(forkserve, "srv");
1423e12c5d1SDavid du Colombier startproc(syncproc, "sync");
1433e12c5d1SDavid du Colombier
1443e12c5d1SDavid du Colombier exits(0);
1453e12c5d1SDavid du Colombier }
1463e12c5d1SDavid du Colombier
1473e12c5d1SDavid du Colombier void
forkserve(void)1489a747e4fSDavid du Colombier forkserve(void)
1493e12c5d1SDavid du Colombier {
1509a747e4fSDavid du Colombier serve(chan);
15159cc4ca5SDavid du Colombier }
15259cc4ca5SDavid du Colombier
1533e12c5d1SDavid du Colombier static
1543e12c5d1SDavid du Colombier struct
1553e12c5d1SDavid du Colombier {
1563e12c5d1SDavid du Colombier int nfilter;
1573e12c5d1SDavid du Colombier Filter* filters[100];
1583e12c5d1SDavid du Colombier }f;
1593e12c5d1SDavid du Colombier
1607dd7cddfSDavid du Colombier int alarmed;
1617dd7cddfSDavid du Colombier
1623e12c5d1SDavid du Colombier void
catchalarm(void * regs,char * msg)1633e12c5d1SDavid du Colombier catchalarm(void *regs, char *msg)
1643e12c5d1SDavid du Colombier {
1653e12c5d1SDavid du Colombier USED(regs, msg);
1667dd7cddfSDavid du Colombier if(strcmp(msg, "alarm") == 0){
1677dd7cddfSDavid du Colombier alarmed = 1;
1683e12c5d1SDavid du Colombier noted(NCONT);
1697dd7cddfSDavid du Colombier } else
1703e12c5d1SDavid du Colombier noted(NDFLT);
1713e12c5d1SDavid du Colombier }
1723e12c5d1SDavid du Colombier
1733e12c5d1SDavid du Colombier /*
1743e12c5d1SDavid du Colombier * process to synch blocks
1753e12c5d1SDavid du Colombier * it puts out a block/line every second
1763e12c5d1SDavid du Colombier * it waits 10 seconds if catches up.
1773e12c5d1SDavid du Colombier * in both cases, it takes about 10 seconds
1783e12c5d1SDavid du Colombier * to get up-to-date.
1793e12c5d1SDavid du Colombier *
1803e12c5d1SDavid du Colombier * it also updates the filter stats
1813e12c5d1SDavid du Colombier * and executes commands
1823e12c5d1SDavid du Colombier */
1833e12c5d1SDavid du Colombier void
syncproc(void)1843e12c5d1SDavid du Colombier syncproc(void)
1853e12c5d1SDavid du Colombier {
1863e12c5d1SDavid du Colombier char buf[4*1024];
1873e12c5d1SDavid du Colombier Filter *ft;
1883e12c5d1SDavid du Colombier ulong c0, c1;
1893e12c5d1SDavid du Colombier long t, n, d;
1903e12c5d1SDavid du Colombier int i, p[2];
1913e12c5d1SDavid du Colombier
1923e12c5d1SDavid du Colombier /*
1933e12c5d1SDavid du Colombier * make a pipe for commands
1943e12c5d1SDavid du Colombier */
1953e12c5d1SDavid du Colombier if(pipe(p) < 0)
1963e12c5d1SDavid du Colombier panic("command pipe");
1973e12c5d1SDavid du Colombier sprint(buf, "#s/%s.cmd", service);
1987dd7cddfSDavid du Colombier srvfd(buf, cmdmode, p[0]);
1993e12c5d1SDavid du Colombier close(p[0]);
2003e12c5d1SDavid du Colombier cmdfd = p[1];
2013e12c5d1SDavid du Colombier notify(catchalarm);
2023e12c5d1SDavid du Colombier
2037dd7cddfSDavid du Colombier t = time(nil);
2043e12c5d1SDavid du Colombier for(;;){
2053e12c5d1SDavid du Colombier i = syncblock();
2067dd7cddfSDavid du Colombier alarmed = 0;
2073e12c5d1SDavid du Colombier alarm(i ? 1000: 10000);
2083e12c5d1SDavid du Colombier n = read(cmdfd, buf, sizeof buf - 1);
2097dd7cddfSDavid du Colombier if(n <= 0 && !alarmed)
2107dd7cddfSDavid du Colombier sleep(i ? 1000: 10000);
2113e12c5d1SDavid du Colombier alarm(0);
2123e12c5d1SDavid du Colombier if(n > 0){
2133e12c5d1SDavid du Colombier buf[n] = '\0';
2143e12c5d1SDavid du Colombier if(cmd_exec(buf))
2153e12c5d1SDavid du Colombier fprint(cmdfd, "done");
2163e12c5d1SDavid du Colombier else
2173e12c5d1SDavid du Colombier fprint(cmdfd, "unknown command");
2183e12c5d1SDavid du Colombier }
2197dd7cddfSDavid du Colombier n = time(nil);
2203e12c5d1SDavid du Colombier d = n - t;
2213e12c5d1SDavid du Colombier if(d < 0 || d > 5*60)
2223e12c5d1SDavid du Colombier d = 0;
2233e12c5d1SDavid du Colombier while(d >= 1) {
2243e12c5d1SDavid du Colombier d -= 1;
2253e12c5d1SDavid du Colombier for(i=0; i<f.nfilter; i++) {
2263e12c5d1SDavid du Colombier ft = f.filters[i];
2273e12c5d1SDavid du Colombier c0 = ft->count;
2283e12c5d1SDavid du Colombier c1 = c0 - ft->oldcount;
2293e12c5d1SDavid du Colombier ft->oldcount = c0;
2303e12c5d1SDavid du Colombier ft->filter[0] = famd(ft->filter[0], c1, 59, 60);
2313e12c5d1SDavid du Colombier ft->filter[1] = famd(ft->filter[1], c1, 599, 600);
2323e12c5d1SDavid du Colombier ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000);
2333e12c5d1SDavid du Colombier }
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier t = n;
2363e12c5d1SDavid du Colombier }
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier
2393e12c5d1SDavid du Colombier void
dofilter(Filter * ft)2403e12c5d1SDavid du Colombier dofilter(Filter *ft)
2413e12c5d1SDavid du Colombier {
2423e12c5d1SDavid du Colombier int i;
2433e12c5d1SDavid du Colombier
2443e12c5d1SDavid du Colombier i = f.nfilter;
2453e12c5d1SDavid du Colombier if(i >= sizeof f.filters / sizeof f.filters[0]) {
2463e12c5d1SDavid du Colombier print("dofilter: too many filters\n");
2473e12c5d1SDavid du Colombier return;
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier f.filters[i] = ft;
2503e12c5d1SDavid du Colombier f.nfilter = i+1;
2513e12c5d1SDavid du Colombier }
2523e12c5d1SDavid du Colombier
2533e12c5d1SDavid du Colombier void
startproc(void (* f)(void),char * name)2543e12c5d1SDavid du Colombier startproc(void (*f)(void), char *name)
2553e12c5d1SDavid du Colombier {
2563e12c5d1SDavid du Colombier switch(rfork(RFMEM|RFFDG|RFPROC)){
2573e12c5d1SDavid du Colombier case -1:
2583e12c5d1SDavid du Colombier panic("can't fork");
2593e12c5d1SDavid du Colombier case 0:
2603e12c5d1SDavid du Colombier break;
2613e12c5d1SDavid du Colombier default:
2623e12c5d1SDavid du Colombier return;
2633e12c5d1SDavid du Colombier }
2643e12c5d1SDavid du Colombier procname = name;
2653e12c5d1SDavid du Colombier f();
2669a747e4fSDavid du Colombier _exits(nil);
2673e12c5d1SDavid du Colombier }
2683e12c5d1SDavid du Colombier
2693e12c5d1SDavid du Colombier void
confinit(void)2703e12c5d1SDavid du Colombier confinit(void)
2713e12c5d1SDavid du Colombier {
2729a747e4fSDavid du Colombier conf.niobuf = 0;
2739a747e4fSDavid du Colombier conf.nuid = 600;
2749a747e4fSDavid du Colombier conf.nserve = 2;
2759a747e4fSDavid du Colombier conf.uidspace = conf.nuid*6;
2769a747e4fSDavid du Colombier conf.gidspace = conf.nuid*3;
2779a747e4fSDavid du Colombier cons.flags = 0;
27859cc4ca5SDavid du Colombier }
27959cc4ca5SDavid du Colombier
28059cc4ca5SDavid du Colombier static void
dochaninit(Chan * cp,int fd)28159cc4ca5SDavid du Colombier dochaninit(Chan *cp, int fd)
28259cc4ca5SDavid du Colombier {
28359cc4ca5SDavid du Colombier cp->chan = fd;
28459cc4ca5SDavid du Colombier fileinit(cp);
28559cc4ca5SDavid du Colombier wlock(&cp->reflock);
28659cc4ca5SDavid du Colombier wunlock(&cp->reflock);
28759cc4ca5SDavid du Colombier lock(&cp->flock);
28859cc4ca5SDavid du Colombier unlock(&cp->flock);
2893e12c5d1SDavid du Colombier }
2903e12c5d1SDavid du Colombier
2913e12c5d1SDavid du Colombier Chan*
chaninit(char * server)2923e12c5d1SDavid du Colombier chaninit(char *server)
2933e12c5d1SDavid du Colombier {
2943e12c5d1SDavid du Colombier Chan *cp;
2953e12c5d1SDavid du Colombier char buf[3*NAMELEN];
2963e12c5d1SDavid du Colombier int p[2];
2973e12c5d1SDavid du Colombier
2983e12c5d1SDavid du Colombier sprint(buf, "#s/%s", server);
2993e12c5d1SDavid du Colombier if(sfd < 0){
3003e12c5d1SDavid du Colombier if(pipe(p) < 0)
3013e12c5d1SDavid du Colombier panic("can't make a pipe");
3023e12c5d1SDavid du Colombier sfd = p[0];
3033e12c5d1SDavid du Colombier rfd = p[1];
3043e12c5d1SDavid du Colombier }
3057dd7cddfSDavid du Colombier srvfd(buf, 0666, sfd);
3063e12c5d1SDavid du Colombier close(sfd);
3073e12c5d1SDavid du Colombier cp = ialloc(sizeof *cp);
30859cc4ca5SDavid du Colombier cons.srvchan = cp;
30959cc4ca5SDavid du Colombier dochaninit(cp, rfd);
3103e12c5d1SDavid du Colombier return cp;
3113e12c5d1SDavid du Colombier }
3123e12c5d1SDavid du Colombier
3133e12c5d1SDavid du Colombier int
netserve(char * netaddr)31459cc4ca5SDavid du Colombier netserve(char *netaddr)
31559cc4ca5SDavid du Colombier {
31659cc4ca5SDavid du Colombier int afd, lfd, fd;
31759cc4ca5SDavid du Colombier char adir[2*NAMELEN], ldir[2*NAMELEN];
3189a747e4fSDavid du Colombier Chan *netchan;
31959cc4ca5SDavid du Colombier
3208c41de82SDavid du Colombier if(access("/net/tcp/clone", 0) < 0)
32159cc4ca5SDavid du Colombier bind("#I", "/net", MAFTER);
3228c41de82SDavid du Colombier if(access("/net.alt/tcp/clone", 0) < 0)
32359cc4ca5SDavid du Colombier bind("#I1", "/net.alt", MAFTER);
32459cc4ca5SDavid du Colombier
32559cc4ca5SDavid du Colombier afd = announce(netaddr, adir);
32659cc4ca5SDavid du Colombier if (afd < 0)
32759cc4ca5SDavid du Colombier return -1;
32859cc4ca5SDavid du Colombier switch (rfork(RFMEM|RFFDG|RFPROC)) {
32959cc4ca5SDavid du Colombier case -1:
33059cc4ca5SDavid du Colombier return -1;
33159cc4ca5SDavid du Colombier case 0:
33259cc4ca5SDavid du Colombier break;
33359cc4ca5SDavid du Colombier default:
33459cc4ca5SDavid du Colombier return 0;
33559cc4ca5SDavid du Colombier }
33659cc4ca5SDavid du Colombier for (;;) {
33759cc4ca5SDavid du Colombier lfd = listen(adir, ldir);
33859cc4ca5SDavid du Colombier if (lfd < 0)
33959cc4ca5SDavid du Colombier continue;
34059cc4ca5SDavid du Colombier fd = accept(lfd, ldir);
34159cc4ca5SDavid du Colombier if (fd < 0) {
34259cc4ca5SDavid du Colombier close(lfd);
34359cc4ca5SDavid du Colombier continue;
34459cc4ca5SDavid du Colombier }
3459a747e4fSDavid du Colombier netchan = mallocz(sizeof(Chan), 1);
3469a747e4fSDavid du Colombier if(netchan == nil)
3479a747e4fSDavid du Colombier panic("out of memory");
3489a747e4fSDavid du Colombier dochaninit(netchan, fd);
34959cc4ca5SDavid du Colombier switch (rfork(RFMEM|RFFDG|RFPROC)) {
35059cc4ca5SDavid du Colombier case -1:
35159cc4ca5SDavid du Colombier panic("can't fork");
35259cc4ca5SDavid du Colombier case 0:
35359cc4ca5SDavid du Colombier close(afd);
35459cc4ca5SDavid du Colombier close(lfd);
3559a747e4fSDavid du Colombier serve(netchan);
3569a747e4fSDavid du Colombier free(netchan);
35759cc4ca5SDavid du Colombier exits(0);
35859cc4ca5SDavid du Colombier default:
35959cc4ca5SDavid du Colombier close(fd);
36059cc4ca5SDavid du Colombier close(lfd);
36159cc4ca5SDavid du Colombier continue;
36259cc4ca5SDavid du Colombier }
36359cc4ca5SDavid du Colombier }
36459cc4ca5SDavid du Colombier }
36559cc4ca5SDavid du Colombier
36659cc4ca5SDavid du Colombier int
srvfd(char * s,int mode,int sfd)3677dd7cddfSDavid du Colombier srvfd(char *s, int mode, int sfd)
3683e12c5d1SDavid du Colombier {
3693e12c5d1SDavid du Colombier int fd;
3703e12c5d1SDavid du Colombier char buf[32];
3713e12c5d1SDavid du Colombier
3729a747e4fSDavid du Colombier fd = create(s, ORCLOSE|OWRITE, mode);
3733e12c5d1SDavid du Colombier if(fd < 0){
3743e12c5d1SDavid du Colombier remove(s);
3759a747e4fSDavid du Colombier fd = create(s, ORCLOSE|OWRITE, mode);
3763e12c5d1SDavid du Colombier if(fd < 0)
3773e12c5d1SDavid du Colombier panic(s);
3783e12c5d1SDavid du Colombier }
3793e12c5d1SDavid du Colombier sprint(buf, "%d", sfd);
3803e12c5d1SDavid du Colombier if(write(fd, buf, strlen(buf)) != strlen(buf))
3813e12c5d1SDavid du Colombier panic("srv write");
3823e12c5d1SDavid du Colombier return sfd;
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier
3853e12c5d1SDavid du Colombier void
consinit(void)3863e12c5d1SDavid du Colombier consinit(void)
3873e12c5d1SDavid du Colombier {
3883e12c5d1SDavid du Colombier int i;
3893e12c5d1SDavid du Colombier
3903e12c5d1SDavid du Colombier cons.chan = ialloc(sizeof(Chan));
3913e12c5d1SDavid du Colombier wlock(&cons.chan->reflock);
3923e12c5d1SDavid du Colombier wunlock(&cons.chan->reflock);
3933e12c5d1SDavid du Colombier lock(&cons.chan->flock);
3943e12c5d1SDavid du Colombier unlock(&cons.chan->flock);
3953e12c5d1SDavid du Colombier dofilter(&cons.work);
3963e12c5d1SDavid du Colombier dofilter(&cons.rate);
3973e12c5d1SDavid du Colombier dofilter(&cons.bhit);
3983e12c5d1SDavid du Colombier dofilter(&cons.bread);
3993e12c5d1SDavid du Colombier dofilter(&cons.binit);
4003e12c5d1SDavid du Colombier for(i = 0; i < MAXTAG; i++)
4013e12c5d1SDavid du Colombier dofilter(&cons.tags[i]);
4023e12c5d1SDavid du Colombier }
4033e12c5d1SDavid du Colombier
4043e12c5d1SDavid du Colombier /*
4053e12c5d1SDavid du Colombier * always called with mainlock locked
4063e12c5d1SDavid du Colombier */
4073e12c5d1SDavid du Colombier void
syncall(void)4083e12c5d1SDavid du Colombier syncall(void)
4093e12c5d1SDavid du Colombier {
4103e12c5d1SDavid du Colombier for(;;)
4113e12c5d1SDavid du Colombier if(!syncblock())
4123e12c5d1SDavid du Colombier return;
4133e12c5d1SDavid du Colombier }
4143e12c5d1SDavid du Colombier
4153e12c5d1SDavid du Colombier int
askream(Filsys * fs)4163e12c5d1SDavid du Colombier askream(Filsys *fs)
4173e12c5d1SDavid du Colombier {
4183e12c5d1SDavid du Colombier char c;
4193e12c5d1SDavid du Colombier
4203e12c5d1SDavid du Colombier print("File system %s inconsistent\n", fs->name);
4213e12c5d1SDavid du Colombier print("Would you like to ream it (y/n)? ");
4223e12c5d1SDavid du Colombier read(0, &c, 1);
4233e12c5d1SDavid du Colombier return c == 'y';
4243e12c5d1SDavid du Colombier }
4253e12c5d1SDavid du Colombier
426219b2ee8SDavid du Colombier ulong
memsize(void)427219b2ee8SDavid du Colombier memsize(void)
428219b2ee8SDavid du Colombier {
429219b2ee8SDavid du Colombier char *p, buf[128];
430219b2ee8SDavid du Colombier int fd, n, by2pg, secs;
431219b2ee8SDavid du Colombier
432219b2ee8SDavid du Colombier by2pg = 4*1024;
433219b2ee8SDavid du Colombier p = getenv("cputype");
434219b2ee8SDavid du Colombier if(p && strcmp(p, "68020") == 0)
435219b2ee8SDavid du Colombier by2pg = 8*1024;
436219b2ee8SDavid du Colombier
437219b2ee8SDavid du Colombier secs = 4*1024*1024;
438219b2ee8SDavid du Colombier
439219b2ee8SDavid du Colombier fd = open("/dev/swap", OREAD);
440219b2ee8SDavid du Colombier if(fd < 0)
441219b2ee8SDavid du Colombier return secs;
442219b2ee8SDavid du Colombier n = read(fd, buf, sizeof(buf)-1);
443219b2ee8SDavid du Colombier close(fd);
444219b2ee8SDavid du Colombier if(n <= 0)
445219b2ee8SDavid du Colombier return secs;
446219b2ee8SDavid du Colombier buf[n] = 0;
447219b2ee8SDavid du Colombier p = strchr(buf, '/');
448219b2ee8SDavid du Colombier if(p)
449219b2ee8SDavid du Colombier secs = strtoul(p+1, 0, 0)*by2pg;
450219b2ee8SDavid du Colombier return secs;
451219b2ee8SDavid du Colombier }
452219b2ee8SDavid du Colombier
4533e12c5d1SDavid du Colombier /*
4543e12c5d1SDavid du Colombier * init the devices
4553e12c5d1SDavid du Colombier * wipe some of the file systems, or all if ream is set
4563e12c5d1SDavid du Colombier * this code really assumes that only one file system exists
4573e12c5d1SDavid du Colombier */
4583e12c5d1SDavid du Colombier int
fsinit(int ream,int newbufsize)4593e12c5d1SDavid du Colombier fsinit(int ream, int newbufsize)
4603e12c5d1SDavid du Colombier {
4613e12c5d1SDavid du Colombier Filsys *fs;
4623e12c5d1SDavid du Colombier
4633e12c5d1SDavid du Colombier RBUFSIZE = 4 * 1024;
4647dd7cddfSDavid du Colombier for(fs=filesys; fs->name; fs++)
4653e12c5d1SDavid du Colombier (*devcall[fs->dev.type].init)(fs->dev);
4663e12c5d1SDavid du Colombier if(newbufsize == 0)
4673e12c5d1SDavid du Colombier newbufsize = RBUFSIZE;
468219b2ee8SDavid du Colombier
469219b2ee8SDavid du Colombier if(conf.niobuf == 0) {
470219b2ee8SDavid du Colombier conf.niobuf = memsize()/10;
471219b2ee8SDavid du Colombier if(conf.niobuf > 2*1024*1024)
472219b2ee8SDavid du Colombier conf.niobuf = 2*1024*1024;
473219b2ee8SDavid du Colombier conf.niobuf /= newbufsize;
474219b2ee8SDavid du Colombier if(conf.niobuf < 30)
475219b2ee8SDavid du Colombier conf.niobuf = 30;
476219b2ee8SDavid du Colombier }
477219b2ee8SDavid du Colombier
4783e12c5d1SDavid du Colombier BUFSIZE = RBUFSIZE - sizeof(Tag);
4793e12c5d1SDavid du Colombier
4807dd7cddfSDavid du Colombier for(fs=filesys; fs->name; fs++)
4813e12c5d1SDavid du Colombier if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){
4823e12c5d1SDavid du Colombier RBUFSIZE = newbufsize;
4833e12c5d1SDavid du Colombier BUFSIZE = RBUFSIZE - sizeof(Tag);
4843e12c5d1SDavid du Colombier (*devcall[fs->dev.type].ream)(fs->dev);
4853e12c5d1SDavid du Colombier fs->flags |= FREAM;
4863e12c5d1SDavid du Colombier ream = 1;
4873e12c5d1SDavid du Colombier }
4883e12c5d1SDavid du Colombier
4893e12c5d1SDavid du Colombier /*
4903e12c5d1SDavid du Colombier * set up the block size dependant variables
4913e12c5d1SDavid du Colombier */
4923e12c5d1SDavid du Colombier BUFSIZE = RBUFSIZE - sizeof(Tag);
4933e12c5d1SDavid du Colombier DIRPERBUF = BUFSIZE / sizeof(Dentry);
4943e12c5d1SDavid du Colombier INDPERBUF = BUFSIZE / sizeof(long);
4953e12c5d1SDavid du Colombier INDPERBUF2 = INDPERBUF * INDPERBUF;
4963e12c5d1SDavid du Colombier FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long);
4973e12c5d1SDavid du Colombier return ream;
4983e12c5d1SDavid du Colombier }
4993e12c5d1SDavid du Colombier
5003e12c5d1SDavid du Colombier /*
5013e12c5d1SDavid du Colombier * allocate rest of mem
5023e12c5d1SDavid du Colombier * for io buffers.
5033e12c5d1SDavid du Colombier */
5043e12c5d1SDavid du Colombier #define HWIDTH 5 /* buffers per hash */
5053e12c5d1SDavid du Colombier void
iobufinit(void)5063e12c5d1SDavid du Colombier iobufinit(void)
5073e12c5d1SDavid du Colombier {
5083e12c5d1SDavid du Colombier long i;
5093e12c5d1SDavid du Colombier Iobuf *p, *q;
5103e12c5d1SDavid du Colombier Hiob *hp;
5113e12c5d1SDavid du Colombier
5123e12c5d1SDavid du Colombier i = conf.niobuf*RBUFSIZE;
5133e12c5d1SDavid du Colombier niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH);
5143e12c5d1SDavid du Colombier nhiob = niob / HWIDTH;
5153e12c5d1SDavid du Colombier while(!prime(nhiob))
5163e12c5d1SDavid du Colombier nhiob++;
5173e12c5d1SDavid du Colombier if(chat)
5183e12c5d1SDavid du Colombier print(" %ld buffers; %ld hashes\n", niob, nhiob);
5193e12c5d1SDavid du Colombier hiob = ialloc(nhiob * sizeof(Hiob));
5203e12c5d1SDavid du Colombier hp = hiob;
5213e12c5d1SDavid du Colombier for(i=0; i<nhiob; i++) {
5223e12c5d1SDavid du Colombier lock(hp);
5233e12c5d1SDavid du Colombier unlock(hp);
5243e12c5d1SDavid du Colombier hp++;
5253e12c5d1SDavid du Colombier }
5263e12c5d1SDavid du Colombier p = ialloc(niob * sizeof(Iobuf));
5273e12c5d1SDavid du Colombier hp = hiob;
5283e12c5d1SDavid du Colombier for(i=0; i<niob; i++) {
5293e12c5d1SDavid du Colombier qlock(p);
5303e12c5d1SDavid du Colombier qunlock(p);
5313e12c5d1SDavid du Colombier if(hp == hiob)
5323e12c5d1SDavid du Colombier hp = hiob + nhiob;
5333e12c5d1SDavid du Colombier hp--;
5343e12c5d1SDavid du Colombier q = hp->link;
5353e12c5d1SDavid du Colombier if(q) {
5363e12c5d1SDavid du Colombier p->fore = q;
5373e12c5d1SDavid du Colombier p->back = q->back;
5383e12c5d1SDavid du Colombier q->back = p;
5393e12c5d1SDavid du Colombier p->back->fore = p;
5403e12c5d1SDavid du Colombier } else {
5413e12c5d1SDavid du Colombier hp->link = p;
5423e12c5d1SDavid du Colombier p->fore = p;
5433e12c5d1SDavid du Colombier p->back = p;
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier p->dev = devnone;
5463e12c5d1SDavid du Colombier p->addr = -1;
5473e12c5d1SDavid du Colombier p->xiobuf = ialloc(RBUFSIZE);
5483e12c5d1SDavid du Colombier p->iobuf = (char*)-1;
5493e12c5d1SDavid du Colombier p++;
5503e12c5d1SDavid du Colombier }
5513e12c5d1SDavid du Colombier }
5523e12c5d1SDavid du Colombier
553219b2ee8SDavid du Colombier void
usage(void)554219b2ee8SDavid du Colombier usage(void)
555219b2ee8SDavid du Colombier {
5563e12c5d1SDavid du Colombier fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n");
5573e12c5d1SDavid du Colombier exits(0);
5583e12c5d1SDavid du Colombier }
559