code: mafs

ref: 56bd332994102b4e194819abb5e087a8895452f9
dir: /mafs.c/

View raw version
#include	"all.h"
#include	"pool.h"

char *devfile = nil;	/* device file path */
char service[Namelen] = "\0";
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 [-Ds] [-r service] [-n service] [-m nmemunits] [-h nbuckets] [-w npendingwrites] file\n");
	exits("usage");
}

void
main(int argc, char **argv)
{
	int doream, stdio;
	char buf[Namelen];
	int pid, ctl;
	u64 nmemunits, size;

	/* 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 'D':	chatty9p++; break;
	case 'f':	devfile = ARGF(); break;
	case 'h':	nbuckets = atoll(EARGF(usage())); break;
	case 'm':	nmemunits = atoll(EARGF(usage())); break;
	case 'r':
		doream = 1;
		/* fall through */
	case 'n':
		snprint(service, Namelen, "%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);

	/* 2/3rds of the memory for the pending writes
		and 1/3rd for the buffer cache
	 */
	if(nmemunits == 0)
		nmemunits = size/Blocksize > 8*MiB ? 8*MiB : size/Blocksize;
	if(nmemunits < 16*MiB)
		nmemunits = 16*MiB;
	if(nbuckets == 0)
		nbuckets = nmemunits/(4*Ncollisions*Maxdatablockunits);
	if(nbuckets == 0)
		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);
	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, Namelen, "%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;
}