ref: 285644aadb1b58735651a5068703372f8fc9adac
dir: /mafs.c/
#include "all.h" #include "pool.h" char *devfile = nil; /* device file path */ char service[Servicelen] = "\0"; /* use a byte for all these flags as hjfs? */ u8 noauth = 0; u8 readonly = 0; u8 shuttingdown = 0; int writeallow; /* never on; for compatibility with fs */ int wstatallow; int writegroup; int allownone; static void usage(void); static void printsizes(void); Config config = {0}; static void usage(void) { fprint(2, "usage: mafs [-ADs] [-r service] [-n service] [-m nmemunits] file\n"); exits("usage"); } void main(int argc, char **argv) { int doream, stdio; char buf[Servicelen]; int pid, ctl; u64 nmemunits, size; Errenv env = {0}; envpp = privalloc(); *envpp = &env; if(waserror()){ panic(0, "err stack %d: %lux %lux %lux %lux %lux %lux", env.nlabel, env.label[0][JMPBUFPC], env.label[1][JMPBUFPC], env.label[2][JMPBUFPC], env.label[3][JMPBUFPC], env.label[4][JMPBUFPC], env.label[5][JMPBUFPC]); } /* mainmem->flags |= POOL_PARANOIA|POOL_LOGGING; */ /* * insulate from invoker's environment and keep it from swapping */ rfork(RFNAMEG|RFNOTEG|RFREND); nbuckets = 0; nmemunits = 0; doream = stdio = 0; pid = getpid(); snprint(buf, sizeof buf, "/proc/%d/ctl", pid); ctl = open(buf, OWRITE); fprint(ctl, "noswap\n"); close(ctl); ARGBEGIN{ default: usage(); case 'A': noauth++; break; case 'D': chatty9p++; break; case 'f': /* devfile = ARGF(); */ break; /* to work with bootfs of /sys/src/9/boot/local.rc */ case 'm': nmemunits = atoll(EARGF(usage())); break; case 'r': doream = 1; /* fall through */ case 'n': snprint(service, Servicelen, "%s", EARGF(usage())); break; case 's': stdio++; break; }ARGEND if(argc != 1 || (doream && service[0] == '\0')) usage(); devfile = argv[0]; if(devfile == nil) sysfatal("no disk file"); if (access(devfile, AREAD|AWRITE) == -1) sysfatal("%s cannot access device", devfile); size = devinit(devfile); if(size == 0) panic("null size %s", devfile); /* Minimum number of collisions = 3 Minimum number of hash buckets = 7 Minimum number of memunits = 7 * 3 * 2048 blocks = 43,008 blocks */ if(nmemunits < 42*KiB){ nmemunits = size/Blocksize; if(nmemunits > 8*MiB) nmemunits = 8*MiB; else if(nmemunits < 42*KiB) nmemunits = 42*KiB; } nbuckets = nmemunits/(4*Ncollisions*Maxdatablockunits); if(nbuckets < 7) nbuckets = 7; if(chatty9p){ dprint("\nPlan 9 %d-bit file server with %d-deep indirect blocks\n", sizeof(u64)*8, Niblock); dprint("nmemunits %llud nbuckets %llud\n", nmemunits, nbuckets); } formatinit(); initmemunitpool(nmemunits); initextents(&frees, "blocks", 1, 0, 2, nil, dprintfd, panic, malloc9p); iobufinit(); /* * init the file system, ream it if needed, and get the block sizes. * service = config.service, if service is nil. */ init(doream, size); if(service[0] == '\0') snprint(service, Servicelen, "%s", config.service); start9p(stdio); /* we have started another proc to process /srv/service and it is my time to exit */ exits(nil); } /* * compute BUFSIZE*(Ndblock+INDPERBUF+INDPERBUF²+INDPERBUF³+INDPERBUF⁴ .. upto ^Niblock) * while watching for overflow; in that case, return 0. */ static u64 maxsize(void) { int i; uvlong max = Ndblock, ind; dprint("maxsize direct spans max %llud\n", max); for (i = 0; i < Niblock; i++) { ind = nperiblock(Tind0+i); max += ind; dprint("maxsize %s %llud max %llud\n", tagnames[Tind0+i], ind, max); } return max; }