shithub: riscv

Download patch

ref: 77e279201d08529a662b3f31b8c2c65683a55ebe
parent: cb474632d3f23de10fea2d70a4b4c98d8f3a3755
author: cinap_lenrek <[email protected]>
date: Fri Aug 21 15:52:57 EDT 2015

remove kfs and kfscmd

--- a/sys/src/cmd/disk/kfs/9p1.c
+++ /dev/null
@@ -1,1446 +1,0 @@
-#include	"all.h"
-#include	"9p1.h"
-
-/*
- * buggery to give false qid for
- * the top 2 levels of the dump fs
- */
-void
-mkqid(Qid* qid, Dentry *d, int buggery)
-{
-	int c;
-
-	if(buggery && d->qid.path == QPROOT && (d->qid.path & QPDIR)){
-		c = d->name[0];
-		if(c >= '0' && c <= '9'){
-			qid->path = 3;
-			qid->vers = d->qid.version;
-			qid->type = QTDIR;
-
-			c = (c-'0')*10 + (d->name[1]-'0');
-			if(c >= 1 && c <= 12)
-				qid->path = 4;
-			return;
-		}
-	}
-
-	mkqid9p2(qid, &d->qid, d->mode);
-}
-
-int
-mkqidcmp(Qid* qid, Dentry *d)
-{
-	Qid tmp;
-
-	mkqid(&tmp, d, 1);
-	if(qid->path==tmp.path && (qid->type&QTDIR)==(tmp.type&QTDIR))
-		return 0;
-	return Eqid;
-}
-
-void
-f_nop(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-
-	USED(in);
-	USED(ou);
-	if(CHAT(cp))
-		print("c_nop %d\n", cp->chan);
-}
-
-void
-f_flush(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-
-	USED(in);
-	USED(ou);
-	if(CHAT(cp))
-		print("c_flush %d\n", cp->chan);
-	runlock(&cp->reflock);
-	wlock(&cp->reflock);
-	wunlock(&cp->reflock);
-	rlock(&cp->reflock);
-}
-
-void
-f_session(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	if(CHAT(cp))
-		print("c_session %d\n", cp->chan);
-
-	memmove(cp->rchal, in->chal, sizeof(cp->rchal));
-	if(wstatallow || cp == cons.srvchan){
-		memset(ou->chal, 0, sizeof(ou->chal));
-		memset(ou->authid, 0, sizeof(ou->authid));
-	}else{
-		mkchallenge(cp);
-		memmove(ou->chal, cp->chal, sizeof(ou->chal));
-		memmove(ou->authid, nvr.authid, sizeof(ou->authid));
-	}
-	sprint(ou->authdom, "%s.%s", service, nvr.authdom);
-	fileinit(cp);
-}
-
-void
-f_attach(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p;
-	Dentry *d;
-	File *f;
-	int u;
-	Filsys *fs;
-	long raddr;
-
-	if(CHAT(cp)) {
-		print("c_attach %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-		print("	uid = %s\n", in->uname);
-		print("	arg = %s\n", in->aname);
-	}
-
-	ou->qid = QID9P1(0,0);
-	ou->fid = in->fid;
-	if(!in->aname[0])	/* default */
-		strncpy(in->aname, filesys[0].name, sizeof(in->aname));
-	p = 0;
-	f = filep(cp, in->fid, 1);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	u = -1;
-	if(cp != cons.chan){
-		if(authorize(cp, in, ou) == 0 || strcmp(in->uname, "adm") == 0){
-			ou->err = Eauth;
-			goto out;
-		}
-		u = strtouid(in->uname);
-		if(u < 0){
-			ou->err = Ebadu;
-			goto out;
-		}
-	}
-
-	fs = fsstr(in->aname);
-	if(fs == 0) {
-		ou->err = Ebadspc;
-		goto out;
-	}
-	raddr = getraddr(fs->dev);
-	p = getbuf(fs->dev, raddr, Bread);
-	d = getdir(p, 0);
-	if(!d || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	f->uid = u;
-	if(iaccess(f, d, DREAD)) {
-		ou->err = Eaccess;
-		goto out;
-	}
-	accessdir(p, d, FREAD);
-	mkqid(&f->qid, d, 1);
-	f->fs = fs;
-	f->addr = raddr;
-	f->slot = 0;
-	f->open = 0;
-	freewp(f->wpath);
-	f->wpath = 0;
-
-	mkqid9p1(&ou->qid, &f->qid);
-
-out:
-	if(p)
-		putbuf(p);
-	if(f) {
-		qunlock(f);
-		if(ou->err)
-			freefp(f);
-	}
-}
-
-void
-f_clone(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	File *f1, *f2;
-	int fid, fid1;
-
-	if(CHAT(cp)) {
-		print("c_clone %d\n", cp->chan);
-		print("	old fid = %d\n", in->fid);
-		print("	new fid = %d\n", in->newfid);
-	}
-
-	fid = in->fid;
-	fid1 = in->newfid;
-
-	f1 = 0;
-	f2 = 0;
-	if(fid < fid1) {
-		f1 = filep(cp, fid, 0);
-		f2 = filep(cp, fid1, 1);
-	} else
-	if(fid1 < fid) {
-		f2 = filep(cp, fid1, 1);
-		f1 = filep(cp, fid, 0);
-	}
-	if(!f1 || !f2) {
-		ou->err = Efid;
-		goto out;
-	}
-
-
-	f2->fs = f1->fs;
-	f2->addr = f1->addr;
-	f2->open = f1->open & ~FREMOV;
-	f2->uid = f1->uid;
-	f2->slot = f1->slot;
-	f2->qid = f1->qid;
-
-	freewp(f2->wpath);
-	f2->wpath = getwp(f1->wpath);
-
-out:
-	ou->fid = fid;
-	if(f1)
-		qunlock(f1);
-	if(f2)
-		qunlock(f2);
-}
-
-void
-f_walk(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1;
-	File *f;
-	Wpath *w, *ow;
-	int slot;
-	long addr;
-
-	if(CHAT(cp)) {
-		print("c_walk %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-		print("	name = %s\n", in->name);
-	}
-
-	ou->fid = in->fid;
-	ou->qid = QID9P1(0,0);
-	p = 0;
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(!(d->mode & DDIR)) {
-		ou->err = Edir1;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-	if(cp != cons.chan && iaccess(f, d, DEXEC)) {
-		ou->err = Eaccess;
-		goto out;
-	}
-	accessdir(p, d, FREAD);
-	if(strcmp(in->name, ".") == 0)
-		goto setdot;
-	if(strcmp(in->name, "..") == 0) {
-		if(f->wpath == 0)
-			goto setdot;
-		putbuf(p);
-		p = 0;
-		addr = f->wpath->addr;
-		slot = f->wpath->slot;
-		p1 = getbuf(f->fs->dev, addr, Bread);
-		d1 = getdir(p1, slot);
-		if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
-			if(p1)
-				putbuf(p1);
-			ou->err = Ephase;
-			goto out;
-		}
-		ow = f->wpath;
-		f->wpath = ow->up;
-		putwp(ow);
-		goto found;
-	}
-	for(addr=0;; addr++) {
-		p1 = dnodebuf(p, d, addr, 0);
-		if(!p1 || checktag(p1, Tdir, d->qid.path) ) {
-			if(p1)
-				putbuf(p1);
-			ou->err = Eentry;
-			goto out;
-		}
-		for(slot=0; slot<DIRPERBUF; slot++) {
-			d1 = getdir(p1, slot);
-			if(!(d1->mode & DALLOC))
-				continue;
-			if(strncmp(in->name, d1->name, sizeof(in->name)))
-				continue;
-			/*
-			 * update walk path
-			 */
-			w = newwp();
-			if(!w) {
-				ou->err = Ewalk;
-				putbuf(p1);
-				goto out;
-			}
-			w->addr = f->addr;
-			w->slot = f->slot;
-			w->up = f->wpath;
-			f->wpath = w;
-			slot += DIRPERBUF*addr;
-			goto found;
-		}
-		putbuf(p1);
-	}
-
-found:
-	f->addr = p1->addr;
-	mkqid(&f->qid, d1, 1);
-	putbuf(p1);
-	f->slot = slot;
-
-setdot:
-	mkqid9p1(&ou->qid, &f->qid);
-	f->open = 0;
-
-out:
-	if(p)
-		putbuf(p);
-	if(f)
-		qunlock(f);
-}
-
-void
-f_clunk(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	File *f;
-	Tlock *t;
-	long tim;
-
-	if(CHAT(cp)) {
-		print("c_clunk %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-	}
-
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		print("%p\n", f);
-		ou->err = Efid;
-		goto out;
-	}
-	if(t = f->tlock) {
-		tim = time(0);
-		if(t->time < tim || t->file != f)
-			ou->err = Ebroken;
-		t->time = 0;	/* free the lock */
-		f->tlock = 0;
-	}
-	if(f->open & FREMOV)
-		ou->err = doremove(f, 0);
-	f->open = 0;
-	freewp(f->wpath);
-	freefp(f);
-
-out:
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-}
-
-void
-f_clwalk(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	int er, fid;
-
-	if(CHAT(cp))
-		print("c_clwalk macro\n");
-
-	f_clone(cp, in, ou);		/* sets tag, fid */
-	if(ou->err)
-		return;
-	fid = in->fid;
-	in->fid = in->newfid;
-	f_walk(cp, in, ou);		/* sets tag, fid, qid */
-	er = ou->err;
-	if(er == Eentry) {
-		/*
-		 * if error is "no entry"
-		 * return non error and fid
-		 */
-		ou->err = 0;
-		f_clunk(cp, in, ou);	/* sets tag, fid */
-		ou->err = 0;
-		ou->fid = fid;
-		if(CHAT(cp)) 
-			print("	error: %s\n", errstring[er]);
-		return;
-	}
-	if(er) {
-		/*
-		 * if any other error
-		 * return an error
-		 */
-		ou->err = 0;
-		f_clunk(cp, in, ou);	/* sets tag, fid */
-		ou->err = er;
-		return;
-	}
-	/*
-	 * non error
-	 * return newfid
-	 */
-}
-
-void
-f_open(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p;
-	Dentry *d;
-	File *f;
-	Tlock *t;
-	Qid qid;
-	int ro, fmod;
-
-	if(CHAT(cp)) {
-		print("c_open %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-		print("	mode = %o\n", in->mode);
-	}
-
-	p = 0;
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-
-	/*
-	 * if remove on close, check access here
-	 */
-	ro = isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup));
-	if(in->mode & MRCLOSE) {
-		if(ro) {
-			ou->err = Eronly;
-			goto out;
-		}
-		/*
-		 * check on parent directory of file to be deleted
-		 */
-		if(f->wpath == 0 || f->wpath->addr == f->addr) {
-			ou->err = Ephase;
-			goto out;
-		}
-		p = getbuf(f->fs->dev, f->wpath->addr, Bread);
-		d = getdir(p, f->wpath->slot);
-		if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-			ou->err = Ephase;
-			goto out;
-		}
-		if(iaccess(f, d, DWRITE)) {
-			ou->err = Eaccess;
-			goto out;
-		}
-		putbuf(p);
-	}
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-	mkqid(&qid, d, 1);
-	switch(in->mode & 7) {
-
-	case MREAD:
-		if(iaccess(f, d, DREAD) && !writeallow)
-			goto badaccess;
-		fmod = FREAD;
-		break;
-
-	case MWRITE:
-		if((d->mode & DDIR) ||
-		   (iaccess(f, d, DWRITE) && !writeallow))
-			goto badaccess;
-		if(ro) {
-			ou->err = Eronly;
-			goto out;
-		}
-		fmod = FWRITE;
-		break;
-
-	case MBOTH:
-		if((d->mode & DDIR) ||
-		   (iaccess(f, d, DREAD) && !writeallow) ||
-		   (iaccess(f, d, DWRITE) && !writeallow))
-			goto badaccess;
-		if(ro) {
-			ou->err = Eronly;
-			goto out;
-		}
-		fmod = FREAD+FWRITE;
-		break;
-
-	case MEXEC:
-		if((d->mode & DDIR) ||
-		   iaccess(f, d, DEXEC))
-			goto badaccess;
-		fmod = FREAD;
-		break;
-
-	default:
-		ou->err = Emode;
-		goto out;
-	}
-	if(in->mode & MTRUNC) {
-		if((d->mode & DDIR) ||
-		   (iaccess(f, d, DWRITE) && !writeallow))
-			goto badaccess;
-		if(ro) {
-			ou->err = Eronly;
-			goto out;
-		}
-	}
-	t = 0;
-	if(d->mode & DLOCK) {
-		t = tlocked(p, d);
-		if(t == 0) {
-			ou->err = Elocked;
-			goto out;
-		}
-		t->file = f;
-	}
-	if(in->mode & MRCLOSE)
-		fmod |= FREMOV;
-	f->open = fmod;
-	if(in->mode & MTRUNC)
-		if(!(d->mode & DAPND))
-			dtrunc(p, d);
-	f->tlock = t;
-	f->lastra = 0;
-	mkqid9p1(&ou->qid, &qid);
-	goto out;
-
-badaccess:
-	ou->err = Eaccess;
-	f->open = 0;
-
-out:
-	if(p)
-		putbuf(p);
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-}
-
-void
-f_create(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1;
-	File *f;
-	int slot, slot1, fmod;
-	long addr, addr1, path;
-	Qid qid;
-	Tlock *t;
-	Wpath *w;
-
-	if(CHAT(cp)) {
-		print("c_create %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-		print("	name = %s\n", in->name);
-		print("	perm = %lx+%lo\n", (in->perm>>28)&0xf,
-				in->perm&0777);
-		print("	mode = %d\n", in->mode);
-	}
-
-	p = 0;
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
-		ou->err = Eronly;
-		goto out;
-	}
-
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-	if(!(d->mode & DDIR)) {
-		ou->err = Edir2;
-		goto out;
-	}
-	if(cp != cons.chan && iaccess(f, d, DWRITE) && !writeallow) {
-		ou->err = Eaccess;
-		goto out;
-	}
-	accessdir(p, d, FREAD);
-	if(!strncmp(in->name, ".", sizeof(in->name)) ||
-	   !strncmp(in->name, "..", sizeof(in->name))) {
-		ou->err = Edot;
-		goto out;
-	}
-	if(checkname(in->name)) {
-		ou->err = Ename;
-		goto out;
-	}
-	addr1 = 0;
-	slot1 = 0;	/* set */
-	for(addr=0;; addr++) {
-		p1 = dnodebuf(p, d, addr, 0);
-		if(!p1) {
-			if(addr1)
-				break;
-			p1 = dnodebuf(p, d, addr, Tdir);
-		}
-		if(p1 == 0) {
-			ou->err = Efull;
-			goto out;
-		}
-		if(checktag(p1, Tdir, d->qid.path)) {
-			putbuf(p1);
-			goto phase;
-		}
-		for(slot=0; slot<DIRPERBUF; slot++) {
-			d1 = getdir(p1, slot);
-			if(!(d1->mode & DALLOC)) {
-				if(!addr1) {
-					addr1 = p1->addr;
-					slot1 = slot + addr*DIRPERBUF;
-				}
-				continue;
-			}
-			if(!strncmp(in->name, d1->name, sizeof(in->name))) {
-				putbuf(p1);
-				ou->err = Eexist;
-				goto out;
-			}
-		}
-		putbuf(p1);
-	}
-	switch(in->mode & 7) {
-	case MEXEC:
-	case MREAD:		/* seems only useful to make directories */
-		fmod = FREAD;
-		break;
-
-	case MWRITE:
-		fmod = FWRITE;
-		break;
-
-	case MBOTH:
-		fmod = FREAD+FWRITE;
-		break;
-
-	default:
-		ou->err = Emode;
-		goto out;
-	}
-	if(in->perm & PDIR)
-		if((in->mode & MTRUNC) || (in->perm & PAPND) || (fmod & FWRITE))
-			goto badaccess;
-	/*
-	 * do it
-	 */
-	path = qidpathgen(&f->fs->dev);
-	p1 = getbuf(f->fs->dev, addr1, Bread|Bimm|Bmod);
-	d1 = getdir(p1, slot1);
-	if(!d1 || checktag(p1, Tdir, d->qid.path)) {
-		if(p1)
-			putbuf(p1);
-		goto phase;
-	}
-	if(d1->mode & DALLOC) {
-		putbuf(p1);
-		goto phase;
-	}
-
-	strncpy(d1->name, in->name, sizeof(in->name));
-	/*
-	 * bogus argument passing -- see console.c
-	 */
-	if(cp == cons.chan) {
-		d1->uid = cons.uid;
-		d1->gid = cons.gid;
-	} else {
-		d1->uid = f->uid;
-		d1->gid = d->gid;
-		in->perm &= d->mode | ~0666;
-		if(in->perm & PDIR)
-			in->perm &= d->mode | ~0777;
-	}
-	d1->qid.path = path;
-	d1->qid.version = 0;
-	d1->mode = DALLOC | (in->perm & 0777);
-	if(in->perm & PDIR) {
-		d1->mode |= DDIR;
-		d1->qid.path |= QPDIR;
-	}
-	if(in->perm & PAPND)
-		d1->mode |= DAPND;
-	t = 0;
-	if(in->perm & PLOCK) {
-		d1->mode |= DLOCK;
-		t = tlocked(p1, d1);
-	}
-	accessdir(p1, d1, FWRITE);
-	mkqid(&qid, d1, 0);
-	putbuf(p1);
-	accessdir(p, d, FWRITE);
-
-	/*
-	 * do a walk to new directory entry
-	 */
-	w = newwp();
-	if(!w) {
-		ou->err = Ewalk;
-		goto out;
-	}
-	w->addr = f->addr;
-	w->slot = f->slot;
-	w->up = f->wpath;
-	f->wpath = w;
-	f->qid = qid;
-	f->tlock = t;
-	f->lastra = 0;
-	if(in->mode & MRCLOSE)
-		fmod |= FREMOV;
-	f->open = fmod;
-	f->addr = addr1;
-	f->slot = slot1;
-	if(t)
-		t->file = f;
-	mkqid9p1(&ou->qid, &qid);
-	goto out;
-
-badaccess:
-	ou->err = Eaccess;
-	goto out;
-
-phase:
-	ou->err = Ephase;
-
-out:
-	if(p)
-		putbuf(p);
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-}
-
-void
-f_read(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p, *p1;
-	File *f;
-	Dentry *d, *d1;
-	Tlock *t;
-	long addr, offset, tim;
-	int nread, count, n, o, slot;
-
-	if(CHAT(cp)) {
-		print("c_read %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-		print("	offset = %ld\n", in->offset);
-		print("	count = %ld\n", in->count);
-	}
-
-	p = 0;
-	count = in->count;
-	offset = in->offset;
-	nread = 0;
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	if(!(f->open & FREAD)) {
-		ou->err = Eopen;
-		goto out;
-	}
-	if(count < 0 || count > MAXDAT) {
-		ou->err = Ecount;
-		goto out;
-	}
-	if(offset < 0) {
-		ou->err = Eoffset;
-		goto out;
-	}
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-	if(t = f->tlock) {
-		tim = time(0);
-		if(t->time < tim || t->file != f) {
-			ou->err = Ebroken;
-			goto out;
-		}
-		/* renew the lock */
-		t->time = tim + TLOCK;
-	}
-	accessdir(p, d, FREAD);
-	if(d->mode & DDIR) {
-		addr = 0;
-		goto dread;
-	}
-	if(offset >= d->size)
-		count = 0;
-	else if(offset+count > d->size)
-		count = d->size - offset;
-	while(count > 0) {
-		addr = offset / BUFSIZE;
-		if(addr == f->lastra+1)
-			dbufread(p, d, addr+1);
-		f->lastra = addr;
-		o = offset % BUFSIZE;
-		n = BUFSIZE - o;
-		if(n > count)
-			n = count;
-		p1 = dnodebuf(p, d, addr, 0);
-		if(p1) {
-			if(checktag(p1, Tfile, QPNONE)) {
-				ou->err = Ephase;
-				putbuf(p1);
-				goto out;
-			}
-			memmove(ou->data+nread, p1->iobuf+o, n);
-			putbuf(p1);
-		} else
-			memset(ou->data+nread, 0, n);
-		count -= n;
-		nread += n;
-		offset += n;
-	}
-	goto out;
-
-dread:
-	p1 = dnodebuf(p, d, addr, 0);
-	if(!p1)
-		goto out;
-	if(checktag(p1, Tdir, QPNONE)) {
-		ou->err = Ephase;
-		putbuf(p1);
-		goto out;
-	}
-	n = DIRREC;
-	for(slot=0; slot<DIRPERBUF; slot++) {
-		d1 = getdir(p1, slot);
-		if(!(d1->mode & DALLOC))
-			continue;
-		if(offset >= n) {
-			offset -= n;
-			continue;
-		}
-		if(count < n) {
-			putbuf(p1);
-			goto out;
-		}
-		if(convD2M9p1(d1, ou->data+nread) != n)
-			print("dirread convD2M\n");
-		nread += n;
-		count -= n;
-	}
-	putbuf(p1);
-	addr++;
-	goto dread;
-
-out:
-	count = in->count - nread;
-	if(count > 0)
-		memset(ou->data+nread, 0, count);
-	if(p)
-		putbuf(p);
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-	ou->count = nread;
-	if(CHAT(cp))
-		print("	nread = %d\n", nread);
-}
-
-void
-f_write(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p, *p1;
-	Dentry *d;
-	File *f;
-	Tlock *t;
-	long offset, addr, tim;
-	int count, nwrite, o, n;
-
-	if(CHAT(cp)) {
-		print("c_write %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-		print("	offset = %ld\n", in->offset);
-		print("	count = %ld\n", in->count);
-	}
-
-	offset = in->offset;
-	count = in->count;
-	nwrite = 0;
-	p = 0;
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	if(!(f->open & FWRITE)) {
-		ou->err = Eopen;
-		goto out;
-	}
-	if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
-		ou->err = Eronly;
-		goto out;
-	}
-	if(count < 0 || count > MAXDAT) {
-		ou->err = Ecount;
-		goto out;
-	}
-	if(offset < 0) {
-		ou->err = Eoffset;
-		goto out;
-	}
-	p = getbuf(f->fs->dev, f->addr, Bread|Bmod);
-	d = getdir(p, f->slot);
-	if(!d || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-	if(t = f->tlock) {
-		tim = time(0);
-		if(t->time < tim || t->file != f) {
-			ou->err = Ebroken;
-			goto out;
-		}
-		/* renew the lock */
-		t->time = tim + TLOCK;
-	}
-	accessdir(p, d, FWRITE);
-	if(d->mode & DAPND)
-		offset = d->size;
-	if(offset+count > d->size)
-		d->size = offset+count;
-	while(count > 0) {
-		addr = offset / BUFSIZE;
-		o = offset % BUFSIZE;
-		n = BUFSIZE - o;
-		if(n > count)
-			n = count;
-		p1 = dnodebuf(p, d, addr, Tfile);
-		if(p1 == 0) {
-			ou->err = Efull;
-			goto out;
-		}
-		if(checktag(p1, Tfile, d->qid.path)) {
-			putbuf(p1);
-			ou->err = Ephase;
-			goto out;
-		}
-		memmove(p1->iobuf+o, in->data+nwrite, n);
-		p1->flags |= Bmod;
-		putbuf(p1);
-		count -= n;
-		nwrite += n;
-		offset += n;
-	}
-	if(CHAT(cp))
-		print("	nwrite = %d\n", nwrite);
-
-out:
-	if(p)
-		putbuf(p);
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-	ou->count = nwrite;
-}
-
-int
-doremove(File *f, int iscon)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1;
-	long addr;
-	int slot, err;
-
-	p = 0;
-	p1 = 0;
-	if(isro(f->fs->dev) || (f->cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
-		err = Eronly;
-		goto out;
-	}
-	/*
-	 * check on parent directory of file to be deleted
-	 */
-	if(f->wpath == 0 || f->wpath->addr == f->addr) {
-		err = Ephase;
-		goto out;
-	}
-	p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
-	d1 = getdir(p1, f->wpath->slot);
-	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
-		err = Ephase;
-		goto out;
-	}
-	if(!iscon && iaccess(f, d1, DWRITE)) {
-		err = Eaccess;
-		goto out;
-	}
-	accessdir(p1, d1, FWRITE);
-	putbuf(p1);
-	p1 = 0;
-
-	/*
-	 * check on file to be deleted
-	 */
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-		err = Ealloc;
-		goto out;
-	}
-	if(err = mkqidcmp(&f->qid, d))
-		goto out;
-
-	/*
-	 * if deleting a directory, make sure it is empty
-	 */
-	if((d->mode & DDIR))
-	for(addr=0;; addr++) {
-		p1 = dnodebuf(p, d, addr, 0);
-		if(!p1)
-			break;
-		if(checktag(p1, Tdir, d->qid.path)) {
-			err = Ephase;
-			goto out;
-		}
-		for(slot=0; slot<DIRPERBUF; slot++) {
-			d1 = getdir(p1, slot);
-			if(!(d1->mode & DALLOC))
-				continue;
-			err = Eempty;
-			goto out;
-		}
-		putbuf(p1);
-	}
-
-	/*
-	 * do it
-	 */
-	dtrunc(p, d);
-	memset(d, 0, sizeof(Dentry));
-	settag(p, Tdir, QPNONE);
-
-out:
-	if(p1)
-		putbuf(p1);
-	if(p)
-		putbuf(p);
-	return err;
-}
-
-void
-f_remove(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	File *f;
-
-	if(CHAT(cp)) {
-		print("c_remove %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-	}
-
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	ou->err = doremove(f, cp==cons.chan);
-
-out:
-	ou->fid = in->fid;
-	if(f)
-		qunlock(f);
-}
-
-void
-f_stat(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p;
-	Dentry *d;
-	File *f;
-
-	if(CHAT(cp)) {
-		print("c_stat %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-	}
-
-	p = 0;
-	memset(ou->stat, 0, sizeof(ou->stat));
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-	if(d->qid.path == QPROOT)	/* stat of root gives time */
-		d->atime = time(0);
-	if(convD2M9p1(d, ou->stat) != DIRREC)
-		print("stat convD2M\n");
-
-out:
-	if(p)
-		putbuf(p);
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-}
-
-void
-f_wstat(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1, xd;
-	File *f;
-	int slot;
-	long addr;
-
-	if(CHAT(cp)) {
-		print("c_wstat %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-	}
-
-	p = 0;
-	p1 = 0;
-	d1 = 0;
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	if(isro(f->fs->dev) || (cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
-		ou->err = Eronly;
-		goto out;
-	}
-
-	/*
-	 * first get parent
-	 */
-	if(f->wpath) {
-		p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
-		d1 = getdir(p1, f->wpath->slot);
-		if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
-			ou->err = Ephase;
-			goto out;
-		}
-	}
-
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-		ou->err = Ealloc;
-		goto out;
-	}
-	if(ou->err = mkqidcmp(&f->qid, d))
-		goto out;
-
-	convM2D9p1(in->stat, &xd);
-	if(CHAT(cp)) {
-		print("	d.name = %s\n", xd.name);
-		print("	d.uid  = %d\n", xd.uid);
-		print("	d.gid  = %d\n", xd.gid);
-		print("	d.mode = %.4x\n", xd.mode);
-	}
-
-	/*
-	 * if chown,
-	 * must be god
-	 */
-	while(xd.uid != d->uid) {
-		if(wstatallow)			/* set to allow chown during boot */
-			break;
-		ou->err = Enotu;
-		goto out;
-	}
-
-	/*
-	 * if chgroup,
-	 * must be either
-	 *	a) owner and in new group
-	 *	b) leader of both groups
-	 */
-	while(xd.gid != d->gid) {
-		if(wstatallow || writeallow)		/* set to allow chgrp during boot */
-			break;
-		if(d->uid == f->uid && ingroup(f->uid, xd.gid))
-			break;
-		if(leadgroup(f->uid, xd.gid))
-			if(leadgroup(f->uid, d->gid))
-				break;
-		ou->err = Enotg;
-		goto out;
-	}
-
-	/*
-	 * if rename,
-	 * must have write permission in parent
-	 */
-	if(xd.name[0] == 0)
-		strncpy(xd.name, d->name, sizeof(xd.name));
-	while(strncmp(d->name, xd.name, sizeof(d->name)) != 0) {
-		if(checkname(xd.name)) {
-			ou->err = Ename;
-			goto out;
-		}
-
-		if(strcmp(xd.name, ".") == 0 || strcmp(xd.name, "..") == 0) {
-			ou->err = Ename;
-			goto out;
-		}
-
-		/*
-		 * drop entry to prevent lock, then
-		 * check that destination name is unique,
-		 */
-		putbuf(p);
-		for(addr=0;; addr++) {
-			p = dnodebuf(p1, d1, addr, 0);
-			if(!p)
-				break;
-			if(checktag(p, Tdir, d1->qid.path)) {
-				putbuf(p);
-				continue;
-			}
-			for(slot=0; slot<DIRPERBUF; slot++) {
-				d = getdir(p, slot);
-				if(!(d->mode & DALLOC))
-					continue;
-				if(!strncmp(xd.name, d->name, sizeof(xd.name))) {
-					ou->err = Eexist;
-					goto out;
-				}
-			}
-			putbuf(p);
-		}
-
-		/*
-		 * reacquire entry
-		 */
-		p = getbuf(f->fs->dev, f->addr, Bread);
-		d = getdir(p, f->slot);
-		if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-			ou->err = Ephase;
-			goto out;
-		}
-
-		if(wstatallow || writeallow) /* set to allow rename during boot */
-			break;
-		if(!d1 || iaccess(f, d1, DWRITE)) {
-			ou->err = Eaccess;
-			goto out;
-		}
-		break;
-	}
-
-	/*
-	 * if mode/time, either
-	 *	a) owner
-	 *	b) leader of either group
-	 */
-	while(d->mtime != xd.mtime ||
-	     ((d->mode^xd.mode) & (DAPND|DLOCK|0777))) {
-		if(wstatallow)			/* set to allow chmod during boot */
-			break;
-		if(d->uid == f->uid)
-			break;
-		if(leadgroup(f->uid, xd.gid))
-			break;
-		if(leadgroup(f->uid, d->gid))
-			break;
-		ou->err = Enotu;
-		goto out;
-	}
-	d->mtime = xd.mtime;
-	d->uid = xd.uid;
-	d->gid = xd.gid;
-	d->mode = (xd.mode & (DAPND|DLOCK|0777)) | (d->mode & (DALLOC|DDIR));
-
-	strncpy(d->name, xd.name, sizeof(d->name));
-	if(wstatallow) {
-		p->flags |= Bmod;
-		if(xd.atime)
-			d->atime = xd.atime;
-		if(xd.mtime)
-			d->mtime = xd.mtime;
-	} else
-		accessdir(p, d, FWSTAT);
-
-out:
-	if(p)
-		putbuf(p);
-	if(p1)
-		putbuf(p1);
-	if(f)
-		qunlock(f);
-	ou->fid = in->fid;
-}
-
-void
-(*call9p1[MAXSYSCALL])(Chan*, Oldfcall*, Oldfcall*) =
-{
-	[Tnop9p1]		f_nop,
-	[Tosession9p1]	f_session,
-	[Tsession9p1]	f_session,
-	[Tflush9p1]	f_flush,
-	[Toattach9p1]	f_attach,
-	[Tattach9p1]	f_attach,
-	[Tclone9p1]	f_clone,
-	[Twalk9p1]		f_walk,
-	[Topen9p1]		f_open,
-	[Tcreate9p1]	f_create,
-	[Tread9p1]		f_read,
-	[Twrite9p1]	f_write,
-	[Tclunk9p1]	f_clunk,
-	[Tremove9p1]	f_remove,
-	[Tstat9p1]		f_stat,
-	[Twstat9p1]	f_wstat,
-	[Tclwalk9p1]	f_clwalk,
-};
-
-static void
-send(Chan *c, uchar *buf, int n)
-{
-	int fd, m;
-
-	fd = c->chan;
-	m = write(fd, buf, n);
-	if(m == n)
-		return;
-	panic("write failed");
-}
-
-void
-error9p1(Chan *c, uchar *buf)
-{
-	buf[0] = Rnop9p1;
-	buf[1] = ~0;
-	buf[2] = ~0;
-
-	send(c, buf, 3);
-}
-
-void
-serve9p1(Chan *chan, uchar *ib, int nib)
-{
-	int n, t;
-	uchar inbuf[MAXMSG+MAXDAT], outbuf[MAXMSG+MAXDAT];
-	Oldfcall fi, fo;
-
-	for(;;){
-		if(nib){
-			memmove(inbuf, ib, nib);
-			n = nib;
-			nib = 0;
-		}else
-			n = read(chan->chan, inbuf, sizeof inbuf);
-		if(chat)
-			print("read msg %d\n", n);
-		if(n == 0 && (chan == cons.srvchan || chan == cons.chan))
-			continue;
-		if(n <= 0)
-			return;
-		if(convM2S9p1(inbuf, &fi, n) != n){
-			error9p1(chan, outbuf);
-			continue;
-		}
-
-		t = fi.type;
-		if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
-			print("9p1: bad message type\n");
-			error9p1(chan, outbuf);
-			continue;
-		}
-
-		if(CHAT(chan))
-			print("9p1: fi %O\n", &fi);
-
-		/*
-		 * set up reply message
-		 */
-		fo.err = 0;
-		if(t == Tread9p1)
-			fo.data = (char*)outbuf + 8;
-	
-		/*
-		 * call the file system
-		 */
-		cons.work.count++;
-		cons.rate.count += n;
-
-		/*
-		 * call the file system
-		 */
-		rlock(&mainlock);
-		rlock(&chan->reflock);
-	
-		(*call9p1[t])(chan, &fi, &fo);
-	
-		runlock(&chan->reflock);
-		runlock(&mainlock);
-	
-		fo.type = t+1;
-		fo.tag = fi.tag;
-	
-		if(chat)
-			print("9p1: fo %O\n", &fo);
-
-		if(fo.err) {
-			strcpy(fo.ename, errstring[fo.err]);
-			if(CHAT(cp))
-				print("	error: %s\n", fo.ename);
-			fo.type = Terror9p1+1;
-		}
-	
-		n = convS2M9p1(&fo, outbuf);
-		if(n == 0) {
-			print("9p1: bad S2M conversion\n");
-			error9p1(chan, outbuf);
-			continue;
-		}
-
-		cons.rate.count += n;
-		send(chan, outbuf, n);
-	}
-}
--- a/sys/src/cmd/disk/kfs/9p1.h
+++ /dev/null
@@ -1,113 +1,0 @@
-#define	DIRREC		116		/* size of a directory ascii record */
-#define	ERRREC		64		/* size of a error record */
-#define	MAXMSG		160	/* max header sans data */
-
-typedef	struct	Oldfcall	Oldfcall;
-
-struct	Oldfcall
-{
-	char	type;
-	ushort	fid;
-	short	err;
-	short	tag;
-	union
-	{
-		struct
-		{
-			short	uid;		/* T-Userstr */
-			short	oldtag;		/* T-nFlush */
-			Qid9p1	qid;		/* R-Attach, R-Clwalk, R-Walk,
-						 * R-Open, R-Create */
-			char	rauth[AUTHENTLEN];	/* R-attach */
-		};
-		struct
-		{
-			char	uname[NAMELEN];	/* T-nAttach */
-			char	aname[NAMELEN];	/* T-nAttach */
-			char	ticket[TICKETLEN];	/* T-attach */
-			char	auth[AUTHENTLEN];	/* T-attach */
-		};
-		struct
-		{
-			char	ename[ERRREC];	/* R-nError */
-			char	chal[CHALLEN];	/* T-session, R-session */
-			char	authid[NAMELEN];	/* R-session */
-			char	authdom[DOMLEN];	/* R-session */
-		};
-		struct
-		{
-			char	name[NAMELEN];	/* T-Walk, T-Clwalk, T-Create, T-Remove */
-			long	perm;		/* T-Create */
-			ushort	newfid;		/* T-Clone, T-Clwalk */
-			char	mode;		/* T-Create, T-Open */
-		};
-		struct
-		{
-			long	offset;		/* T-Read, T-Write */
-			long	count;		/* T-Read, T-Write, R-Read */
-			char*	data;		/* T-Write, R-Read */
-		};
-		struct
-		{
-			char	stat[DIRREC];	/* T-Wstat, R-Stat */
-		};
-	};
-};
-
-/*
- * P9 protocol message types
- */
-enum
-{
-	Tnop9p1 =		50,
-	Rnop9p1,
-	Tosession9p1 =	52,
-	Rosession9p1,
-	Terror9p1 =	54,	/* illegal */
-	Rerror9p1,
-	Tflush9p1 =	56,
-	Rflush9p1,
-	Toattach9p1 =	58,
-	Roattach9p1,
-	Tclone9p1 =	60,
-	Rclone9p1,
-	Twalk9p1 =		62,
-	Rwalk9p1,
-	Topen9p1 =		64,
-	Ropen9p1,
-	Tcreate9p1 =	66,
-	Rcreate9p1,
-	Tread9p1 =		68,
-	Rread9p1,
-	Twrite9p1 =	70,
-	Rwrite9p1,
-	Tclunk9p1 =	72,
-	Rclunk9p1,
-	Tremove9p1 =	74,
-	Rremove9p1,
-	Tstat9p1 =		76,
-	Rstat9p1,
-	Twstat9p1 =	78,
-	Rwstat9p1,
-	Tclwalk9p1 =	80,
-	Rclwalk9p1,
-	Tauth9p1 =		82,	/* illegal */
-	Rauth9p1,			/* illegal */
-	Tsession9p1 =	84,
-	Rsession9p1,
-	Tattach9p1 =	86,
-	Rattach9p1,
-
-	MAXSYSCALL
-};
-
-int	convD2M9p1(Dentry*, char*);
-int	convM2D9p1(char*, Dentry*);
-int	convM2S9p1(uchar*, Oldfcall*, int);
-int	convS2M9p1(Oldfcall*, uchar*);
-void	fcall9p1(Chan*, Oldfcall*, Oldfcall*);
-int	authorize(Chan*, Oldfcall*, Oldfcall*);
-
-void	(*call9p1[MAXSYSCALL])(Chan*, Oldfcall*, Oldfcall*);
-
-extern Nvrsafe nvr;
--- a/sys/src/cmd/disk/kfs/9p12.c
+++ /dev/null
@@ -1,114 +1,0 @@
-#include "all.h"
-
-static int
-readmsg(Chan *c, void *abuf, int n, int *ninep)
-{
-	int fd, len;
-	uchar *buf;
-
-	buf = abuf;
-	fd = c->chan;
-	qlock(&c->rlock);
-	if(readn(fd, buf, 3) != 3){
-		qunlock(&c->rlock);
-		print("readn(3) fails: %r\n");
-		return -1;
-	}
-	if((50 <= buf[0] && buf[0] <= 87 && (buf[0]&1)==0 && GBIT16(buf+1) == 0xFFFF)
-	|| buf[0] == 86	/* Tattach */){
-		*ninep = 1;
-		/* assume message boundaries */
-		n = read(fd, buf+3, n-3);
-		if(n < 0){
-			qunlock(&c->rlock);
-			return -1;
-		}
-		return n+3;
-	}
-
-	*ninep = 2;
-	if(read(fd, buf+3, 1) != 1){
-		qunlock(&c->rlock);
-		print("read(1) fails: %r\n");
-		return -1;
-	}
-	len = GBIT32(buf);
-	if(len > n){
-		print("msg too large\n");
-		qunlock(&c->rlock);
-		return -1;
-	}
-	if(readn(fd, buf+4, len-4) != len-4){
-		print("readn(%d) fails: %r\n", len-4);
-		qunlock(&c->rlock);
-		return -1;
-	}
-	qunlock(&c->rlock);
-	return len;
-}
-
-int
-startserveproc(void (*f)(Chan*, uchar*, int), char *name, Chan *c, uchar *b, int nb)
-{
-	int pid;
-
-	switch(pid = rfork(RFMEM|RFPROC)){
-	case -1:
-		panic("can't fork");
-	case 0:
-		break;
-	default:
-		return pid;
-	}
-	procname = name;
-	f(c, b, nb);
-	_exits(nil);
-	return -1;	/* can't happen */
-}
-
-void
-serve(Chan *chan)
-{
-	int i, nin, p9, npid;
-	uchar inbuf[1024];
-	void (*s)(Chan*, uchar*, int);
-	int *pid;
-	Waitmsg *w;
-
-	p9 = 0;
-	if((nin = readmsg(chan, inbuf, sizeof inbuf, &p9)) < 0)
-		return;
-
-	switch(p9){
-	default:
-		print("unknown 9P type\n");
-		return;
-	case 1:
-		s = serve9p1;
-		break;
-	case 2:
-		s = serve9p2;
-		break;
-	}
-
-	pid = malloc(sizeof(pid)*(conf.nserve-1));
-	if(pid == nil)
-		return;
-	for(i=1; i<conf.nserve; i++)
-		pid[i-1] = startserveproc(s, "srv", chan, nil, 0);
-
-	(*s)(chan, inbuf, nin);
-
-	/* wait till all other servers for this chan are done */
-	for(npid = conf.nserve-1; npid > 0;){
-		w = wait();
-		if(w == 0)
-			break;
-		for(i = 0; i < conf.nserve-1; i++)
-			if(pid[i] == w->pid)
-				npid--;
-		free(w);
-	}
-	free(pid);
-}
-
--- a/sys/src/cmd/disk/kfs/9p1lib.c
+++ /dev/null
@@ -1,461 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-#define	CHAR(x)		*p++ = f->x
-#define	SHORT(x)	{ ulong vvv = f->x; p[0] = vvv; p[1] = vvv>>8; p += 2; }
-#define	VLONG(q)	p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4
-#define	LONG(x)		{ ulong vvv = f->x; VLONG(vvv); }
-#define	BYTES(x,n)	memmove(p, f->x, n); p += n
-#define	STRING(x,n)	strncpy((char*)p, f->x, n); p += n
-
-int
-convS2M9p1(Oldfcall *f, uchar *ap)
-{
-	uchar *p;
-	int t;
-
-	p = ap;
-	CHAR(type);
-	t = f->type;
-	SHORT(tag);
-	switch(t)
-	{
-	default:
-		print("convS2M9p1: bad type: %d\n", t);
-		return 0;
-
-	case Tnop9p1:
-	case Tosession9p1:
-		break;
-
-	case Tsession9p1:
-		BYTES(chal, sizeof(f->chal));
-		break;
-
-	case Tflush9p1:
-		SHORT(oldtag);
-		break;
-
-	case Tattach9p1:
-		SHORT(fid);
-		STRING(uname, sizeof(f->uname));
-		STRING(aname, sizeof(f->aname));
-		BYTES(ticket, sizeof(f->ticket));
-		BYTES(auth, sizeof(f->auth));
-		break;
-
-	case Toattach9p1:
-		SHORT(fid);
-		STRING(uname, sizeof(f->uname));
-		STRING(aname, sizeof(f->aname));
-		BYTES(ticket, NAMELEN);
-		break;
-
-	case Tclone9p1:
-		SHORT(fid);
-		SHORT(newfid);
-		break;
-
-	case Twalk9p1:
-		SHORT(fid);
-		STRING(name, sizeof(f->name));
-		break;
-
-	case Tclwalk9p1:
-		SHORT(fid);
-		SHORT(newfid);
-		STRING(name, sizeof(f->name));
-		break;
-
-	case Topen9p1:
-		SHORT(fid);
-		CHAR(mode);
-		break;
-
-	case Tcreate9p1:
-		SHORT(fid);
-		STRING(name, sizeof(f->name));
-		LONG(perm);
-		CHAR(mode);
-		break;
-
-	case Tread9p1:
-		SHORT(fid);
-		LONG(offset); VLONG(0);
-		SHORT(count);
-		break;
-
-	case Twrite9p1:
-		SHORT(fid);
-		LONG(offset); VLONG(0);
-		SHORT(count);
-		p++;
-		if((uchar*)p == (uchar*)f->data) {
-			p += f->count;
-			break;
-		}
-		BYTES(data, f->count);
-		break;
-
-	case Tclunk9p1:
-	case Tremove9p1:
-	case Tstat9p1:
-		SHORT(fid);
-		break;
-
-	case Twstat9p1:
-		SHORT(fid);
-		BYTES(stat, sizeof(f->stat));
-		break;
-/*
- */
-	case Rnop9p1:
-	case Rosession9p1:
-	case Rflush9p1:
-		break;
-
-	case Rsession9p1:
-		BYTES(chal, sizeof(f->chal));
-		BYTES(authid, sizeof(f->authid));
-		BYTES(authdom, sizeof(f->authdom));
-		break;
-
-	case Rerror9p1:
-		STRING(ename, sizeof(f->ename));
-		break;
-
-	case Rclone9p1:
-	case Rclunk9p1:
-	case Rremove9p1:
-	case Rwstat9p1:
-		SHORT(fid);
-		break;
-
-	case Rwalk9p1:
-	case Ropen9p1:
-	case Rcreate9p1:
-	case Rclwalk9p1:
-		SHORT(fid);
-		LONG(qid.path);
-		LONG(qid.version);
-		break;
-
-	case Rattach9p1:
-		SHORT(fid);
-		LONG(qid.path);
-		LONG(qid.version);
-		BYTES(rauth, sizeof(f->rauth));
-		break;
-
-	case Roattach9p1:
-		SHORT(fid);
-		LONG(qid.path);
-		LONG(qid.version);
-		break;
-
-	case Rread9p1:
-		SHORT(fid);
-		SHORT(count);
-		p++;
-		if((uchar*)p == (uchar*)f->data) {
-			p += f->count;
-			break;
-		}
-		BYTES(data, f->count);
-		break;
-
-	case Rwrite9p1:
-		SHORT(fid);
-		SHORT(count);
-		break;
-
-	case Rstat9p1:
-		SHORT(fid);
-		BYTES(stat, sizeof(f->stat));
-		break;
-	}
-	return p - (uchar*)ap;
-}
-
-/*
- * buggery to give false qid for
- * the top 2 levels of the dump fs
- */
-static ulong
-fakeqid9p1(Dentry *f)
-{
-	ulong q;
-	int c;
-
-	q = f->qid.path;
-	if(q == (QPROOT|QPDIR)) {
-		c = f->name[0];
-		if(c >= '0' && c <= '9') {
-			q = 3|QPDIR;
-			c = (c-'0')*10 + (f->name[1]-'0');
-			if(c >= 1 && c <= 12)
-				q = 4|QPDIR;
-		}
-	}
-	return q;
-}
-
-int
-convD2M9p1(Dentry *f, char *ap)
-{
-	uchar *p;
-	ulong q;
-
-	p = (uchar*)ap;
-	STRING(name, sizeof(f->name));
-
-	memset(p, 0, 2*NAMELEN);
-	uidtostr((char*)p, f->uid);
-	p += NAMELEN;
-
-	uidtostr((char*)p, f->gid);
-	p += NAMELEN;
-
-	q = fakeqid9p1(f);
-	VLONG(q);
-	LONG(qid.version);
-	{
-		q = f->mode & 0x0fff;
-		if(f->mode & DDIR)
-			q |= PDIR;
-		if(f->mode & DAPND)
-			q |= PAPND;
-		if(f->mode & DLOCK)
-			q |= PLOCK;
-		VLONG(q);
-	}
-	LONG(atime);
-	LONG(mtime);
-	LONG(size); VLONG(0);
-	VLONG(0);
-	return p - (uchar*)ap;
-}
-
-#undef	CHAR
-#undef	SHORT
-#undef	LONG
-#undef	VLONG
-#undef	BYTES
-#undef	STRING
-
-#define	CHAR(x)		f->x = *p++
-#define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
-#define	VLONG(q)	q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4
-#define	LONG(x)		VLONG(f->x)
-#define	BYTES(x,n)	memmove(f->x, p, n); p += n
-#define	STRING(x,n)	memmove(f->x, p, n); p += n
-
-int
-convM2S9p1(uchar *ap, Oldfcall *f, int n)
-{
-	uchar *p;
-	int t;
-
-	p = ap;
-	CHAR(type);
-	t = f->type;
-	SHORT(tag);
-	switch(t)
-	{
-	default:
-		/*
-		 * only whine if it couldn't be a 9P2000 Tversion9p1.
-		 */
-		if(t != 19 || ap[4] != 100)
-			print("convM2S9p1: bad type: %d\n", f->type);
-		return 0;
-
-	case Tnop9p1:
-	case Tosession9p1:
-		break;
-
-	case Tsession9p1:
-		BYTES(chal, sizeof(f->chal));
-		break;
-
-	case Tflush9p1:
-		SHORT(oldtag);
-		break;
-
-	case Tattach9p1:
-		SHORT(fid);
-		BYTES(uname, sizeof(f->uname));
-		BYTES(aname, sizeof(f->aname));
-		BYTES(ticket, sizeof(f->ticket));
-		BYTES(auth, sizeof(f->auth));
-		break;
-
-	case Toattach9p1:
-		SHORT(fid);
-		BYTES(uname, sizeof(f->uname));
-		BYTES(aname, sizeof(f->aname));
-		BYTES(ticket, NAMELEN);
-		break;
-
-	case Tclone9p1:
-		SHORT(fid);
-		SHORT(newfid);
-		break;
-
-	case Twalk9p1:
-		SHORT(fid);
-		BYTES(name, sizeof(f->name));
-		break;
-
-	case Tclwalk9p1:
-		SHORT(fid);
-		SHORT(newfid);
-		BYTES(name, sizeof(f->name));
-		break;
-
-	case Tremove9p1:
-		SHORT(fid);
-		break;
-
-	case Topen9p1:
-		SHORT(fid);
-		CHAR(mode);
-		break;
-
-	case Tcreate9p1:
-		SHORT(fid);
-		BYTES(name, sizeof(f->name));
-		LONG(perm);
-		CHAR(mode);
-		break;
-
-	case Tread9p1:
-		SHORT(fid);
-		LONG(offset); p += 4;
-		SHORT(count);
-		break;
-
-	case Twrite9p1:
-		SHORT(fid);
-		LONG(offset); p += 4;
-		SHORT(count);
-		p++;
-		f->data = (char*)p; p += f->count;
-		break;
-
-	case Tclunk9p1:
-	case Tstat9p1:
-		SHORT(fid);
-		break;
-
-	case Twstat9p1:
-		SHORT(fid);
-		BYTES(stat, sizeof(f->stat));
-		break;
-
-/*
- */
-	case Rnop9p1:
-	case Rosession9p1:
-		break;
-
-	case Rsession9p1:
-		BYTES(chal, sizeof(f->chal));
-		BYTES(authid, sizeof(f->authid));
-		BYTES(authdom, sizeof(f->authdom));
-		break;
-
-	case Rerror9p1:
-		BYTES(ename, sizeof(f->ename));
-		break;
-
-	case Rflush9p1:
-		break;
-
-	case Rclone9p1:
-	case Rclunk9p1:
-	case Rremove9p1:
-	case Rwstat9p1:
-		SHORT(fid);
-		break;
-
-	case Rwalk9p1:
-	case Rclwalk9p1:
-	case Ropen9p1:
-	case Rcreate9p1:
-		SHORT(fid);
-		LONG(qid.path);
-		LONG(qid.version);
-		break;
-
-	case Rattach9p1:
-		SHORT(fid);
-		LONG(qid.path);
-		LONG(qid.version);
-		BYTES(rauth, sizeof(f->rauth));
-		break;
-
-	case Roattach9p1:
-		SHORT(fid);
-		LONG(qid.path);
-		LONG(qid.version);
-		break;
-
-	case Rread9p1:
-		SHORT(fid);
-		SHORT(count);
-		p++;
-		f->data = (char*)p; p += f->count;
-		break;
-
-	case Rwrite9p1:
-		SHORT(fid);
-		SHORT(count);
-		break;
-
-	case Rstat9p1:
-		SHORT(fid);
-		BYTES(stat, sizeof(f->stat));
-		break;
-	}
-	if((uchar*)ap+n == p)
-		return n;
-	return 0;
-}
-
-int
-convM2D9p1(char *ap, Dentry *f)
-{
-	uchar *p;
-	char str[28];
-
-	p = (uchar*)ap;
-	BYTES(name, sizeof(f->name));
-
-	memmove(str, p, NAMELEN);
-	p += NAMELEN;
-	f->uid = strtouid(str);
-
-	memmove(str, p, NAMELEN);
-	p += NAMELEN;
-	f->gid = strtouid(str);
-
-	LONG(qid.path);
-	LONG(qid.version);
-	{
-		LONG(atime);
-		f->mode = (f->atime & 0x0fff) | DALLOC;
-		if(f->atime & PDIR)
-			f->mode |= DDIR;
-		if(f->atime & PAPND)
-			f->mode |= DAPND;
-		if(f->atime & PLOCK)
-			f->mode |= DLOCK;
-	}
-	LONG(atime);
-	LONG(mtime);
-	LONG(size); p += 4;
-	p += 4;
-	return p - (uchar*)ap;
-}
-
--- a/sys/src/cmd/disk/kfs/9p2.c
+++ /dev/null
@@ -1,1870 +1,0 @@
-#include	"all.h"
-
-#define MSIZE	(MAXDAT+128)
-
-static void
-seterror(Fcall *ou, int err)
-{
-
-	if(0 <= err && err < MAXERR)
-		ou->ename = errstring[err];
-	else
-		ou->ename = "unknown error";
-}
-
-static int
-fsversion(Chan* chan, Fcall* f, Fcall* r)
-{
-	if(f->msize < 256)
-		return Econvert;
-
-	if(f->msize < MSIZE)
-		r->msize = f->msize;
-	else
-		r->msize = MSIZE;
-	/*
-	 * Should check the '.' stuff here.
-	 * What happens if Tversion has already been seen?
-	 */
-	if(strcmp(f->version, VERSION9P) == 0){
-		r->version = VERSION9P;
-		chan->msize = r->msize;
-	}else
-		r->version = "unknown";
-
-	fileinit(chan);
-	return 0;
-}
-
-char *keyspec = "proto=p9any role=server";
-
-static int
-fsauth(Chan *chan, Fcall *f, Fcall *r)
-{
-	int err, fd;
-	char *aname;
-	File *file;
-	int afd;
-	AuthRpc *rpc;
-
-	err = 0;
-	if(chan == cons.srvchan)
-		return Eauthmsg;
-	file = filep(chan, f->afid, 1);
-	if(file == nil)
-		return Efidinuse;
-
-	/* forget any previous authentication */
-	file->cuid = 0;
-
-	if(access("/mnt/factotum", 0) < 0)
-		if((fd = open("/srv/factotum", ORDWR)) >= 0)
-			mount(fd, -1, "/mnt", MBEFORE, "");
-
-	afd = open("/mnt/factotum/rpc", ORDWR);
-	if(afd < 0){
-		err = Esystem;
-		goto out;
-	}
-	rpc = auth_allocrpc(afd);
-	if(rpc == nil){
-		close(afd);
-		err = Esystem;
-		goto out;
-	}
-	file->rpc = rpc;
-	if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
-		err = Esystem;
-		goto out;
-	}
-
-	aname = f->aname;
-	if(!aname[0])
-		aname = "main";
-	file->fs = fsstr(aname);
-	if(file->fs == nil){
-		err = Ebadspc;
-		goto out;
-	}
-	file->uid = strtouid(f->uname);
-	if(file->uid < 0){
-		err = Ebadu;
-		goto out;
-	}
-	file->qid.path = 0;
-	file->qid.vers = 0;
-	file->qid.type = QTAUTH;
-	r->qid = file->qid;
-
-out:
-	if(file != nil){
-		qunlock(file);
-		if(err != 0)
-			freefp(file);
-	}
-	return err;
-}
-
-int
-authread(File *file, uchar *data, int count)
-{
-	AuthInfo *ai;
-	AuthRpc *rpc;
-	int rv;
-
-	rpc = file->rpc;
-	if(rpc == nil)
-		return -1;
-
-	rv = auth_rpc(rpc, "read", nil, 0);
-	switch(rv){
-	case ARdone:
-		ai = auth_getinfo(rpc);
-		if(ai == nil)
-			return -1;
-		if(chat)
-			print("authread identifies user as %s\n", ai->cuid);
-		file->cuid = strtouid(ai->cuid);
-		auth_freeAI(ai);
-		if(file->cuid == 0)
-			return -1;
-		if(chat)
-			print("%s is a known user\n", ai->cuid);
-		return 0;
-	case ARok:
-		if(count < rpc->narg)
-			return -1;
-		memmove(data, rpc->arg, rpc->narg);
-		return rpc->narg;
-	case ARphase:
-		return -1;
-	default:
-		return -1;
-	}
-}
-
-int
-authwrite(File *file, uchar *data, int count)
-{
-	int ret;
-
-	ret = auth_rpc(file->rpc, "write", data, count);
-	if(ret != ARok)
-		return -1;
-	return count;
-}
-
-void
-mkqid9p1(Qid9p1* qid9p1, Qid* qid)
-{
-	if(qid->path & 0xFFFFFFFF00000000LL)
-		panic("mkqid9p1: path %lluX\n", qid->path);
-	qid9p1->path = qid->path & 0xFFFFFFFF;
-	if(qid->type & QTDIR)
-		qid9p1->path |= QPDIR;
-	qid9p1->version = qid->vers;
-}
-
-void
-authfree(File *fp)
-{
-	if(fp->rpc != nil){
-		close(fp->rpc->afd);
-		free(fp->rpc);
-		fp->rpc = nil;
-	}
-}
-
-void
-mkqid9p2(Qid* qid, Qid9p1* qid9p1, int mode)
-{
-	qid->path = (ulong)(qid9p1->path & ~QPDIR);
-	qid->vers = qid9p1->version;
-	qid->type = 0;
-	if(mode & DDIR)
-		qid->type |= QTDIR;
-	if(mode & DAPND)
-		qid->type |= QTAPPEND;
-	if(mode & DLOCK)
-		qid->type |= QTEXCL;
-}
-
-static int
-checkattach(Chan *chan, File *afile, File *file, Filsys *fs)
-{
-	uchar buf[1];
-
-	if(chan == cons.srvchan || chan == cons.chan)
-		return 0;
-
-	/* if no afile, this had better be none */
-	if(afile == nil){
-		if(file->uid == 0){
-			if(!allownone && !chan->authed)
-				return Eauth;
-			return 0;
-		}
-		return Eauth;
-	}
-
-	/* otherwise, we'ld better have a usable cuid */
-	if(!(afile->qid.type&QTAUTH))
-		return Eauth;
-	if(afile->uid != file->uid || afile->fs != fs)
-		return Eauth;
-	if(afile->cuid <= 0){
-		if(authread(afile, buf, 0) != 0)
-			return Eauth;
-		if(afile->cuid <= 0)
-			return Eauth;
-	}
-	file->uid = afile->cuid;
-
-	/* once someone has authenticated on the channel, others can become none */
-	chan->authed = 1;
-
-	return 0;
-}		
-
-static int
-fsattach(Chan* chan, Fcall* f, Fcall* r)
-{
-	char *aname;
-	Iobuf *p;
-	Dentry *d;
-	File *file;
-	File *afile;
-	Filsys *fs;
-	long raddr;
-	int error, u;
-
-	aname = f->aname;
-	if(!aname[0])	/* default */
-		aname = "main";
-	p = nil;
-	afile = filep(chan, f->afid, 0);
-	file = filep(chan, f->fid, 1);
-	if(file == nil){
-		error = Efidinuse;
-		goto out;
-	}
-
-	u = -1;
-	if(chan != cons.chan){
-		if(strcmp(f->uname, "adm") == 0){
-			error = Eauth;
-			goto out;
-		}
-		u = strtouid(f->uname);
-		if(u < 0){
-			error = Ebadu;
-			goto out;
-		}
-	}
-	file->uid = u;
-
-	fs = fsstr(aname);
-	if(fs == nil){
-		error = Ebadspc;
-		goto out;
-	}
-
-	if(error = checkattach(chan, afile, file, fs))
-		goto out;
-
-	raddr = getraddr(fs->dev);
-	p = getbuf(fs->dev, raddr, Bread);
-	d = getdir(p, 0);
-	if(d == nil || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(iaccess(file, d, DEXEC)){
-		error = Eaccess;
-		goto out;
-	}
-	if(file->uid == 0 && isro(fs->dev)) {
-		/*
-		 * 'none' not allowed on dump
-		 */
-		error = Eaccess;
-		goto out;
-	}
-	accessdir(p, d, FREAD);
-	mkqid(&file->qid, d, 1);
-	file->fs = fs;
-	file->addr = raddr;
-	file->slot = 0;
-	file->open = 0;
-	freewp(file->wpath);
-	file->wpath = 0;
-
-	r->qid = file->qid;
-
-//	if(cons.flags & attachflag)
-//		print("9p2: attach %s %T to \"%s\" C%d\n",
-//			chan->whoname, chan->whotime, fs->name, chan->chan);
-
-out:
-//	if((cons.flags & attachflag) && error)
-//		print("9p2: attach %s %T SUCK EGGS --- %s\n",
-//			f->uname, time(), errstr[error]);
-	if(p != nil)
-		putbuf(p);
-	if(afile != nil)
-		qunlock(afile);
-	if(file != nil){
-		qunlock(file);
-		if(error)
-			freefp(file);
-	}
-
-	return error;
-}
-
-static int
-fsflush(Chan* chan, Fcall*, Fcall*)
-{
-	runlock(&chan->reflock);
-	wlock(&chan->reflock);
-	wunlock(&chan->reflock);
-	rlock(&chan->reflock);
-
-	return 0;
-}
-
-static void
-clone(File* nfile, File* file)
-{
-	Wpath *wpath;
-
-	nfile->qid = file->qid;
-
-	lock(&wpathlock);
-	nfile->wpath = file->wpath;
-	for(wpath = nfile->wpath; wpath != nil; wpath = wpath->up)
-		wpath->refs++;
-	unlock(&wpathlock);
-
-	nfile->fs = file->fs;
-	nfile->addr = file->addr;
-	nfile->slot = file->slot;
-	nfile->uid = file->uid;
-	nfile->cuid = 0;
-	nfile->open = file->open & ~FREMOV;
-}
-
-static int
-walkname(File* file, char* wname, Qid* wqid)
-{
-	Wpath *w;
-	Iobuf *p, *p1;
-	Dentry *d, *d1;
-	int error, slot;
-	long addr, qpath;
-
-	p = p1 = nil;
-
-	/*
-	 * File must not have been opened for I/O by an open
-	 * or create message and must represent a directory.
-	 */
-	if(file->open != 0){
-		error = Emode;
-		goto out;
-	}
-
-	p = getbuf(file->fs->dev, file->addr, Bread);
-	if(p == nil || checktag(p, Tdir, QPNONE)){
-		error = Edir1;
-		goto out;
-	}
-	if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(!(d->mode & DDIR)){
-		error = Edir1;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-
-	/*
-	 * For walked elements the implied user must
-	 * have permission to search the directory.
-	 */
-	if(file->cp != cons.chan && iaccess(file, d, DEXEC)){
-		error = Eaccess;
-		goto out;
-	}
-	accessdir(p, d, FREAD);
-
-	if(strcmp(wname, ".") == 0){
-setdot:
-		if(wqid != nil)
-			*wqid = file->qid;
-		goto out;
-	}
-	if(strcmp(wname, "..") == 0){
-		if(file->wpath == 0)
-			goto setdot;
-		putbuf(p);
-		p = nil;
-		addr = file->wpath->addr;
-		slot = file->wpath->slot;
-		p1 = getbuf(file->fs->dev, addr, Bread);
-		if(p1 == nil || checktag(p1, Tdir, QPNONE)){
-			error = Edir1;
-			goto out;
-		}
-		if((d1 = getdir(p1, slot)) == nil || !(d1->mode & DALLOC)){
-			error = Ephase;
-			goto out;
-		}
-		lock(&wpathlock);
-		file->wpath->refs--;
-		file->wpath = file->wpath->up;
-		unlock(&wpathlock);
-		goto found;
-	}
-
-	for(addr = 0; ; addr++){
-		if(p == nil){
-			p = getbuf(file->fs->dev, file->addr, Bread);
-			if(p == nil || checktag(p, Tdir, QPNONE)){
-				error = Ealloc;
-				goto out;
-			}
-			d = getdir(p, file->slot);
-			if(d == nil ||  !(d->mode & DALLOC)){
-				error = Ealloc;
-				goto out;
-			}
-		}
-		qpath = d->qid.path;
-		p1 = dnodebuf1(p, d, addr, 0);
-		p = nil;
-		if(p1 == nil || checktag(p1, Tdir, qpath)){
-			error = Eentry;
-			goto out;
-		}
-		for(slot = 0; slot < DIRPERBUF; slot++){
-			d1 = getdir(p1, slot);
-			if(!(d1->mode & DALLOC))
-				continue;
-			if(strncmp(wname, d1->name, NAMELEN) != 0)
-				continue;
-			/*
-			 * update walk path
-			 */
-			if((w = newwp()) == nil){
-				error = Ewalk;
-				goto out;
-			}
-			w->addr = file->addr;
-			w->slot = file->slot;
-			w->up = file->wpath;
-			file->wpath = w;
-			slot += DIRPERBUF*addr;
-			goto found;
-		}
-		putbuf(p1);
-		p1 = nil;
-	}
-
-found:
-	file->addr = p1->addr;
-	mkqid(&file->qid, d1, 1);
-	putbuf(p1);
-	p1 = nil;
-	file->slot = slot;
-	if(wqid != nil)
-		*wqid = file->qid;
-
-out:
-	if(p1 != nil)
-		putbuf(p1);
-	if(p != nil)
-		putbuf(p);
-
-	return error;
-}
-
-static int
-fswalk(Chan* chan, Fcall* f, Fcall* r)
-{
-	int error, nwname;
-	File *file, *nfile, tfile;
-
-	/*
-	 * The file identified by f->fid must be valid in the
-	 * current session and must not have been opened for I/O
-	 * by an open or create message.
-	 */
-	if((file = filep(chan, f->fid, 0)) == nil)
-		return Efid;
-	if(file->open != 0){
-		qunlock(file);
-		return Emode;
-	}
-
-	/*
-	 * If newfid is not the same as fid, allocate a new file;
-	 * a side effect is checking newfid is not already in use (error);
-	 * if there are no names to walk this will be equivalent to a
-	 * simple 'clone' operation.
-	 * Otherwise, fid and newfid are the same and if there are names
-	 * to walk make a copy of 'file' to be used during the walk as
-	 * 'file' must only be updated on success.
-	 * Finally, it's a no-op if newfid is the same as fid and f->nwname
-	 * is 0.
-	 */
-	r->nwqid = 0;
-	if(f->newfid != f->fid){
-		if((nfile = filep(chan, f->newfid, 1)) == nil){
-			qunlock(file);
-			return Efidinuse;
-		}
-	}
-	else if(f->nwname != 0){
-		nfile = &tfile;
-		memset(nfile, 0, sizeof(File));
-		nfile->cp = chan;
-		nfile->fid = ~0;
-	}
-	else{
-		qunlock(file);
-		return 0;
-	}
-	clone(nfile, file);
-
-	/*
-	 * Should check name is not too long.
-	 */
-	error = 0;
-	for(nwname = 0; nwname < f->nwname; nwname++){
-		error = walkname(nfile, f->wname[nwname], &r->wqid[r->nwqid]);
-		if(error != 0 || ++r->nwqid >= MAXDAT/sizeof(Qid))
-			break;
-	}
-
-	if(f->nwname == 0){
-		/*
-		 * Newfid must be different to fid (see above)
-		 * so this is a simple 'clone' operation - there's
-		 * nothing to do except unlock unless there's
-		 * an error.
-		 */
-		if(error){
-			freewp(nfile->wpath);
-			qunlock(nfile);
-			freefp(nfile);
-		}
-		else
-			qunlock(nfile);
-	}
-	else if(r->nwqid < f->nwname){
-		/*
-		 * Didn't walk all elements, 'clunk' nfile
-		 * and leave 'file' alone.
-		 * Clear error if some of the elements were
-		 * walked OK.
-		 */
-		freewp(nfile->wpath);
-		if(nfile != &tfile){
-			qunlock(nfile);
-			freefp(nfile);
-		}
-		if(r->nwqid != 0)
-			error = 0;
-	}
-	else{
-		/*
-		 * Walked all elements. If newfid is the same
-		 * as fid must update 'file' from the temporary
-		 * copy used during the walk.
-		 * Otherwise just unlock (when using tfile there's
-		 * no need to unlock as it's a local).
-		 */
-		if(nfile == &tfile){
-			file->qid = nfile->qid;
-			freewp(file->wpath);
-			file->wpath = nfile->wpath;
-			file->addr = nfile->addr;
-			file->slot = nfile->slot;
-		}
-		else
-			qunlock(nfile);
-	}
-	qunlock(file);
-
-	return error;
-}
-
-static int
-fsopen(Chan* chan, Fcall* f, Fcall* r)
-{
-	Iobuf *p;
-	Dentry *d;
-	File *file;
-	Tlock *t;
-	Qid qid;
-	int error, ro, fmod, wok;
-
-	wok = 0;
-	p = nil;
-
-	if(chan == cons.chan || writeallow)
-		wok = 1;
-
-	if((file = filep(chan, f->fid, 0)) == nil){
-		error = Efid;
-		goto out;
-	}
-
-	/*
-	 * if remove on close, check access here
-	 */
-	ro = isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup));
-	if(f->mode & ORCLOSE){
-		if(ro){
-			error = Eronly;
-			goto out;
-		}
-		/*
-		 * check on parent directory of file to be deleted
-		 */
-		if(file->wpath == 0 || file->wpath->addr == file->addr){
-			error = Ephase;
-			goto out;
-		}
-		p = getbuf(file->fs->dev, file->wpath->addr, Bread);
-		if(p == nil || checktag(p, Tdir, QPNONE)){
-			error = Ephase;
-			goto out;
-		}
-		if((d = getdir(p, file->wpath->slot)) == nil || !(d->mode & DALLOC)){
-			error = Ephase;
-			goto out;
-		}
-		if(iaccess(file, d, DWRITE)){
-			error = Eaccess;
-			goto out;
-		}
-		putbuf(p);
-	}
-	p = getbuf(file->fs->dev, file->addr, Bread);
-	if(p == nil || checktag(p, Tdir, QPNONE)){
-		error = Ealloc;
-		goto out;
-	}
-	if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-	mkqid(&qid, d, 1);
-	switch(f->mode & 7){
-
-	case OREAD:
-		if(iaccess(file, d, DREAD) && !wok)
-			goto badaccess;
-		fmod = FREAD;
-		break;
-
-	case OWRITE:
-		if((d->mode & DDIR) || (iaccess(file, d, DWRITE) && !wok))
-			goto badaccess;
-		if(ro){
-			error = Eronly;
-			goto out;
-		}
-		fmod = FWRITE;
-		break;
-
-	case ORDWR:
-		if((d->mode & DDIR)
-		|| (iaccess(file, d, DREAD) && !wok)
-		|| (iaccess(file, d, DWRITE) && !wok))
-			goto badaccess;
-		if(ro){
-			error = Eronly;
-			goto out;
-		}
-		fmod = FREAD+FWRITE;
-		break;
-
-	case OEXEC:
-		if((d->mode & DDIR) || (iaccess(file, d, DEXEC) && !wok))
-			goto badaccess;
-		fmod = FREAD;
-		break;
-
-	default:
-		error = Emode;
-		goto out;
-	}
-	if(f->mode & OTRUNC){
-		if((d->mode & DDIR) || (iaccess(file, d, DWRITE) && !wok))
-			goto badaccess;
-		if(ro){
-			error = Eronly;
-			goto out;
-		}
-	}
-	t = 0;
-	if(d->mode & DLOCK){
-		if((t = tlocked(p, d)) == nil){
-			error = Elocked;
-			goto out;
-		}
-	}
-	if(f->mode & ORCLOSE)
-		fmod |= FREMOV;
-	file->open = fmod;
-	if((f->mode & OTRUNC) && !(d->mode & DAPND)){
-		dtrunc(p, d);
-		qid.vers = d->qid.version;
-	}
-	r->qid = qid;
-	file->tlock = t;
-	if(t != nil)
-		t->file = file;
-	file->lastra = 1;
-	goto out;
-
-badaccess:
-	error = Eaccess;
-	file->open = 0;
-
-out:
-	if(p != nil)
-		putbuf(p);
-	if(file != nil)
-		qunlock(file);
-
-	r->iounit = chan->msize-IOHDRSZ;
-
-	return error;
-}
-
-static int
-dir9p2(Dir* dir, Dentry* dentry, void* strs)
-{
-	char *op, *p;
-
-	memset(dir, 0, sizeof(Dir));
-	mkqid(&dir->qid, dentry, 1);
-	dir->mode = (dir->qid.type<<24)|(dentry->mode & 0777);
-	dir->atime = dentry->atime;
-	dir->mtime = dentry->mtime;
-	dir->length = dentry->size;
-
-	op = p = strs;
-	dir->name = p;
-	p += sprint(p, "%s", dentry->name)+1;
-
-	dir->uid = p;
-	uidtostr(p, dentry->uid);
-	p += strlen(p)+1;
-
-	dir->gid = p;
-	uidtostr(p, dentry->gid);
-	p += strlen(p)+1;
-
-	dir->muid = p;
-	strcpy(p, "");
-	p += strlen(p)+1;
-
-	return p-op;
-}
-
-static int
-checkname9p2(char* name)
-{
-	char *p;
-
-	/*
-	 * Return length of string if valid, 0 if not.
-	 */
-	if(name == nil)
-		return 0;
-
-	for(p = name; *p != 0; p++){
-		if((*p & 0xFF) <= 040)
-			return 0;
-	}
-
-	return p-name;
-}
-
-static int
-fscreate(Chan* chan, Fcall* f, Fcall* r)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1;
-	File *file;
-	int error, slot, slot1, fmod, wok, l;
-	long addr, addr1, path;
-	Tlock *t;
-	Wpath *w;
-
-	wok = 0;
-	p = nil;
-
-	if(chan == cons.chan || writeallow)
-		wok = 1;
-
-	if((file = filep(chan, f->fid, 0)) == nil){
-		error = Efid;
-		goto out;
-	}
-	if(isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup))){
-		error = Eronly;
-		goto out;
-	}
-
-	p = getbuf(file->fs->dev, file->addr, Bread);
-	if(p == nil || checktag(p, Tdir, QPNONE)){
-		error = Ealloc;
-		goto out;
-	}
-	if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-	if(!(d->mode & DDIR)){
-		error = Edir2;
-		goto out;
-	}
-	if(iaccess(file, d, DWRITE) && !wok) {
-		error = Eaccess;
-		goto out;
-	}
-	accessdir(p, d, FREAD);
-
-	/*
-	 * Check the name is valid and will fit in an old
-	 * directory entry.
-	 */
-	if((l = checkname9p2(f->name)) == 0){
-		error = Ename;
-		goto out;
-	}
-	if(l+1 > NAMELEN){
-		error = Etoolong;
-		goto out;
-	}
-	if(strcmp(f->name, ".") == 0 || strcmp(f->name, "..") == 0){
-		error = Edot;
-		goto out;
-	}
-
-	addr1 = 0;
-	slot1 = 0;	/* set */
-	for(addr = 0; ; addr++){
-		if((p1 = dnodebuf(p, d, addr, 0)) == nil){
-			if(addr1 != 0)
-				break;
-			p1 = dnodebuf(p, d, addr, Tdir);
-		}
-		if(p1 == nil){
-			error = Efull;
-			goto out;
-		}
-		if(checktag(p1, Tdir, d->qid.path)){
-			putbuf(p1);
-			goto phase;
-		}
-		for(slot = 0; slot < DIRPERBUF; slot++){
-			d1 = getdir(p1, slot);
-			if(!(d1->mode & DALLOC)){
-				if(addr1 == 0){
-					addr1 = p1->addr;
-					slot1 = slot + addr*DIRPERBUF;
-				}
-				continue;
-			}
-			if(strncmp(f->name, d1->name, sizeof(d1->name)) == 0){
-				putbuf(p1);
-				error = Eexist;
-				goto out;
-			}
-		}
-		putbuf(p1);
-	}
-
-	switch(f->mode & 7){
-	case OEXEC:
-	case OREAD:		/* seems only useful to make directories */
-		fmod = FREAD;
-		break;
-
-	case OWRITE:
-		fmod = FWRITE;
-		break;
-
-	case ORDWR:
-		fmod = FREAD+FWRITE;
-		break;
-
-	default:
-		error = Emode;
-		goto out;
-	}
-	if(f->perm & PDIR)
-		if((f->mode & OTRUNC) || (f->perm & PAPND) || (fmod & FWRITE))
-			goto badaccess;
-	/*
-	 * do it
-	 */
-	path = qidpathgen(&file->fs->dev);
-	if((p1 = getbuf(file->fs->dev, addr1, Bread|Bimm|Bmod)) == nil)
-		goto phase;
-	d1 = getdir(p1, slot1);
-	if(d1 == nil || checktag(p1, Tdir, d->qid.path)) {
-		putbuf(p1);
-		goto phase;
-	}
-	if(d1->mode & DALLOC){
-		putbuf(p1);
-		goto phase;
-	}
-
-	strncpy(d1->name, f->name, sizeof(d1->name));
-	if(chan == cons.chan){
-		d1->uid = cons.uid;
-		d1->gid = cons.gid;
-	}
-	else{
-		d1->uid = file->uid;
-		d1->gid = d->gid;
-		f->perm &= d->mode | ~0666;
-		if(f->perm & PDIR)
-			f->perm &= d->mode | ~0777;
-	}
-	d1->qid.path = path;
-	d1->qid.version = 0;
-	d1->mode = DALLOC | (f->perm & 0777);
-	if(f->perm & PDIR) {
-		d1->mode |= DDIR;
-		d1->qid.path |= QPDIR;
-	}
-	if(f->perm & PAPND)
-		d1->mode |= DAPND;
-	t = nil;
-	if(f->perm & PLOCK){
-		d1->mode |= DLOCK;
-		t = tlocked(p1, d1);
-		/* if nil, out of tlock structures */
-	}
-	accessdir(p1, d1, FWRITE);
-	mkqid(&r->qid, d1, 0);
-	putbuf(p1);
-	accessdir(p, d, FWRITE);
-
-	/*
-	 * do a walk to new directory entry
-	 */
-	if((w = newwp()) == nil){
-		error = Ewalk;
-		goto out;
-	}
-	w->addr = file->addr;
-	w->slot = file->slot;
-	w->up = file->wpath;
-	file->wpath = w;
-	file->qid = r->qid;
-	file->tlock = t;
-	if(t != nil)
-		t->file = file;
-	file->lastra = 1;
-	if(f->mode & ORCLOSE)
-		fmod |= FREMOV;
-	file->open = fmod;
-	file->addr = addr1;
-	file->slot = slot1;
-	goto out;
-
-badaccess:
-	error = Eaccess;
-	goto out;
-
-phase:
-	error = Ephase;
-
-out:
-	if(p != nil)
-		putbuf(p);
-	if(file != nil)
-		qunlock(file);
-
-	r->iounit = chan->msize-IOHDRSZ;
-
-	return error;
-}
-
-static int
-fsread(Chan* chan, Fcall* f, Fcall* r)
-{
-	uchar *data;
-	Iobuf *p, *p1;
-	File *file;
-	Dentry *d, *d1;
-	Tlock *t;
-	long addr, offset, start, tim;
-	int error, iounit, nread, count, n, o, slot;
-	Dir dir;
-	char strdata[28*10];
-
-	p = nil;
-	data = (uchar*)r->data;
-	count = f->count;
-	offset = f->offset;
-	nread = 0;
-	if((file = filep(chan, f->fid, 0)) == nil){
-		error = Efid;
-		goto out;
-	}
-	if(file->qid.type & QTAUTH){
-		nread = authread(file, data, count);
-		if(nread < 0)
-			error = Esystem;
-		else
-			error = 0;
-		goto out;
-	}
-	if(!(file->open & FREAD)){
-		error = Eopen;
-		goto out;
-	}
-	iounit = chan->msize-IOHDRSZ;
-	if(count < 0 || count > iounit){
-		error = Ecount;
-		goto out;
-	}
-	if(offset < 0){
-		error = Eoffset;
-		goto out;
-	}
-	p = getbuf(file->fs->dev, file->addr, Bread);
-	if(p == nil || checktag(p, Tdir, QPNONE)){
-		error = Ealloc;
-		goto out;
-	}
-	if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-	if(t = file->tlock){
-		tim = time(0);
-		if(t->time < tim || t->file != file){
-			error = Ebroken;
-			goto out;
-		}
-		/* renew the lock */
-		t->time = tim + TLOCK;
-	}
-	accessdir(p, d, FREAD);
-	if(d->mode & DDIR)
-		goto dread;
-	if(offset >= d->size)
-		count = 0;
-	else if(offset+count > d->size)
-		count = d->size - offset;
-	while(count > 0){
-		if(p == nil){
-			p = getbuf(file->fs->dev, file->addr, Bread);
-			if(p == nil || checktag(p, Tdir, QPNONE)){
-				error = Ealloc;
-				goto out;
-			}
-			if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-				error = Ealloc;
-				goto out;
-			}
-		}
-		addr = offset / BUFSIZE;
-		o = offset % BUFSIZE;
-		n = BUFSIZE - o;
-		if(n > count)
-			n = count;
-		p1 = dnodebuf1(p, d, addr, 0);
-		p = nil;
-		if(p1 != nil){
-			if(checktag(p1, Tfile, QPNONE)){
-				error = Ephase;
-				putbuf(p1);
-				goto out;
-			}
-			memmove(data+nread, p1->iobuf+o, n);
-			putbuf(p1);
-		}
-		else
-			memset(data+nread, 0, n);
-		count -= n;
-		nread += n;
-		offset += n;
-	}
-	goto out;
-
-dread:
-	/*
-	 * Pick up where we left off last time if nothing has changed,
-	 * otherwise must scan from the beginning.
-	 */
-	if(offset == file->doffset /*&& file->qid.vers == file->dvers*/){
-		addr = file->dslot/DIRPERBUF;
-		slot = file->dslot%DIRPERBUF;
-		start = offset;
-	}
-	else{
-		addr = 0;
-		slot = 0;
-		start = 0;
-	}
-
-dread1:
-	if(p == nil){
-		/*
-		 * This is just a check to ensure the entry hasn't
-		 * gone away during the read of each directory block.
-		 */
-		p = getbuf(file->fs->dev, file->addr, Bread);
-		if(p == nil || checktag(p, Tdir, QPNONE)){
-			error = Ealloc;
-			goto out1;
-		}
-		if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-			error = Ealloc;
-			goto out1;
-		}
-	}
-	p1 = dnodebuf1(p, d, addr, 0);
-	p = nil;
-	if(p1 == nil)
-		goto out1;
-	if(checktag(p1, Tdir, QPNONE)){
-		error = Ephase;
-		putbuf(p1);
-		goto out1;
-	}
-
-	for(; slot < DIRPERBUF; slot++){
-		d1 = getdir(p1, slot);
-		if(!(d1->mode & DALLOC))
-			continue;
-		dir9p2(&dir, d1, strdata);
-		if((n = convD2M(&dir, data+nread, iounit - nread)) <= BIT16SZ){
-			putbuf(p1);
-			goto out1;
-		}
-		start += n;
-		if(start < offset)
-			continue;
-		if(count < n){
-			putbuf(p1);
-			goto out1;
-		}
-		count -= n;
-		nread += n;
-		offset += n;
-	}
-	putbuf(p1);
-	slot = 0;
-	addr++;
-	goto dread1;
-
-out1:
-	if(error == 0){
-		file->doffset = offset;
-		file->dvers = file->qid.vers;
-		file->dslot = slot+DIRPERBUF*addr;
-	}
-
-out:
-	/*
-	 * Do we need this any more?
-	count = f->count - nread;
-	if(count > 0)
-		memset(data+nread, 0, count);
-	 */
-	if(p != nil)
-		putbuf(p);
-	if(file != nil)
-		qunlock(file);
-	r->count = nread;
-	r->data = (char*)data;
-
-	return error;
-}
-
-static int
-fswrite(Chan* chan, Fcall* f, Fcall* r)
-{
-	Iobuf *p, *p1;
-	Dentry *d;
-	File *file;
-	Tlock *t;
-	long offset, addr, tim, qpath;
-	int count, error, nwrite, o, n;
-
-	offset = f->offset;
-	count = f->count;
-
-	nwrite = 0;
-	p = nil;
-
-	if((file = filep(chan, f->fid, 0)) == nil){
-		error = Efid;
-		goto out;
-	}
-	if(file->qid.type & QTAUTH){
-		nwrite = authwrite(file, (uchar*)f->data, count);
-		if(nwrite < 0)
-			error = Esystem;
-		else
-			error = 0;
-		goto out;
-	}
-	if(!(file->open & FWRITE)){
-		error = Eopen;
-		goto out;
-	}
-	if(isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup))){
-		error = Eronly;
-		goto out;
-	}
-	if(count < 0 || count > chan->msize-IOHDRSZ){
-		error = Ecount;
-		goto out;
-	}
-	if(offset < 0) {
-		error = Eoffset;
-		goto out;
-	}
-	if((p = getbuf(file->fs->dev, file->addr, Bread|Bmod)) == nil){
-		error = Ealloc;
-		goto out;
-	}
-	if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-	if(t = file->tlock) {
-		tim = time(0);
-		if(t->time < tim || t->file != file){
-			error = Ebroken;
-			goto out;
-		}
-		/* renew the lock */
-		t->time = tim + TLOCK;
-	}
-	accessdir(p, d, FWRITE);
-	if(d->mode & DAPND)
-		offset = d->size;
-	if(offset+count > d->size)
-		d->size = offset+count;
-	while(count > 0){
-		if(p == nil){
-			p = getbuf(file->fs->dev, file->addr, Bread|Bmod);
-			if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-				error = Ealloc;
-				goto out;
-			}
-		}
-		addr = offset / BUFSIZE;
-		o = offset % BUFSIZE;
-		n = BUFSIZE - o;
-		if(n > count)
-			n = count;
-		qpath = d->qid.path;
-		p1 = dnodebuf1(p, d, addr, Tfile);
-		p = nil;
-		if(p1 == nil) {
-			error = Efull;
-			goto out;
-		}
-		if(checktag(p1, Tfile, qpath)){
-			putbuf(p1);
-			error = Ephase;
-			goto out;
-		}
-		memmove(p1->iobuf+o, f->data+nwrite, n);
-		p1->flags |= Bmod;
-		putbuf(p1);
-		count -= n;
-		nwrite += n;
-		offset += n;
-	}
-
-out:
-	if(p != nil)
-		putbuf(p);
-	if(file != nil)
-		qunlock(file);
-	r->count = nwrite;
-
-	return error;
-}
-
-static int
-_clunk(File* file, int remove, int wok)
-{
-	Tlock *t;
-	int error;
-
-	error = 0;
-	if(t = file->tlock){
-		if(t->file == file)
-			t->time = 0;		/* free the lock */
-		file->tlock = 0;
-	}
-	if(remove)
-		error = doremove(file, wok);
-	file->open = 0;
-	freewp(file->wpath);
-	freefp(file);
-	qunlock(file);
-
-	return error;
-}
-
-static int
-fsclunk(Chan* chan, Fcall* f, Fcall*)
-{
-	File *file;
-
-	if((file = filep(chan, f->fid, 0)) == nil)
-		return Efid;
-
-	_clunk(file, file->open & FREMOV, 0);
-	return 0;
-}
-
-static int
-fsremove(Chan* chan, Fcall* f, Fcall*)
-{
-	File *file;
-
-	if((file = filep(chan, f->fid, 0)) == nil)
-		return Efid;
-
-	return _clunk(file, 1, chan == cons.chan);
-}
-
-static int
-fsstat(Chan* chan, Fcall* f, Fcall* r, uchar* data)
-{
-	Dir dir;
-	Iobuf *p;
-	Dentry *d;
-	File *file;
-	int error, len;
-
-	if((file = filep(chan, f->fid, 0)) == nil)
-		return Efid;
-
-	p = getbuf(file->fs->dev, file->addr, Bread);
-	if(p == nil || checktag(p, Tdir, QPNONE)){
-		error = Edir1;
-		goto out;
-	}
-	if((d = getdir(p, file->slot)) == nil || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-
-	if(d->qid.path == QPROOT)	/* stat of root gives time */
-		d->atime = time(0);
-
-	len = dir9p2(&dir, d, data);
-	data += len;
-	if((r->nstat = convD2M(&dir, data, chan->msize - len)) == 0)
-		error = Ersc;
-	else
-		r->stat = data;
-
-out:
-	if(p != nil)
-		putbuf(p);
-	if(file != nil)
-		qunlock(file);
-
-	return error;
-}
-
-static int
-fswstat(Chan* chan, Fcall* f, Fcall*, char *strs)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1, xd;
-	File *file;
-	int error, slot, uid, gid, l;
-	long addr;
-	Dir dir;
-	ulong mode;
-
-	p = p1 = nil;
-	d1 = nil;
-
-	if((file = filep(chan, f->fid, 0)) == nil){
-		error = Efid;
-		goto out;
-	}
-
-	/*
-	 * if user none,
-	 * can't do anything
-	 * unless allow.
-	 */
-	if(file->uid == 0 && !wstatallow){
-		error = Eaccess;
-		goto out;
-	}
-
-	if(isro(file->fs->dev) || (writegroup && !ingroup(file->uid, writegroup))){
-		error = Eronly;
-		goto out;
-	}
-
-	/*
-	 * first get parent
-	 */
-	if(file->wpath){
-		p1 = getbuf(file->fs->dev, file->wpath->addr, Bread);
-		if(p1 == nil){
-			error = Ephase;
-			goto out;
-		}
-		d1 = getdir(p1, file->wpath->slot);
-		if(d1 == nil || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)){
-			error = Ephase;
-			goto out;
-		}
-	}
-
-	if((p = getbuf(file->fs->dev, file->addr, Bread)) == nil){
-		error = Ealloc;
-		goto out;
-	}
-	d = getdir(p, file->slot);
-	if(d == nil || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)){
-		error = Ealloc;
-		goto out;
-	}
-	if(error = mkqidcmp(&file->qid, d))
-		goto out;
-
-	/*
-	 * Convert the message and fix up
-	 * fields not to be changed.
-	 */
-	if(convM2D(f->stat, f->nstat, &dir, strs) == 0){
-		print("9p2: convM2D returns 0\n");
-		error = Econvert;
-		goto out;
-	}
-	if(dir.uid == nil || strlen(dir.uid) == 0)
-		uid = d->uid;
-	else
-		uid = strtouid(dir.uid);
-	if(dir.gid == nil || strlen(dir.gid) == 0)
-		gid = d->gid;
-	else
-		gid = strtouid(dir.gid);
-	if(dir.name == nil || strlen(dir.name) == 0)
-		dir.name = d->name;
-	else{
-		if((l = checkname9p2(dir.name)) == 0){
-			error = Ename;
-			goto out;
-		}
-		if(l > NAMELEN){
-			error = Etoolong;
-			goto out;
-		}
-	}
-
-	/*
-	 * Before doing sanity checks, find out what the
-	 * new 'mode' should be:
-	 * if 'type' and 'mode' are both defaults, take the
-	 * new mode from the old directory entry;
-	 * else if 'type' is the default, use the new mode entry;
-	 * else if 'mode' is the default, create the new mode from
-	 * 'type' or'ed with the old directory mode;
-	 * else neither are defaults, use the new mode but check
-	 * it agrees with 'type'.
-	 */
-	if(dir.qid.type == 0xFF && dir.mode == ~0){
-		dir.mode = d->mode & 0777;
-		if(d->mode & DLOCK)
-			dir.mode |= DMEXCL;
-		if(d->mode & DAPND)
-			dir.mode |= DMAPPEND;
-		if(d->mode & DDIR)
-			dir.mode |= DMDIR;
-	}
-	else if(dir.qid.type == 0xFF){
-		/* nothing to do */
-	}
-	else if(dir.mode == ~0)
-		dir.mode = (dir.qid.type<<24)|(d->mode & 0777);
-	else if(dir.qid.type != ((dir.mode>>24) & 0xFF)){
-		error = Eqidmode;
-		goto out;
-	}
-
-	/*
-	 * Check for unknown type/mode bits
-	 * and an attempt to change the directory bit.
-	 */
-	if(dir.mode & ~(DMDIR|DMAPPEND|DMEXCL|0777)){
-		error = Enotm;
-		goto out;
-	}
-	if(d->mode & DDIR)
-		mode = DMDIR;
-	else
-		mode = 0;
-	if((dir.mode^mode) & DMDIR){
-		error = Enotd;
-		goto out;
-	}
-
-	if(dir.mtime == ~0)
-		dir.mtime = d->mtime;
-	if(dir.length == ~0)
-		dir.length = d->size;
-
-	/*
-	 * Currently, can't change length.
-	 */
-	if(dir.length != d->size){
-		error = Enotl;
-		goto out;
-	}
-
-	/*
-	 * if chown,
-	 * must be god
-	 * wstatallow set to allow chown during boot
-	 */
-	if(uid != d->uid && !wstatallow) {
-		error = Enotu;
-		goto out;
-	}
-
-	/*
-	 * if chgroup,
-	 * must be either
-	 *	a) owner and in new group
-	 *	b) leader of both groups
-	 * wstatallow and writeallow are set to allow chgrp during boot
-	 */
-	while(gid != d->gid) {
-		if(wstatallow || writeallow)
-			break;
-		if(d->uid == file->uid && ingroup(file->uid, gid))
-			break;
-		if(leadgroup(file->uid, gid))
-			if(leadgroup(file->uid, d->gid))
-				break;
-		error = Enotg;
-		goto out;
-	}
-
-	/*
-	 * if rename,
-	 * must have write permission in parent
-	 */
-	while(strncmp(d->name, dir.name, sizeof(d->name)) != 0) {
-		if(checkname(dir.name) || d1 == nil) {
-			error = Ename;
-			goto out;
-		}
-		if(strcmp(dir.name, ".") == 0 || strcmp(xd.name, "..") == 0) {
-			error = Ename;
-			goto out;
-		}
-
-		/*
-		 * drop entry to prevent lock, then
-		 * check that destination name is unique,
-		 */
-		putbuf(p);
-		for(addr = 0; ; addr++) {
-			if((p = dnodebuf(p1, d1, addr, 0)) == nil)
-				break;
-			if(checktag(p, Tdir, d1->qid.path)) {
-				putbuf(p);
-				continue;
-			}
-			for(slot = 0; slot < DIRPERBUF; slot++) {
-				d = getdir(p, slot);
-				if(!(d->mode & DALLOC))
-					continue;
-				if(strncmp(dir.name, d->name, sizeof(d->name)) == 0) {
-					error = Eexist;
-					goto out;
-				}
-			}
-			putbuf(p);
-		}
-
-		/*
-		 * reacquire entry
-		 */
-		if((p = getbuf(file->fs->dev, file->addr, Bread)) == nil){
-			error = Ephase;
-			goto out;
-		}
-		d = getdir(p, file->slot);
-		if(d == nil || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
-			error = Ephase;
-			goto out;
-		}
-
-		if(wstatallow || writeallow) /* set to allow rename during boot */
-			break;
-		if(d1 == nil || iaccess(file, d1, DWRITE)) {
-			error = Eaccess;
-			goto out;
-		}
-		break;
-	}
-
-	/*
-	 * if mode/time, either
-	 *	a) owner
-	 *	b) leader of either group
-	 */
-	mode = dir.mode & 0777;
-	if(dir.mode & DMAPPEND)
-		mode |= DAPND;
-	if(dir.mode & DMEXCL)
-		mode |= DLOCK;
-	while(d->mtime != dir.mtime || ((d->mode^mode) & (DAPND|DLOCK|0777))) {
-		if(wstatallow)			/* set to allow chmod during boot */
-			break;
-		if(d->uid == file->uid)
-			break;
-		if(leadgroup(file->uid, gid))
-			break;
-		if(leadgroup(file->uid, d->gid))
-			break;
-		error = Enotu;
-		goto out;
-	}
-	d->mtime = dir.mtime;
-	d->uid = uid;
-	d->gid = gid;
-	d->mode = (mode & (DAPND|DLOCK|0777)) | (d->mode & (DALLOC|DDIR));
-
-	strncpy(d->name, dir.name, sizeof(d->name));
-	accessdir(p, d, FWSTAT);
-
-out:
-	if(p != nil)
-		putbuf(p);
-	if(p1 != nil)
-		putbuf(p1);
-	if(file != nil)
-		qunlock(file);
-
-	return error;
-}
-
-static int
-recv(Chan *c, uchar *buf, int n)
-{
-	int fd, m, len;
-
-	fd = c->chan;
-	/* read count */
-	qlock(&c->rlock);
-	m = readn(fd, buf, BIT32SZ);
-	if(m != BIT32SZ){
-		qunlock(&c->rlock);
-		if(m < 0){
-			print("readn(BIT32SZ) fails: %r\n");
-			return -1;
-		}
-		print("readn(BIT32SZ) returns %d: %r\n", m);
-		return 0;
-	}
-
-	len = GBIT32(buf);
-	if(len <= BIT32SZ || len > n){
-		print("recv bad length %d\n", len);
-		werrstr("bad length in 9P2000 message header");
-		qunlock(&c->rlock);
-		return -1;
-	}
-	len -= BIT32SZ;
-	m = readn(fd, buf+BIT32SZ, len);
-	qunlock(&c->rlock);
-	if(m < len){
-		print("recv wanted %d got %d\n", len, m);
-		return 0;
-	}
-	return BIT32SZ+m;
-}
-
-static void
-send(Chan *c, uchar *buf, int n)
-{
-	int fd, m;
-
-	fd = c->chan;
-	qlock(&c->wlock);
-	m = write(fd, buf, n);
-	qunlock(&c->wlock);
-	if(m == n)
-		return;
-	panic("write failed");
-}
-
-void
-serve9p2(Chan *chan, uchar *ib, int nib)
-{
-	uchar inbuf[MSIZE+IOHDRSZ], outbuf[MSIZE+IOHDRSZ];
-	Fcall f, r;
-	char ename[64];
-	int error, n, type;
-
-	chan->msize = MSIZE;
-	fmtinstall('F', fcallfmt);
-
-	for(;;){
-		if(nib){
-			memmove(inbuf, ib, nib);
-			n = nib;
-			nib = 0;
-		}else
-			n = recv(chan, inbuf, sizeof inbuf);
-		if(chat){
-			print("read msg %d (fd %d)\n", n, chan->chan);
-			if(n <= 0)
-				print("\terr: %r\n");
-		}
-		if(n == 0 && (chan == cons.srvchan || chan == cons.chan))
-			continue;
-		if(n <= 0)
-			break;
-		if(convM2S(inbuf, n, &f) != n){
-			print("9p2: cannot decode\n");
-			continue;
-		}
-
-		type = f.type;
-		if(type < Tversion || type >= Tmax || (type&1) || type == Terror){
-			print("9p2: bad message type %d\n", type);
-			continue;
-		}
-
-		if(CHAT(chan))
-			print("9p2: f %F\n", &f);
-
-		r.type = type+1;
-		r.tag = f.tag;
-		error = 0;
-
-		rlock(&mainlock);
-		rlock(&chan->reflock);
-		switch(type){
-		default:
-			r.type = Rerror;
-			snprint(ename, sizeof ename, "unknown message: %F", &f);
-			r.ename = ename;
-			break;
-		case Tversion:
-			error = fsversion(chan, &f, &r);
-			break;
-		case Tauth:
-			error = fsauth(chan, &f, &r);
-			break;
-		case Tattach:
-			error = fsattach(chan, &f, &r);
-			break;
-		case Tflush:
-			error = fsflush(chan, &f, &r);
-			break;
-		case Twalk:
-			error = fswalk(chan, &f, &r);
-			break;
-		case Topen:
-			error = fsopen(chan, &f, &r);
-			break;
-		case Tcreate:
-			error = fscreate(chan, &f, &r);
-			break;
-		case Tread:
-			r.data = (char*)inbuf;
-			error = fsread(chan, &f, &r);
-			break;
-		case Twrite:
-			error = fswrite(chan, &f, &r);
-			break;
-		case Tclunk:
-			error = fsclunk(chan, &f, &r);
-			break;
-		case Tremove:
-			error = fsremove(chan, &f, &r);
-			break;
-		case Tstat:
-			error = fsstat(chan, &f, &r, inbuf);
-			break;
-		case Twstat:
-			error = fswstat(chan, &f, &r, (char*)outbuf);
-			break;
-		}
-		runlock(&chan->reflock);
-		runlock(&mainlock);
-
-		if(error != 0){
-			r.type = Rerror;
-			if(error >= MAXERR){
-				snprint(ename, sizeof(ename), "error %d", error);
-				r.ename = ename;
-			}
-			else
-				r.ename = errstring[error];
-		}
-		if(CHAT(chan))
-			print("9p2: r %F\n", &r);
-	
-		n = convS2M(&r, outbuf, sizeof outbuf);
-		if(n == 0){
-			type = r.type;
-			r.type = Rerror;
-			snprint(ename, sizeof(ename), "9p2: convS2M: type %d", type);
-			r.ename = ename;
-			print(ename);
-			n = convS2M(&r, outbuf, sizeof outbuf);
-			if(n == 0){
-				/*
-				 * What to do here, the failure notification failed?
-				 */
-				panic("can't write anything at all");
-			}
-		}
-		send(chan, outbuf, n);
-	}
-	fileinit(chan);
-	close(chan->chan);
-	if(chan == cons.srvchan || chan == cons.chan)
-		print("console chan read error");
-}
-
--- a/sys/src/cmd/disk/kfs/all.h
+++ /dev/null
@@ -1,8 +1,0 @@
-#include	"u.h"
-#include	"libc.h"
-#include	"dat.h"
-#include	"fns.h"
-
-#include	<fcall.h>
-#include	<auth.h>
-#include	<authsrv.h>
--- a/sys/src/cmd/disk/kfs/auth.c
+++ /dev/null
@@ -1,120 +1,0 @@
-/*
- * Network listening authentication.
- * This and all the other network-related 
- * code is due to Richard Miller.
- */
-#include	"all.h"
-#include	"9p1.h"
-
-int allownone;
-Nvrsafe nvr;
-Authkey authkey; 
-int didread;
-
-/*
- *  create a challenge for a fid space
- */
-void
-mkchallenge(Chan *cp)
-{
-	int i;
-
-	if(!didread && readnvram(&nvr, 0) >= 0){
-		memmove(authkey.des, nvr.machkey, DESKEYLEN);
-		didread = 1;
-	}
-
-	srand(truerand());
-	for(i = 0; i < CHALLEN; i++)
-		cp->chal[i] = nrand(256);
-
-	cp->idoffset = 0;
-	cp->idvec = 0;
-}
-
-/*
- *  match a challenge from an attach
- */
-Nvrsafe nvr;
-
-int
-authorize(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	Ticket t;
-	Authenticator a;
-	int x;
-	ulong bit;
-
-	if (cp == cons.srvchan)               /* local channel already safe */
-		return 1;
-
-	if(wstatallow)		/* set to allow entry during boot */
-		return 1;
-
-	if(strcmp(in->uname, "none") == 0)
-		return allownone || cp->authed;
-
-	if(in->type == Toattach9p1)
-		return 0;
-
-	if(!didread)
-		return 0;
-
-	/* decrypt and unpack ticket */
-	convM2T(in->ticket, sizeof(in->ticket), &t, &authkey);
-	if(t.num != AuthTs){
-print("bad AuthTs num\n");
-		return 0;
-	}
-
-	/* decrypt and unpack authenticator */
-	convM2A(in->auth, sizeof(in->auth), &a, &t);
-	if(a.num != AuthAc){
-print("bad AuthAc num\n");
-		return 0;
-	}
-
-	/* challenges must match */
-	if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){
-print("bad challenge\n");
-		return 0;
-	}
-
-	/*
-	 *  the id must be in a valid range.  the range is specified by a
-	 *  lower bount (idoffset) and a bit vector (idvec) where a
-	 *  bit set to 1 means unusable
-	 */
-	lock(&cp->idlock);
-	x = a.id - cp->idoffset;
-	bit = 1<<x;
-	if(x < 0 || x > 31 || (bit&cp->idvec)){
-		unlock(&cp->idlock);
-		return 0;
-	}
-	cp->idvec |= bit;
-
-	/* normalize the vector */
-	while(cp->idvec&0xffff0001){
-		cp->idvec >>= 1;
-		cp->idoffset++;
-	}
-	unlock(&cp->idlock);
-
-	/* ticket name and attach name must match */
-	if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){
-print("names don't match\n");
-		return 0;
-	}
-
-	/* copy translated name into input record */
-	memmove(in->uname, t.suid, sizeof(in->uname));
-
-	/* craft a reply */
-	a.num = AuthAs;
-	memmove(a.chal, cp->rchal, CHALLEN);
-	convA2M(&a, ou->rauth, sizeof(ou->rauth), &t);
-
-	cp->authed = 1;
-	return 1;
-}
--- a/sys/src/cmd/disk/kfs/chk.c
+++ /dev/null
@@ -1,654 +1,0 @@
-#include	"all.h"
-
-#define	DSIZE		546000
-#define	MAXDEPTH	100
-
-static	char*	abits;
-static	long	sizabits;
-static	char*	qbits;
-static	long	sizqbits;
-static	char*	name;
-static	long	sizname;
-static	long	fstart;
-static	long	fsize;
-static	long	nfiles;
-static	long	maxq;
-static	char*	fence;
-static	char*	fencebase;
-static	Device	dev;
-static	long	ndup;
-static	long	nused;
-static	long	nfdup;
-static	long	nqbad;
-static	long	nfree;
-static	long	nbad;
-static	int	mod;
-static	int	flags;
-static	int	ronly;
-static	int	cwflag;
-static	long	sbaddr;
-static	long	oldblock;
-static	int	depth;
-static	int	maxdepth;
-
-/* local prototypes */
-static	int	fsck(Dentry*);
-static	void	ckfreelist(Superb*);
-static	void	mkfreelist(Superb*);
-static	Dentry*	maked(long, int, long);
-static	void	modd(long, int, Dentry*);
-static	void	xread(long, long);
-static	int	amark(long);
-static	int	fmark(long);
-static	void	missing(void);
-static	void	qmark(long);
-static	void*	zalloc(ulong);
-static	void*	dalloc(ulong);
-static	Iobuf*	xtag(long, int, long);
-
-static
-void*
-zalloc(ulong n)
-{
-	char *p;
-
-	p = malloc(n);
-	if(p == 0)
-		panic("zalloc: out of memory\n");
-	memset(p, '\0', n);
-	return p;
-}
-
-static
-void*
-dalloc(ulong n)
-{
-	char *p;
-
-	if(fencebase == 0)
-		fence = fencebase = zalloc(MAXDEPTH*sizeof(Dentry));
-	p = fence;
-	fence += n;
-	if(fence > fencebase+MAXDEPTH*sizeof(Dentry))
-		panic("dalloc too much memory\n");
-	return p;
-}
-
-void
-check(Filsys *fs, long flag)
-{
-	Iobuf *p;
-	Superb *sb;
-	Dentry *d;
-	long raddr;
-	long nqid;
-
-	wlock(&mainlock);
-	dev = fs->dev;
-	flags = flag;
-	fence = fencebase;
-
-	sizname = 4000;
-	name = zalloc(sizname);
-	sizname -= NAMELEN+10;	/* for safety */
-
-	sbaddr = superaddr(dev);
-	raddr = getraddr(dev);
-	p = xtag(sbaddr, Tsuper, QPSUPER);
-	if(!p){
-		cprint("bad superblock\n");
-		goto out;
-	}
-	sb = (Superb*)p->iobuf;
-	fstart = 1;
-
-	fsize = sb->fsize;
-	sizabits = (fsize-fstart + 7)/8;
-	abits = zalloc(sizabits);
-
-	nqid = sb->qidgen+100;		/* not as much of a botch */
-	if(nqid > 1024*1024*8)
-		nqid = 1024*1024*8;
-	if(nqid < 64*1024)
-		nqid = 64*1024;
-
-	sizqbits = (nqid+7)/8;
-	qbits = zalloc(sizqbits);
-
-	mod = 0;
-	nfree = 0;
-	nfdup = 0;
-	nused = 0;
-	nbad = 0;
-	ndup = 0;
-	nqbad = 0;
-	depth = 0;
-	maxdepth = 0;
-
-	if(flags & Ctouch) {
-		oldblock = fsize/DSIZE;
-		oldblock *= DSIZE;
-		if(oldblock < 0)
-			oldblock = 0;
-		cprint("oldblock = %ld\n", oldblock);
-	}
-	if(amark(sbaddr))
-		{}
-	if(cwflag) {
-		if(amark(sb->roraddr))
-			{}
-		if(amark(sb->next))
-			{}
-	}
-
-	if(!(flags & Cquiet))
-		cprint("checking file system: %s\n", fs->name);
-	nfiles = 0;
-	maxq = 0;
-
-	d = maked(raddr, 0, QPROOT);
-	if(d) {
-		if(amark(raddr))
-			{}
-		if(fsck(d))
-			modd(raddr, 0, d);
-		depth--;
-		fence -= sizeof(Dentry);
-		if(depth)
-			cprint("depth not zero on return\n");
-	}
-
-	if(flags & Cfree) {
-		mkfreelist(sb);
-		sb->qidgen = maxq;
-		settag(p, Tsuper, QPNONE);
-	}
-
-	if(sb->qidgen < maxq)
-		cprint("qid generator low path=%ld maxq=%ld\n",
-			sb->qidgen, maxq);
-	if(!(flags & Cfree))
-		ckfreelist(sb);
-	if(mod) {
-		cprint("file system was modified\n");
-		settag(p, Tsuper, QPNONE);
-	}
-
-	if(!(flags & Cquiet)){
-		cprint("%8ld files\n", nfiles);
-		cprint("%8ld blocks in the file system\n", fsize-fstart);
-		cprint("%8ld used blocks\n", nused);
-		cprint("%8ld free blocks\n", sb->tfree);
-	}
-	if(!(flags & Cfree)){
-		if(nfree != sb->tfree)
-			cprint("%8ld free blocks found\n", nfree);
-		if(nfdup)
-			cprint("%8ld blocks duplicated in the free list\n", nfdup);
-		if(fsize-fstart-nused-nfree)
-			cprint("%8ld missing blocks\n", fsize-fstart-nused-nfree);
-	}
-	if(ndup)
-		cprint("%8ld address duplications\n", ndup);
-	if(nbad)
-		cprint("%8ld bad block addresses\n", nbad);
-	if(nqbad)
-		cprint("%8ld bad qids\n", nqbad);
-	if(!(flags & Cquiet))
-		cprint("%8ld maximum qid path\n", maxq);
-	missing();
-
-out:
-	if(p)
-		putbuf(p);
-	free(abits);
-	free(name);
-	free(qbits);
-	wunlock(&mainlock);
-}
-
-static
-int
-touch(long a)
-{
-	Iobuf *p;
-
-	if((flags&Ctouch) && a && a < oldblock){
-		p = getbuf(dev, a, Bread|Bmod);
-		if(p)
-			putbuf(p);
-		return 1;
-	}
-	return 0;
-}
-
-static
-int
-checkdir(long a, long qpath)
-{
-	Dentry *nd;
-	int i, ns, dmod;
-
-	ns = strlen(name);
-	dmod = touch(a);
-	for(i=0; i<DIRPERBUF; i++) {
-		nd = maked(a, i, qpath);
-		if(!nd)
-			break;
-		if(fsck(nd)) {
-			modd(a, i, nd);
-			dmod++;
-		}
-		depth--;
-		fence -= sizeof(Dentry);
-		name[ns] = 0;
-	}
-	name[ns] = 0;
-	return dmod;
-}
-
-static
-int
-checkindir(long a, Dentry *d, long qpath)
-{
-	Iobuf *p;
-	int i, dmod;
-
-	dmod = touch(a);
-	p = xtag(a, Tind1, qpath);
-	if(!p)
-		return dmod;
-	for(i=0; i<INDPERBUF; i++) {
-		a = ((long*)p->iobuf)[i];
-		if(!a)
-			continue;
-		if(amark(a)) {
-			if(flags & Cbad) {
-				((long*)p->iobuf)[i] = 0;
-				p->flags |= Bmod;
-			}
-			continue;
-		}
-		if(d->mode & DDIR)
-			dmod += checkdir(a, qpath);
-		else if(flags & Crdall)
-			xread(a, qpath);
-	}
-	putbuf(p);
-	return dmod;
-}
-
-static
-int
-fsck(Dentry *d)
-{
-	char *s;
-	Rune r;
-	Iobuf *p;
-	int l, i, ns, dmod;
-	long a, qpath;
-
-	depth++;
-	if(depth >= maxdepth){
-		maxdepth = depth;
-		if(maxdepth >= MAXDEPTH){
-			cprint("max depth exceeded: %s\n", name);
-			return 0;
-		}
-	}
-	dmod = 0;
-	if(!(d->mode & DALLOC))
-		return 0;
-	nfiles++;
-
-	ns = strlen(name);
-	i = strlen(d->name);
-	if(i >= NAMELEN){
-		d->name[NAMELEN-1] = 0;
-		cprint("%s->name (%s) not terminated\n", name, d->name);
-		return 0;
-	}
-	ns += i;
-	if(ns >= sizname){
-		cprint("%s->name (%s) name too large\n", name, d->name);
-		return 0;
-	}
-	for (s = d->name; *s; s += l){
-		l = chartorune(&r, s);
-		if (r == Runeerror)
-			for (i = 0; i < l; i++){
-				s[i] = '_';
-				cprint("%s->name (%s) bad UTF\n", name, d->name);
-				dmod++;
-			}
-	}
-	strcat(name, d->name);
-
-	if(d->mode & DDIR){
-		if(ns > 1)
-			strcat(name, "/");
-		if(flags & Cpdir)
-			cprint("%s\n", name);
-	} else
-	if(flags & Cpfile)
-		cprint("%s\n", name);
-
-	qpath = d->qid.path & ~QPDIR;
-	qmark(qpath);
-	if(qpath > maxq)
-		maxq = qpath;
-	for(i=0; i<NDBLOCK; i++) {
-		a = d->dblock[i];
-		if(!a)
-			continue;
-		if(amark(a)) {
-			d->dblock[i] = 0;
-			dmod++;
-			continue;
-		}
-		if(d->mode & DDIR)
-			dmod += checkdir(a, qpath);
-		else if(flags & Crdall)
-			xread(a, qpath);
-	}
-	a = d->iblock;
-	if(a && amark(a)) {
-		d->iblock = 0;
-		dmod++;
-	}
-	else if(a)
-		dmod += checkindir(a, d, qpath);
-
-	a = d->diblock;
-	if(a && amark(a)) {
-		d->diblock = 0;
-		return dmod + 1;
-	}
-	dmod += touch(a);
-	if(p = xtag(a, Tind2, qpath)){
-		for(i=0; i<INDPERBUF; i++){
-			a = ((long*)p->iobuf)[i];
-			if(!a)
-				continue;
-			if(amark(a)) {
-				if(flags & Cbad) {
-					((long*)p->iobuf)[i] = 0;
-					p->flags |= Bmod;
-				}
-				continue;
-			}
-			dmod += checkindir(a, d, qpath);
-		}
-		putbuf(p);
-	}
-	return dmod;
-}
-
-static
-void
-ckfreelist(Superb *sb)
-{
-	long a, lo, hi;
-	int n, i;
-	Iobuf *p;
-	Fbuf *fb;
-
-
-	strcpy(name, "free list");
-	cprint("check %s\n", name);
-	fb = &sb->fbuf;
-	a = sbaddr;
-	p = 0;
-	lo = 0;
-	hi = 0;
-	for(;;) {
-		n = fb->nfree;
-		if(n < 0 || n > FEPERBUF) {
-			cprint("check: nfree bad %ld\n", a);
-			break;
-		}
-		for(i=1; i<n; i++) {
-			a = fb->free[i];
-			if(a && !fmark(a)) {
-				if(!lo || lo > a)
-					lo = a;
-				if(!hi || hi < a)
-					hi = a;
-			}
-		}
-		a = fb->free[0];
-		if(!a)
-			break;
-		if(fmark(a))
-			break;
-		if(!lo || lo > a)
-			lo = a;
-		if(!hi || hi < a)
-			hi = a;
-		if(p)
-			putbuf(p);
-		p = xtag(a, Tfree, QPNONE);
-		if(!p)
-			break;
-		fb = (Fbuf*)p->iobuf;
-	}
-	if(p)
-		putbuf(p);
-	cprint("lo = %ld; hi = %ld\n", lo, hi);
-}
-
-/*
- * make freelist from scratch
- */
-static
-void
-mkfreelist(Superb *sb)
-{
-	long a;
-	int i, b;
-
-	strcpy(name, "free list");
-	memset(&sb->fbuf, 0, sizeof(sb->fbuf));
-	sb->fbuf.nfree = 1;
-	sb->tfree = 0;
-	for(a=fsize-fstart-1; a >= 0; a--) {
-		i = a/8;
-		if(i < 0 || i >= sizabits)
-			continue;
-		b = 1 << (a&7);
-		if(abits[i] & b)
-			continue;
-		addfree(dev, fstart+a, sb);
-		abits[i] |= b;
-	}
-}
-
-static
-Dentry*
-maked(long a, int s, long qpath)
-{
-	Iobuf *p;
-	Dentry *d, *d1;
-
-	p = xtag(a, Tdir, qpath);
-	if(!p)
-		return 0;
-	d = getdir(p, s);
-	d1 = dalloc(sizeof(Dentry));
-	memmove(d1, d, sizeof(Dentry));
-	putbuf(p);
-	return d1;
-}
-
-static
-void
-modd(long a, int s, Dentry *d1)
-{
-	Iobuf *p;
-	Dentry *d;
-
-	if(!(flags & Cbad))
-		return;
-	p = getbuf(dev, a, Bread);
-	d = getdir(p, s);
-	if(!d) {
-		if(p)
-			putbuf(p);
-		return;
-	}
-	memmove(d, d1, sizeof(Dentry));
-	p->flags |= Bmod;
-	putbuf(p);
-}
-
-static
-void
-xread(long a, long qpath)
-{
-	Iobuf *p;
-
-	p = xtag(a, Tfile, qpath);
-	if(p)
-		putbuf(p);
-}
-
-static
-Iobuf*
-xtag(long a, int tag, long qpath)
-{
-	Iobuf *p;
-
-	if(a == 0)
-		return 0;
-	p = getbuf(dev, a, Bread);
-	if(!p) {
-		cprint("check: \"%s\": xtag: p null\n", name);
-		if(flags & (Cream|Ctag)) {
-			p = getbuf(dev, a, Bmod);
-			if(p) {
-				memset(p->iobuf, 0, RBUFSIZE);
-				settag(p, tag, qpath);
-				mod++;
-				return p;
-			}
-		}
-		return 0;
-	}
-	if(checktag(p, tag, qpath)) {
-		cprint("check: \"%s\": xtag: checktag\n", name);
-		if(flags & Cream)
-			memset(p->iobuf, 0, RBUFSIZE);
-		if(flags & (Cream|Ctag)) {
-			settag(p, tag, qpath);
-			mod++;
-		}
-		return p;
-	}
-	return p;
-}
-
-static
-int
-amark(long a)
-{
-	long i;
-	int b;
-
-	if(a < fstart || a >= fsize) {
-		cprint("check: \"%s\": range %ld\n",
-			name, a);
-		nbad++;
-		return 1;
-	}
-	a -= fstart;
-	i = a/8;
-	b = 1 << (a&7);
-	if(abits[i] & b) {
-		if(!ronly) {
-			if(ndup < 10)
-				cprint("check: \"%s\": address dup %ld\n",
-					name, fstart+a);
-			else
-			if(ndup == 10)
-				cprint("...");
-		}
-		ndup++;
-		return 0;	/* really?? */
-	}
-	abits[i] |= b;
-	nused++;
-	return 0;
-}
-
-static
-int
-fmark(long a)
-{
-	long i;
-	int b;
-
-	if(a < fstart || a >= fsize) {
-		cprint("check: \"%s\": range %ld\n",
-			name, a);
-		nbad++;
-		return 1;
-	}
-	a -= fstart;
-	i = a/8;
-	b = 1 << (a&7);
-	if(abits[i] & b) {
-		cprint("check: \"%s\": address dup %ld\n",
-			name, fstart+a);
-		nfdup++;
-		return 1;
-	}
-	abits[i] |= b;
-	nfree++;
-	return 0;
-}
-
-static
-void
-missing(void)
-{
-	long a, i;
-	int b, n;
-
-	n = 0;
-	for(a=fsize-fstart-1; a>=0; a--) {
-		i = a/8;
-		b = 1 << (a&7);
-		if(!(abits[i] & b)) {
-			cprint("missing: %ld\n", fstart+a);
-			n++;
-		}
-		if(n > 10) {
-			cprint(" ...\n");
-			break;
-		}
-	}
-}
-
-static
-void
-qmark(long qpath)
-{
-	int i, b;
-
-	i = qpath/8;
-	b = 1 << (qpath&7);
-	if(i < 0 || i >= sizqbits) {
-		nqbad++;
-		if(nqbad < 20)
-			cprint("check: \"%s\": qid out of range %lux\n",
-				name, qpath);
-		return;
-	}
-	if((qbits[i] & b) && !ronly) {
-		nqbad++;
-		if(nqbad < 20)
-			cprint("check: \"%s\": qid dup %lux\n",
-				name, qpath);
-	}
-	qbits[i] |= b;
-}
--- a/sys/src/cmd/disk/kfs/con.c
+++ /dev/null
@@ -1,705 +1,0 @@
-#include	"all.h"
-#include	"9p1.h"
-
-static	char	elem[NAMELEN];
-static	Filsys*	cur_fs;
-static	char	conline[100];
-
-void
-consserve(void)
-{
-	con_session();
-	cmd_exec("cfs");
-	cmd_exec("user");
-}
-
-int
-cmd_exec(char *arg)
-{
-	char *s, *c;
-	int i;
-
-	for(i=0; s = command[i].string; i++) {
-		for(c=arg; *s; c++)
-			if(*c != *s++)
-				goto brk;
-		if(*c == '\0' || *c == ' ' || *c == '\t'){
-			cons.arg = c;
-			(*command[i].func)();
-			return 1;
-		}
-	brk:;
-	}
-	return 0;
-}
-
-void
-cmd_check(void)
-{
-	char *s;
-	int flags;
-
-	flags = 0;
-	for(s = cons.arg; *s; s++){
-		while(*s == ' ' || *s == '\t')
-			s++;
-		if(*s == '\0')
-			break;
-		switch(*s){
-		/* rebuild the free list */
-		case 'f':	flags |= Cfree;			break;
-		/* fix bad tags */
-		case 't':	flags |= Ctag;			break;
-		/* fix bad tags and clear the contents of the block */
-		case 'c':	flags |= Cream;			break;
-		/* delete all redundant references to a block */
-		case 'd':	flags |= Cbad;			break;
-		/* read and check tags on all blocks */
-		case 'r':	flags |= Crdall;		break;
-		/* write all of the blocks you touch */
-		case 'w':	flags |= Ctouch;		break;
-		/* print all directories as they are read */
-		case 'p':	flags |= Cpdir;			break;
-		/* print all files as they are read */
-		case 'P':	flags |= Cpfile;		break;
-		/* quiet, just report really nasty stuff */
-		case 'q':	flags |= Cquiet;		break;
-		}
-	}
-	check(cur_fs, flags);
-}
-
-enum
-{
-	Sset	= (1<<0),
-	Setc	= (1<<1),
-};
-void
-cmd_stats(void)
-{
-	cprint("work stats\n");
-	cprint("	work = %A rps\n", (Filta){&cons.work, 1});
-	cprint("	rate = %A tBps\n", (Filta){&cons.rate, 1000});
-	cprint("	hits = %A iops\n", (Filta){&cons.bhit, 1});
-	cprint("	read = %A iops\n", (Filta){&cons.bread, 1});
-	cprint("	init = %A iops\n", (Filta){&cons.binit, 1});
-/*	for(i = 0; i < MAXTAG; i++)
-		cprint("	tag %G = %A iops\n", i, (Filta){&cons.tags[i], 1});
-*/
-}
-
-void
-cmd_sync(void)
-{
-	rlock(&mainlock);
-	syncall();
-	runlock(&mainlock);
-}
-
-void
-cmd_halt(void)
-{
-	wlock(&mainlock);
-	syncall();
-	superok(cur_fs->dev, superaddr(cur_fs->dev), 1);
-	print("kfs: file system halted\n");
-}
-
-void
-cmd_start(void)
-{
-	superok(cur_fs->dev, superaddr(cur_fs->dev), 0);
-	wunlock(&mainlock);
-	print("kfs: file system started\n");
-}
-
-void
-cmd_help(void)
-{
-	int i;
-
-	for(i=0; command[i].string; i++)
-		cprint("	%s %s\n", command[i].string, command[i].args);
-	cprint("check options:\n"
-		" r	read all blocks\n"
-		" f	rebuild the free list\n"
-		" t	fix all bad tags\n"
-		" c	fix bad tags and zero the blocks\n"
-		" d	delete all redundant references to blocks\n"
-		" p	print directories as they are checked\n"
-		" P	print all files as they are checked\n"
-		" w	write all blocks that are read\n");
-}
-
-void
-cmd_create(void)
-{
-	int uid, gid, err;
-	long perm;
-	char oelem[NAMELEN];
-	char name[NAMELEN];
-
-	if(err = con_clone(FID1, FID2)){
-		cprint("clone failed: %s\n", errstring[err]);
-		return;
-	}
-	if(skipbl(1)){
-		cprint("skipbl\n");
-		return;
-	}
-	oelem[0] = 0;
-	while(nextelem()) {
-		if(oelem[0])
-			if(err = con_walk(FID2, oelem)){
-				cprint("walk failed: %s\n", errstring[err]);
-				return;
-			}
-		memmove(oelem, elem, NAMELEN);
-	}
-	if(skipbl(1))
-		return;
-	uid = strtouid(cname(name));
-	if(uid == 0){
-		cprint("unknown user %s\n", name);
-		return;
-	}
-	gid = strtouid(cname(name));
-	if(gid == 0){
-		cprint("unknown group %s\n", name);
-		return;
-	}
-	perm = number(0777, 8);
-	skipbl(0);
-	for(; *cons.arg; cons.arg++){
-		if(*cons.arg == 'l')
-			perm |= PLOCK;
-		else
-		if(*cons.arg == 'a')
-			perm |= PAPND;
-		else
-		if(*cons.arg == 'd')
-			perm |= PDIR;
-		else
-			break;
-	}
-	err = con_create(FID2, elem, uid, gid, perm, 0);
-	if(err)
-		cprint("can't create %s: %s\n", elem, errstring[err]);
-}
-
-void
-cmd_clri(void)
-{
-	if(con_clone(FID1, FID2))
-		return;
-	if(skipbl(1))
-		return;
-	while(nextelem())
-		if(con_walk(FID2, elem)){
-			cprint("can't walk %s\n", elem);
-			return;
-		}
-	con_clri(FID2);
-}
-
-void
-cmd_rename(void)
-{
-	ulong perm;
-	Dentry d;
-	char stat[DIRREC];
-	char oelem[NAMELEN], noelem[NAMELEN], nxelem[NAMELEN];
-	int err;
-
-	if(con_clone(FID1, FID2))
-		return;
-	if(skipbl(1))
-		return;
-	oelem[0] = 0;
-	while(nextelem()) {
-		if(oelem[0])
-			if(con_walk(FID2, oelem)){
-				cprint("file does not exits");
-				return;
-			}
-		memmove(oelem, elem, NAMELEN);
-	}
-	if(skipbl(1))
-		return;
-	if(cons.arg[0]=='/'){
-		if(con_clone(FID1, FID3))
-			return;
-		noelem[0] = 0;
-		while(nextelem()){
-			if(noelem[0])
-				if(con_walk(FID3, noelem)){
-					cprint("target path %s does not exist", noelem);
-					return;
-				}
-			memmove(noelem, elem, NAMELEN);
-		}
-		if(!con_walk(FID3, elem)){
-			cprint("target %s already exists\n", elem);
-			return;
-		}
-		if(con_walk(FID2, oelem)){
-			cprint("src %s does not exist\n", oelem);
-			return;
-		}
-		/*
-		 * we know the target does not exist,
-		 * the source does exist.
-		 * to do the rename, create the target and then
-		 * copy the directory entry directly.  then remove the source.
-		 */
-		if(err = con_stat(FID2, stat)){
-			cprint("can't stat file: %s\n", errstring[err]);
-			return;
-		}
-		convM2D9p1(stat, &d);
-		perm = (d.mode&0777)|((d.mode&0x7000)<<17);
-		if(err = con_create(FID3, elem, d.uid, d.gid, perm, (d.mode&DDIR)?OREAD:ORDWR)){
-			cprint("can't create %s: %s\n", elem, errstring[err]);
-			return;
-		}
-		if(err = con_swap(FID2, FID3)){
-			cprint("can't swap data: %s\n", errstring[err]);
-			return;
-		}
-		if(err = con_remove(FID2)){
-			cprint("can't remove file: %s\n", errstring[err]);
-			return;
-		}		
-	}else{
-		cname(nxelem);
-		if(strchr(nxelem, '/')){
-			cprint("bad rename target: not full path, but contains slashes\n");
-			return;
-		}
-		if(!con_walk(FID2, nxelem))
-			cprint("file %s already exists\n", nxelem);
-		else if(con_walk(FID2, oelem))
-			cprint("file does not already exist\n");
-		else if(err = con_stat(FID2, stat))
-			cprint("can't stat file: %s\n", errstring[err]);
-		else{
-			convM2D9p1(stat, &d);
-			strncpy(d.name, nxelem, NAMELEN);
-			convD2M9p1(&d, stat);
-			if(err = con_wstat(FID2, stat))
-				cprint("can't move file: %s\n", errstring[err]);
-		}
-	}	
-}
-
-void
-cmd_remove(void)
-{
-	if(con_clone(FID1, FID2))
-		return;
-	if(skipbl(1))
-		return;
-	while(nextelem())
-		if(con_walk(FID2, elem)){
-			cprint("can't walk %s\n", elem);
-			return;
-		}
-	con_remove(FID2);
-}
-
-void
-cmd_cfs(void)
-{
-	Filsys *fs;
-
-	if(*cons.arg != ' ') {
-		fs = &filesys[0];		/* default */
-	} else {
-		if(skipbl(1)){
-			cprint("skipbl\n");
-			return;
-		}
-		if(!nextelem())
-			fs = &filesys[0];	/* default */
-		else
-			fs = fsstr(elem);
-	}
-	if(fs == 0) {
-		cprint("unknown file system %s\n", elem);
-		return;
-	}
-	if(con_attach(FID1, "adm", fs->name))
-		panic("FID1 attach to root");
-	cur_fs = fs;
-}
-
-/*
- * find out the length of a file
- * given the mesg version of a stat buffer
- * we call this because convM2D is different
- * for the file system than in the os
- */
-static uvlong
-statlen(char *ap)
-{
-	uchar *p;
-	ulong ll, hl;
-
-	p = (uchar*)ap;
-	p += 3*28+5*4;
-	ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
-	hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
-	return ll | ((uvlong) hl << 32);
-}
-
-int
-adduser(char *user, int isgroup)
-{
-	char stat[DIRREC];
-	char msg[100];
-	Uid *u;
-	int i, c, nu;
-
-	/*
-	 * check uniq of name
-	 * and get next uid
-	 */
-	cmd_exec("cfs");
-	cmd_exec("user");
-	if(isgroup)
-		nu = 9000;
-	else
-		nu = 0;
-	for(i=0, u=uid; i<conf.nuid; i++,u++) {
-		c = u->uid;
-		if(c == 0)
-			break;
-		if(strcmp(uidspace+u->offset, user) == 0)
-			return 1;
-		if(c >= 9000 && !isgroup)
-			continue;
-		if(c > nu)
-			nu = c;
-	}
-	nu++;
-	if(isgroup){
-		if(nu >= 0x10000) {
-			cprint("out of group ids\n");
-			return 0;
-		}
-	} else {
-		if(nu >= 9000) {
-			cprint("out of user ids\n");
-			return 0;
-		}
-	}
-
-	/*
-	 * write onto adm/users
-	 */
-	if(con_clone(FID1, FID2)
-	|| con_path(FID2, "/adm/users")
-	|| con_open(FID2, 1)) {
-		cprint("can't open /adm/users\n");
-		return 0;
-	}
-
-	sprint(msg, "%d:%s:%s:\n", nu, user, user);
-	cprint("add user %s", msg);
-	c = strlen(msg);
-	i = con_stat(FID2, stat);
-	if(i){
-		cprint("can't stat /adm/users: %s\n", errstring[i]);
-		return 0;
-	}
-	i = con_write(FID2, msg, statlen(stat), c);
-	if(i != c){
-		cprint("short write on /adm/users: %d %d\n", c, i);
-		return 0;
-	}
-	return 1;
-}
-
-void
-cmd_newuser(void)
-{
-	char user[NAMELEN], param[NAMELEN], msg[100];
-	int i, c;
-
-	/*
-	 * get uid
-	 */
-	cname(user);
-	cname(param);
-	for(i=0; i<NAMELEN; i++) {
-		c = user[i];
-		if(c == 0)
-			break;
-		if(c >= '0' && c <= '9'
-		|| c >= 'a' && c <= 'z'
-		|| c >= 'A' && c <= 'Z')
-			continue;
-		cprint("bad character in name: 0x%x\n", c);
-		return;
-	}
-	if(i < 2) {
-		cprint("name too short: %s\n", user);
-		return;
-	}
-	if(i >= NAMELEN) {
-		cprint("name too long: %s\n", user);
-		return;
-	}
-
-	switch(param[0]){
-	case 0:
-		if(!adduser(user, 0))
-			return;
-		cmd_exec("user");
-		break;
-	case ':':
-		adduser(user, 1);
-		cmd_exec("user");
-		return;
-	case '#':
-		adduser(user, 0);
-		cmd_exec("user");
-		return;
-	}
-
-	/*
-	 * create directories
-	 */
-	cmd_exec("user");
-	sprint(msg, "create /usr/%s %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/tmp %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/lib %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/bin %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/bin/rc %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/bin/mips %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/bin/386 %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/bin/power %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-	sprint(msg, "create /usr/%s/bin/alpha %s %s 775 d", user, user, user);
-	cmd_exec(msg);
-}
-
-void
-cmd_checkuser(void)
-{
-	uchar buf[DIRREC], *p;
-	static char utime[4];
-
-	if(con_clone(FID1, FID2)
-	|| con_path(FID2, "/adm/users")
-	|| con_open(FID2, 0)
-	|| con_stat(FID2, (char*)buf))
-		return;
-	p = buf + 3*NAMELEN + 4*4;
-	if(memcmp(utime, p, 4) == 0)
-		return;
-	memmove(utime, p, 4);
-	cmd_user();
-}
-
-void
-cmd_allow(void)
-{
-	wstatallow = 1;
-}
-
-void
-cmd_disallow(void)
-{
-	wstatallow = 0;
-}
-
-void
-cmd_chat(void)
-{
-	chat = 1 - chat;
-}
-
-void
-cmd_atime(void)
-{
-	noatime = !noatime;
-	if(noatime)
-		cprint("atimes will not be updated\n");
-	else
-		cprint("atimes will be updated\n");
-}
-
-void
-cmd_noneattach(void)
-{
-	allownone = !allownone;
-	if(allownone) 
-		cprint("none can attach to new connections\n");
-	else
-		cprint("none can only attach on authenticated connections\n");
-}
-
-void
-cmd_listen(void)
-{
-	char addr[NAMELEN];
-
-	if(skipbl(0))
-		strcpy(addr, "tcp!*!564");	/* 9fs */
-	else
-		cname(addr);
-
-	if(netserve(addr))
-		cprint("announce %s failed\n", addr);
-	else
-		cprint("announce %s\n", addr);
-}
-
-void
-cmd_nowritegroup(void)
-{
-	writegroup = 0;
-}
-
-Command	command[] =
-{
-	"allow",	cmd_allow,	"",
-	"allowoff",	cmd_disallow,	"",
-	"atime",		cmd_atime,	"",
-	"cfs",		cmd_cfs,	"[filesys]",
-	"chat",		cmd_chat,	"",
-	"check",	cmd_check,	"[cdfpPqrtw]",
-	"clri",		cmd_clri,	"filename",
-	"create",	cmd_create,	"filename user group perm [ald]",
-	"disallow",	cmd_disallow,	"",
-	"halt",		cmd_halt,	"",
-	"help",		cmd_help,	"",
-	"listen",		cmd_listen,	"[address]",
-	"newuser",	cmd_newuser,	"username",
-	"noneattach",	cmd_noneattach,	"",
-	"nowritegroup",	cmd_nowritegroup,	"",
-	"remove",	cmd_remove,	"filename",
-	"rename",	cmd_rename,	"file newname",
-	"start",	cmd_start, "",
-	"stats",	cmd_stats,	"[fw]",
-	"sync",		cmd_sync,	"",
-	"user",		cmd_user,	"",
-	0
-};
-
-int
-skipbl(int err)
-{
-	if(*cons.arg != ' ') {
-		if(err)
-			cprint("syntax error\n");
-		return 1;
-	}
-	while(*cons.arg == ' ')
-		cons.arg++;
-	return 0;
-}
-
-char*
-_cname(char *name)
-{
-	int i, c;
-
-	memset(name, 0, NAMELEN);
-	for(i=0;; i++) {
-		c = *cons.arg;
-		switch(c) {
-		case ' ':
-		case '\t':
-		case '\n':
-		case '\0':
-			return name;
-		}
-		if(i < NAMELEN-1)
-			name[i] = c;
-		cons.arg++;
-	}
-}
-
-char*
-cname(char *name)
-{
-	skipbl(0);
-	return _cname(name);
-}
-
-int
-nextelem(void)
-{
-	char *e;
-	int i, c;
-
-	e = elem;
-	while(*cons.arg == '/')
-		cons.arg++;
-	c = *cons.arg;
-	if(c == 0 || c == ' ')
-		return 0;
-	for(i = 0; c = *cons.arg; i++) {
-		if(c == ' ' || c == '/')
-			break;
-		if(i == NAMELEN) {
-			cprint("path name component too long\n");
-			return 0;
-		}
-		*e++ = c;
-		cons.arg++;
-	}
-	*e = 0;
-	return 1;
-}
-
-long
-number(int d, int base)
-{
-	int c, sign, any;
-	long n;
-
-	sign = 0;
-	any = 0;
-	n = 0;
-
-	c = *cons.arg;
-	while(c == ' ') {
-		cons.arg++;
-		c = *cons.arg;
-	}
-	if(c == '-') {
-		sign = 1;
-		cons.arg++;
-		c = *cons.arg;
-	}
-	while((c >= '0' && c <= '9') ||
-	      (base == 16 && c >= 'a' && c <= 'f') ||
-	      (base == 16 && c >= 'A' && c <= 'F')) {
-		n *= base;
-		if(c >= 'a' && c <= 'f')
-			n += c - 'a' + 10;
-		else
-		if(c >= 'A' && c <= 'F')
-			n += c - 'A' + 10;
-		else
-			n += c - '0';
-		cons.arg++;
-		c = *cons.arg;
-		any = 1;
-	}
-	if(!any)
-		return d;
-	if(sign)
-		n = -n;
-	return n;
-}
--- a/sys/src/cmd/disk/kfs/console.c
+++ /dev/null
@@ -1,371 +1,0 @@
-#include	"all.h"
-#include	"9p1.h"
-
-void
-fcall9p1(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	int t;
-
-	rlock(&mainlock);
-	t = in->type;
-	if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
-		print("bad message type %d\n", t);
-		panic("");
-	}
-	ou->type = t+1;
-	ou->err = 0;
-
-	rlock(&cp->reflock);
-	(*call9p1[t])(cp, in, ou);
-	runlock(&cp->reflock);
-
-	if(ou->err)
-		if(CHAT(cp))
-			print("	error: %s\n", errstring[ou->err]);
-	cons.work.count++;
-	runlock(&mainlock);
-}
-
-int
-con_session(void)
-{
-	Oldfcall in, ou;
-
-	in.type = Tsession9p1;
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_attach(int fid, char *uid, char *arg)
-{
-	Oldfcall in, ou;
-
-	in.type = Tattach9p1;
-	in.fid = fid;
-	strncpy(in.uname, uid, NAMELEN);
-	strncpy(in.aname, arg, NAMELEN);
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_clone(int fid1, int fid2)
-{
-	Oldfcall in, ou;
-
-	in.type = Tclone9p1;
-	in.fid = fid1;
-	in.newfid = fid2;
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_path(int fid, char *path)
-{
-	Oldfcall in, ou;
-	char *p;
-
-	in.type = Twalk9p1;
-	in.fid = fid;
-
-loop:
-	if(*path == 0)
-		return 0;
-	strncpy(in.name, path, NAMELEN);
-	if(p = strchr(path, '/')) {
-		path = p+1;
-		if(p = strchr(in.name, '/'))
-			*p = 0;
-	} else
-		path = strchr(path, 0);
-	if(in.name[0]) {
-		fcall9p1(cons.chan, &in, &ou);
-		if(ou.err)
-			return ou.err;
-	}
-	goto loop;
-}
-
-int
-con_walk(int fid, char *name)
-{
-	Oldfcall in, ou;
-
-	in.type = Twalk9p1;
-	in.fid = fid;
-	strncpy(in.name, name, NAMELEN);
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_stat(int fid, char *data)
-{
-	Oldfcall in, ou;
-
-	in.type = Tstat9p1;
-	in.fid = fid;
-	fcall9p1(cons.chan, &in, &ou);
-	if(ou.err == 0)
-		memmove(data, ou.stat, sizeof ou.stat);
-	return ou.err;
-}
-
-int
-con_wstat(int fid, char *data)
-{
-	Oldfcall in, ou;
-
-	in.type = Twstat9p1;
-	in.fid = fid;
-	memmove(in.stat, data, sizeof in.stat);
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_open(int fid, int mode)
-{
-	Oldfcall in, ou;
-
-	in.type = Topen9p1;
-	in.fid = fid;
-	in.mode = mode;
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_read(int fid, char *data, long offset, int count)
-{
-	Oldfcall in, ou;
-
-	in.type = Tread9p1;
-	in.fid = fid;
-	in.offset = offset;
-	in.count = count;
-	ou.data = data;
-	fcall9p1(cons.chan, &in, &ou);
-	if(ou.err)
-		return 0;
-	return ou.count;
-}
-
-int
-con_write(int fid, char *data, long offset, int count)
-{
-	Oldfcall in, ou;
-
-	in.type = Twrite9p1;
-	in.fid = fid;
-	in.data = data;
-	in.offset = offset;
-	in.count = count;
-	fcall9p1(cons.chan, &in, &ou);
-	if(ou.err)
-		return 0;
-	return ou.count;
-}
-
-int
-con_remove(int fid)
-{
-	Oldfcall in, ou;
-
-	in.type = Tremove9p1;
-	in.fid = fid;
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-con_create(int fid, char *name, int uid, int gid, long perm, int mode)
-{
-	Oldfcall in, ou;
-
-	in.type = Tcreate9p1;
-	in.fid = fid;
-	strncpy(in.name, name, NAMELEN);
-	in.perm = perm;
-	in.mode = mode;
-	cons.uid = uid;			/* beyond ugly */
-	cons.gid = gid;
-	fcall9p1(cons.chan, &in, &ou);
-	return ou.err;
-}
-
-int
-doclri(File *f)
-{
-	Iobuf *p, *p1;
-	Dentry *d, *d1;
-	int err;
-
-	err = 0;
-	p = 0;
-	p1 = 0;
-	if(isro(f->fs->dev)) {
-		err = Eronly;
-		goto out;
-	}
-	/*
-	 * check on parent directory of file to be deleted
-	 */
-	if(f->wpath == 0 || f->wpath->addr == f->addr) {
-		err = Ephase;
-		goto out;
-	}
-	p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
-	d1 = getdir(p1, f->wpath->slot);
-	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
-		err = Ephase;
-		goto out;
-	}
-
-	accessdir(p1, d1, FWRITE);
-	putbuf(p1);
-	p1 = 0;
-
-	/*
-	 * check on file to be deleted
-	 */
-	p = getbuf(f->fs->dev, f->addr, Bread);
-	d = getdir(p, f->slot);
-
-
-	/*
-	 * do it
-	 */
-	memset(d, 0, sizeof(Dentry));
-	settag(p, Tdir, QPNONE);
-	freewp(f->wpath);
-	freefp(f);
-
-out:
-	if(p1)
-		putbuf(p1);
-	if(p)
-		putbuf(p);
-	return err;
-}
-
-void
-f_clri(Chan *cp, Oldfcall *in, Oldfcall *ou)
-{
-	File *f;
-
-	if(CHAT(cp)) {
-		print("c_clri %d\n", cp->chan);
-		print("	fid = %d\n", in->fid);
-	}
-
-	f = filep(cp, in->fid, 0);
-	if(!f) {
-		ou->err = Efid;
-		goto out;
-	}
-	ou->err = doclri(f);
-
-out:
-	ou->fid = in->fid;
-	if(f)
-		qunlock(f);
-}
-
-int
-con_clri(int fid)
-{
-	Oldfcall in, ou;
-	Chan *cp;
-
-	in.type = Tremove9p1;
-	in.fid = fid;
-	cp = cons.chan;
-
-	rlock(&mainlock);
-	ou.type = Tremove9p1+1;
-	ou.err = 0;
-
-	rlock(&cp->reflock);
-
-	f_clri(cp, &in, &ou);
-
-	runlock(&cp->reflock);
-
-	cons.work.count++;
-	runlock(&mainlock);
-	return ou.err;
-}
-
-int
-con_swap(int fid1, int fid2)
-{
-	int err;
-	Iobuf *p1, *p2;
-	File *f1, *f2;
-	Dentry *d1, *d2;
-	Dentry dt1, dt2;
-	Chan *cp;
-
-	cp = cons.chan;
-	err = 0;
-	rlock(&mainlock);
-	rlock(&cp->reflock);
-
-	f2 = nil;
-	p1 = p2 = nil;
-	f1 = filep(cp, fid1, 0);
-	if(!f1){
-		err = Efid;
-		goto out;
-	}
-	p1 = getbuf(f1->fs->dev, f1->addr, Bread|Bmod);
-	d1 = getdir(p1, f1->slot);
-	if(!d1 || !(d1->mode&DALLOC)){
-		err = Ealloc;
-		goto out;
-	}
-
-	f2 = filep(cp, fid2, 0);
-	if(!f2){
-		err = Efid;
-		goto out;
-	}
-	if(memcmp(&f1->fs->dev, &f2->fs->dev, 4)==0
-	&& f2->addr == f1->addr)
-		p2 = p1;
-	else
-		p2 = getbuf(f2->fs->dev, f2->addr, Bread|Bmod);
-	d2 = getdir(p2, f2->slot);
-	if(!d2 || !(d2->mode&DALLOC)){
-		err = Ealloc;
-		goto out;
-	}
-
-	dt1 = *d1;
-	dt2 = *d2;
-	*d1 = dt2;
-	*d2 = dt1;
-	memmove(d1->name, dt1.name, NAMELEN);
-	memmove(d2->name, dt2.name, NAMELEN);
-
-	mkqid(&f1->qid, d1, 1);
-	mkqid(&f2->qid, d2, 1);
-out:
-	if(f1)
-		qunlock(f1);
-	if(f2)
-		qunlock(f2);
-	if(p1)
-		putbuf(p1);
-	if(p2 && p2!=p1)
-		putbuf(p2);
-
-	runlock(&cp->reflock);
-	cons.work.count++;
-	runlock(&mainlock);
-
-	return err;
-}
--- a/sys/src/cmd/disk/kfs/dat.c
+++ /dev/null
@@ -1,87 +1,0 @@
-#include	"all.h"
-
-Uid*	uid;
-char*	uidspace;
-short*	gidspace;
-RWLock	mainlock;
-long	boottime;
-Tlock	*tlocks;
-Conf	conf;
-Cons	cons;
-Chan	*chan;
-char	service[2*NAMELEN];
-char	*progname;
-char	*procname;
-int	RBUFSIZE;
-int	BUFSIZE;
-int	DIRPERBUF;
-int	INDPERBUF;
-int	INDPERBUF2;
-int	FEPERBUF;
-
-Filsys	filesys[MAXFILSYS] =
-{
-	{"main",	{Devwren, 0, 0, 0},	0},
-};
-
-Device 	devnone = {Devnone, 0, 0, 0};
-
-Devcall devcall[MAXDEV] = {
-	[Devnone]	{0},
-	[Devwren]	{wreninit, wrenream, wrencheck, wrensuper, wrenroot, wrensize, wrenread, wrenwrite},
-};
-
-char*	tagnames[] =
-{
-	[Tbuck]		"Tbuck",
-	[Tdir]		"Tdir",
-	[Tfile]		"Tfile",
-	[Tfree]		"Tfree",
-	[Tind1]		"Tind1",
-	[Tind2]		"Tind2",
-	[Tnone]		"Tnone",
-	[Tsuper]	"Tsuper",
-	[Tvirgo]	"Tvirgo",
-	[Tcache]	"Tcache",
-};
-
-char	*errstring[MAXERR] =
-{
-	[Ebadspc]	"attach -- bad specifier",
-	[Efid]		"unknown fid",
-	[Echar]		"bad character in directory name",
-	[Eopen]		"read/write -- on non open fid",
-	[Ecount]	"read/write -- count too big",
-	[Ealloc]	"phase error -- directory entry not allocated",
-	[Eqid]		"phase error -- qid does not match",
-	[Eauth]		"authentication failed",
-	[Eauthmsg]	"kfs: authentication not required",
-	[Eaccess]	"access permission denied",
-	[Eentry]	"directory entry not found",
-	[Emode]		"open/create -- unknown mode",
-	[Edir1]		"walk -- in a non-directory",
-	[Edir2]		"create -- in a non-directory",
-	[Ephase]	"phase error -- cannot happen",
-	[Eexist]	"create -- file exists",
-	[Edot]		"create -- . and .. illegal names",
-	[Eempty]	"remove -- directory not empty",
-	[Ebadu]		"attach -- privileged user",
-	[Enotu]		"wstat -- not owner",
-	[Enotg]		"wstat -- not in group",
-	[Enotl]		"wstat -- attempt to change length",
-	[Enotd]		"wstat -- attempt to change directory",
-	[Enotm]		"wstat -- unknown type/mode",
-	[Ename]		"create/wstat -- bad character in file name",
-	[Ewalk]		"walk -- too many (system wide)",
-	[Eronly]	"file system read only",
-	[Efull]		"file system full",
-	[Eoffset]	"read/write -- offset negative",
-	[Elocked]	"open/create -- file is locked",
-	[Ebroken]	"close/read/write -- lock is broken",
-	[Efidinuse]	"fid already in use",
-	[Etoolong]	"name too long",
-	[Ersc]	"it's russ's fault.  bug him.",
-	[Econvert]	"protocol botch",
-	[Eqidmode]	"wstat -- qid.type/dir.mode mismatch",
-	[Esystem]	"kfs system error",
-};
--- a/sys/src/cmd/disk/kfs/dat.h
+++ /dev/null
@@ -1,170 +1,0 @@
-typedef	struct	Chan	Chan;
-typedef struct	Command	Command;
-typedef	struct	Conf	Conf;
-typedef	struct	Cons	Cons;
-typedef struct	Devcall	Devcall;
-
-#define MAXBUFSIZE	(16*1024)	/* max. buffer size */
-
-#include "portdat.h"
-
-struct	Chan
-{
-	int	chan;			/* fd request came in on */
-	QLock rlock, wlock;		/* lock for reading/writing messages on chan */
-	int	type;
-	int	flags;
-	long	whotime;
-	File*	flist;			/* base of file structures */
-	Lock	flock;			/* manipulate flist */
-	RWLock	reflock;		/* lock for Tflush */
-	int	msize;			/* version */
-	int	authed;		/* someone other than ``none'' has authed */
-
-/* 9p1 auth */
-	uchar	chal[8];
-	uchar	rchal[8];
-	int	idoffset;
-	int	idvec;
-	Lock	idlock;
-};
-
-/*
- * console cons.flag flags
- */
-enum
-{
-	Fchat	= (1<<0),	/* print out filesys rpc traffic */
-	Fuid	= (1<<2),	/* print out uids */
-				/* debugging flags for drivers */
-};
-
-struct	Cons
-{
-	int	flags;		/* overall flags for all channels */
-	int	uid;		/* botch -- used to get uid on cons_create */
-	int	gid;		/* botch -- used to get gid on cons_create */
-	int	allow;		/* no-protection flag */
-	long	offset;		/* used to read files, c.f. fchar */
-	char*	arg;		/* pointer to remaining line */
-
-	Chan	*chan;	/* console channel */
-	Chan	*srvchan;	/* local server channel */
-
-	Filter	work;		/* thruput in messages */
-	Filter	rate;		/* thruput in bytes */
-	Filter	bhit;		/* getbufs that hit */
-	Filter	bread;		/* getbufs that miss and read */
-	Filter	binit;		/* getbufs that miss and dont read */
-	Filter	tags[MAXTAG];	/* reads of each type of block */
-};
-
-struct	Conf
-{
-	ulong	niobuf;		/* number of iobufs to allocate */
-	ulong	nuid;		/* distinct uids */
-	ulong	uidspace;	/* space for uid names -- derrived from nuid */
-	ulong	gidspace;	/* space for gid names -- derrived from nuid */
-	ulong	nserve;		/* server processes */
-	ulong	nfile;		/* number of fid -- system wide */
-	ulong	nwpath;		/* number of active paths, derrived from nfile */
-	ulong	bootsize;	/* number of bytes reserved for booting */
-};
-
-struct	Command
-{
-	char	*string;
-	void	(*func)(void);
-	char	*args;
-};
-
-struct Devcall
-{
-	void	(*init)(Device);
-	void	(*ream)(Device);
-	int	(*check)(Device);
-	long	(*super)(Device);
-	long	(*root)(Device);
-	long	(*size)(Device);
-	int	(*read)(Device, long, void*);
-	int	(*write)(Device, long, void*);
-};
-
-/*
- * device types
- */
-enum
-{
-	Devnone 	= 0,
-	Devwren,
-	MAXDEV
-};
-
-/*
- * file systems
- */
-enum
-{
-	MAXFILSYS = 4
-};
-
-/*
- * should be in portdat.h
- */
-#define	QPDIR	0x80000000L
-#define	QPNONE	0
-#define	QPROOT	1
-#define	QPSUPER	2
-
-/*
- * perm argument in p9 create
- */
-#define	PDIR	(1L<<31)	/* is a directory */
-#define	PAPND	(1L<<30)	/* is append only */
-#define	PLOCK	(1L<<29)	/* is locked on open */
-
-#define	NOF	(-1)
-
-#define	FID1		1
-#define	FID2		2
-#define	FID3		3
-
-#define SECOND(n) 	(n)
-#define MINUTE(n)	(n*SECOND(60))
-#define HOUR(n)		(n*MINUTE(60))
-#define DAY(n)		(n*HOUR(24))
-#define	TLOCK		MINUTE(5)
-
-#define	CHAT(cp)	(chat)
-#define	QID9P1(a,b)	(Qid9p1){a,b}
-
-extern	Uid*	uid;
-extern	char*	uidspace;
-extern	short*	gidspace;
-extern	char*	errstring[MAXERR];
-extern	Chan*	chans;
-extern	RWLock	mainlock;
-extern	long	boottime;
-extern	Tlock	*tlocks;
-extern	Device	devnone;
-extern	Filsys	filesys[];
-extern	char	service[];
-extern	char*	tagnames[];
-extern	Conf	conf;
-extern	Cons	cons;
-extern	Command	command[];
-extern	Chan	*chan;
-extern	Devcall	devcall[];
-extern	char	*progname;
-extern	char	*procname;
-extern	long	niob;
-extern	long	nhiob;
-extern	Hiob	*hiob;
-extern	int	chat;
-extern	int	writeallow;
-extern	int	wstatallow;
-extern	int	allownone;
-extern	int	noatime;
-extern	int	writegroup;
-
-extern Lock wpathlock;
--- a/sys/src/cmd/disk/kfs/dentry.c
+++ /dev/null
@@ -1,174 +1,0 @@
-#include	"all.h"
-
-Dentry*
-getdir(Iobuf *p, int slot)
-{
-	Dentry *d;
-
-	if(!p)
-		return 0;
-	d = (Dentry*)p->iobuf + slot%DIRPERBUF;
-	return d;
-}
-
-void
-accessdir(Iobuf *p, Dentry *d, int f)
-{
-	long t;
-
-	if(p && !isro(p->dev)) {
-		if(!(f & (FWRITE|FWSTAT)) && noatime)
-			return;
-		t = time(nil);
-		if(f & (FREAD|FWRITE|FWSTAT)){
-			d->atime = t;
-			p->flags |= Bmod;
-		}
-		if(f & FWRITE) {
-			d->mtime = t;
-			d->qid.version++;
-			p->flags |= Bmod;
-		}
-	}
-}
-
-void
-dbufread(Iobuf *p, Dentry *d, long a)
-{
-	USED(p, d, a);
-}
-
-long
-rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb)
-{
-	long addr, qpath;
-	Device dev;
-
-	if(a < 0) {
-		print("dnodebuf: neg\n");
-		return 0;
-	}
-	qpath = d->qid.path;
-	dev = p->dev;
-	if(a < NDBLOCK) {
-		addr = d->dblock[a];
-		if(!addr && tag) {
-			addr = balloc(dev, tag, qpath);
-			d->dblock[a] = addr;
-			p->flags |= Bmod|Bimm;
-		}
-		if(putb)
-			putbuf(p);
-		return addr;
-	}
-	a -= NDBLOCK;
-	if(a < INDPERBUF) {
-		addr = d->iblock;
-		if(!addr && tag) {
-			addr = balloc(dev, Tind1, qpath);
-			d->iblock = addr;
-			p->flags |= Bmod|Bimm;
-		}
-		if(putb)
-			putbuf(p);
-		addr = indfetch(p, d, addr, a, Tind1, tag);
-		return addr;
-	}
-	a -= INDPERBUF;
-	if(a < INDPERBUF2) {
-		addr = d->diblock;
-		if(!addr && tag) {
-			addr = balloc(dev, Tind2, qpath);
-			d->diblock = addr;
-			p->flags |= Bmod|Bimm;
-		}
-		if(putb)
-			putbuf(p);
-		addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
-		addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
-		return addr;
-	}
-	if(putb)
-		putbuf(p);
-	print("dnodebuf: trip indirect\n");
-	return 0;
-}
-
-Iobuf*
-dnodebuf(Iobuf *p, Dentry *d, long a, int tag)
-{
-	long addr;
-
-	addr = rel2abs(p, d, a, tag, 0);
-	if(addr)
-		return getbuf(p->dev, addr, Bread);
-	return 0;
-}
-
-/*
- * same as dnodebuf but it calls putpuf(p)
- * to reduce interference.
- */
-Iobuf*
-dnodebuf1(Iobuf *p, Dentry *d, long a, int tag)
-{
-	long addr;
-	Device dev;
-
-	dev = p->dev;
-	addr = rel2abs(p, d, a, tag, 1);
-	if(addr)
-		return getbuf(dev, addr, Bread);
-	return 0;
-
-}
-
-long
-indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
-{
-	Iobuf *bp;
-
-	if(!addr)
-		return 0;
-	bp = getbuf(p->dev, addr, Bread);
-	if(!bp || checktag(bp, itag, d->qid.path)) {
-		if(!bp) {
-			print("ind fetch bp = 0\n");
-			return 0;
-		}
-		print("ind fetch tag\n");
-		putbuf(bp);
-		return 0;
-	}
-	addr = ((long*)bp->iobuf)[a];
-	if(!addr && tag) {
-		addr = balloc(p->dev, tag, d->qid.path);
-		if(addr) {
-			((long*)bp->iobuf)[a] = addr;
-			bp->flags |= Bmod;
-			if(localfs || tag == Tdir)
-				bp->flags |= Bimm;
-			settag(bp, itag, d->qid.path);
-		}
-	}
-	putbuf(bp);
-	return addr;
-}
-
-void
-dtrunc(Iobuf *p, Dentry *d)
-{
-	int i;
-
-	bfree(p->dev, d->diblock, 2);
-	d->diblock = 0;
-	bfree(p->dev, d->iblock, 1);
-	d->iblock = 0;
-	for(i=NDBLOCK-1; i>=0; i--) {
-		bfree(p->dev, d->dblock[i], 0);
-		d->dblock[i] = 0;
-	}
-	d->size = 0;
-	p->flags |= Bmod|Bimm;
-	accessdir(p, d, FWRITE);
-}
--- a/sys/src/cmd/disk/kfs/devmulti.c
+++ /dev/null
@@ -1,244 +1,0 @@
-#include "all.h"
-
-enum{
-	MAXWREN = 7,
-};
-
-static char WMAGIC[] =	"kfs wren device\n";
-static char MMAGIC[] =	"kfs multi-wren device %4d/%4d\n";
-
-typedef struct Wren	Wren;
-
-struct Wren{
-	QLock;
-	Device	dev;
-	ulong	nblocks;
-	int	fd;
-};
-
-static char	*wmagic = WMAGIC;
-static Wren	*wrens;
-static int	maxwren;
-char		*wrenfile;
-int		nwren;
-int		badmagic;
-
-static Wren *
-wren(Device dev)
-{
-	int i;
-
-	for(i = 0; i < maxwren; i++)
-		if(devcmp(dev, wrens[i].dev) == 0)
-			return &wrens[i];
-	panic("can't find wren for %D", dev);
-	return 0;
-}
-
-/*
- * find out the length of a file
- * given the mesg version of a stat buffer
- * we call this because convM2D is different
- * for the file system than in the os
- */
-uvlong
-statlen(char *ap)
-{
-	uchar *p;
-	ulong ll, hl;
-
-	p = (uchar*)ap;
-	p += 3*NAMELEN+5*4;
-	ll = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
-	hl = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
-	return ll | ((uvlong) hl << 32);
-}
-
-static void
-wrenpartinit(Device dev, int k)
-{
-	char buf[MAXBUFSIZE], d[DIRREC];
-	char file[128], magic[64];
-	Wren *w;
-	int fd, i, nmagic;
-
-	if(wrens == 0)
-		wrens = ialloc(MAXWREN * sizeof *wrens);
-	w = &wrens[maxwren];
-	if(nwren > 0)
-		sprint(file, "%s%d", wrenfile, k);
-	else
-		strcpy(file, wrenfile);
-	fd = open(file, ORDWR);
-	if(fd < 0)
-		panic("can't open %s", file);
-	if(fstat(fd, d) < 0)
-		panic("can't stat %s\n", file);
-	seek(fd, 0, 0);
-	i = read(fd, buf, sizeof buf);
-	if(i < sizeof buf)
-		panic("can't read %s", file);
-	badmagic = 0;
-	RBUFSIZE = 1024;
-	sprint(magic, wmagic, k, nwren);
-	nmagic = strlen(magic);
-	if(strncmp(buf+256, magic, nmagic) == 0){
-		RBUFSIZE = atol(buf+256+nmagic);
-		if(RBUFSIZE % 512){
-			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
-			RBUFSIZE = 1024;
-		}
-	}else
-		badmagic = 1;
-	w->dev = dev;
-	w->nblocks = statlen(d)/RBUFSIZE;
-	if(k > 0)
-		w->nblocks -= 1;	/* don't count magic */
-	w->fd = fd;
-	maxwren++;
-}
-
-void
-wreninit(Device dev)
-{
-	int i;
-
-	if(nwren > 0)
-		wmagic = MMAGIC;
-	i = 0;
-	do{
-		wrenpartinit(dev, i);
-	}while(++i < nwren);
-}
-
-static void
-wrenpartream(Device dev, int k)
-{
-	Wren *w;
-	char buf[MAXBUFSIZE], magic[64];
-	int fd, i;
-
-	if(RBUFSIZE % 512)
-		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
-	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
-	w = wren(dev)+k;
-	fd = w->fd;
-	memset(buf, 0, sizeof buf);
-	sprint(magic, wmagic, k, nwren);
-	sprint(buf+256, "%s%d\n", magic, RBUFSIZE);
-	qlock(w);
-	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
-	qunlock(w);
-	if(i < 0)
-		panic("can't ream disk");
-}
-
-void
-wrenream(Device dev)
-{
-	int i;
-
-	i = 0;
-	do{
-		wrenpartream(dev, i);
-	}while(++i < nwren);
-}
-
-static int
-wrentag(char *p, int tag, long qpath)
-{
-	Tag *t;
-
-	t = (Tag*)(p+BUFSIZE);
-	return t->tag != tag || (qpath&~QPDIR) != t->path;
-}
-
-int
-wrencheck(Device dev)
-{
-	char buf[MAXBUFSIZE];
-
-	if(badmagic)
-		return 1;
-	if(RBUFSIZE > sizeof buf)
-		panic("bufsize too big");
-	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
-	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
-		return 1;
-	if(((Dentry *)buf)[0].mode & DALLOC)
-		return 0;
-	return 1;
-}
-
-long
-wrensize(Device dev)
-{
-	Wren *w;
-	int i, nb;
-
-	w = wren(dev);
-	nb = 0;
-	i = 0;
-	do{
-		nb += w[i].nblocks;
-	}while(++i < nwren);
-	return nb;
-}
-
-long
-wrensuper(Device dev)
-{
-	USED(dev);
-	return 1;
-}
-
-long
-wrenroot(Device dev)
-{
-	USED(dev);
-	return 2;
-}
-
-int
-wrenread(Device dev, long addr, void *b)
-{
-	Wren *w;
-	int fd, i;
-
-	w = wren(dev);
-	for(i=0; i<nwren; i++){
-		if(addr < w->nblocks)
-			break;
-		addr -= w->nblocks;
-		++w;
-	}
-	if(i > 0)
-		addr++;
-	fd = w->fd;
-	qlock(w);
-	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
-	qunlock(w);
-	return i;
-}
-
-int
-wrenwrite(Device dev, long addr, void *b)
-{
-	Wren *w;
-	int fd, i;
-
-	w = wren(dev);
-	for(i=0; i<nwren; i++){
-		if(addr < w->nblocks)
-			break;
-		addr -= w->nblocks;
-		++w;
-	}
-	if(i > 0)
-		addr++;
-	fd = w->fd;
-	qlock(w);
-	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
-	qunlock(w);
-	return i;
-}
--- a/sys/src/cmd/disk/kfs/devwren.c
+++ /dev/null
@@ -1,174 +1,0 @@
-#include "all.h"
-
-enum{
-	MAXWREN = 7,
-};
-
-#define WMAGIC	"kfs wren device\n"
-
-typedef struct Wren	Wren;
-
-struct Wren{
-	QLock;
-	Device	dev;
-	uvlong	size;
-	int	fd;
-};
-
-static Wren	*wrens;
-static int	maxwren;
-char		*wrenfile;
-int		nwren;
-int		badmagic;
-
-static Wren *
-wren(Device dev)
-{
-	int i;
-
-	for(i = 0; i < maxwren; i++)
-		if(devcmp(dev, wrens[i].dev) == 0)
-			return &wrens[i];
-	panic("can't find wren for %D", dev);
-	return 0;
-}
-
-void
-wreninit(Device dev)
-{
-	char buf[MAXBUFSIZE];
-	Wren *w;
-	Dir *d;
-	int fd, i;
-
-	if(wrens == 0)
-		wrens = ialloc(MAXWREN * sizeof *wrens);
-	w = &wrens[maxwren];
-	fd = open(wrenfile, ORDWR);
-	if(fd < 0)
-		panic("can't open %s", wrenfile);
-	if((d = dirfstat(fd)) == nil)
-		panic("can't stat %s\n", wrenfile);
-	seek(fd, 0, 0);
-	i = read(fd, buf, sizeof buf);
-	if(i < sizeof buf)
-		panic("can't read %s", wrenfile);
-	badmagic = 0;
-	RBUFSIZE = 1024;
-	if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
-		RBUFSIZE = atol(buf+256+strlen(WMAGIC));
-		if(RBUFSIZE % 512){
-			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
-			RBUFSIZE = 1024;
-		}
-	}else
-		badmagic = 1;
-	w->dev = dev;
-	w->size = d->length;
-	free(d);
-	w->fd = fd;
-	maxwren++;
-}
-
-void
-wrenream(Device dev)
-{
-	Wren *w;
-	char buf[MAXBUFSIZE];
-	int fd, i;
-
-	if(RBUFSIZE % 512)
-		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
-	if(RBUFSIZE > sizeof(buf))
-		panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
-
-	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
-	w = wren(dev);
-	fd = w->fd;
-	memset(buf, 0, sizeof buf);
-	sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
-	qlock(w);
-	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
-	qunlock(w);
-	if(i < 0)
-		panic("can't ream disk");
-}
-
-int
-wrentag(char *p, int tag, long qpath)
-{
-	Tag *t;
-
-	t = (Tag*)(p+BUFSIZE);
-	return t->tag != tag || (qpath&~QPDIR) != t->path;
-}
-
-int
-wrencheck(Device dev)
-{
-	char buf[MAXBUFSIZE];
-
-	if(badmagic)
-		return 1;
-	if(RBUFSIZE > sizeof(buf))
-		panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
-
-	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
-	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
-		return 1;
-	if(((Dentry *)buf)[0].mode & DALLOC)
-		return 0;
-	return 1;
-}
-
-long
-wrensize(Device dev)
-{
-	return wren(dev)->size / RBUFSIZE;
-}
-
-long
-wrensuper(Device dev)
-{
-	USED(dev);
-	return 1;
-}
-
-long
-wrenroot(Device dev)
-{
-	USED(dev);
-	return 2;
-}
-
-int
-wrenread(Device dev, long addr, void *b)
-{
-	Wren *w;
-	int fd, i;
-
-	w = wren(dev);
-	fd = w->fd;
-	qlock(w);
-	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
-	qunlock(w);
-	if(i)
-		print("wrenread failed: %r\n");
-	return i;
-}
-
-int
-wrenwrite(Device dev, long addr, void *b)
-{
-	Wren *w;
-	int fd, i;
-
-	w = wren(dev);
-	fd = w->fd;
-	qlock(w);
-	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
-	qunlock(w);
-	if(i)
-		print("wrenwrite failed: %r\n");
-	return i;
-}
--- a/sys/src/cmd/disk/kfs/errno.h
+++ /dev/null
@@ -1,35 +1,0 @@
-enum{
-	Enevermind,	/* never mind */
-	Enofd,		/* no free file descriptors */
-	Efidinuse,		/* fid already in use */
-	Ebadfd,		/* fid out of range or not open */
-	Ebadusefd,	/* inappropriate use of fid */
-	Ebadarg,	/* bad arg in system call */
-	Enonexist,	/* file does not exist */
-	Efilename,	/* file name syntax */
-	Ebadchar,	/* bad character in file name */
-	Ebadsharp,	/* unknown device in # filename */
-	Ebadexec,	/* a.out header invalid */
-	Eioload,	/* i/o error in demand load */
-	Eperm,		/* permission denied */
-	Enotdir,	/* not a directory */
-	Enochild,	/* no living children */
-	Enoseg,		/* no free segments */
-	Ebuf,		/* buffer wrong size */
-	Ebadmount,	/* inconsistent mount */
-	Enomount,	/* mount table full */
-	Enomntdev,	/* no free mount devices */
-	Eshutdown,	/* mounted device shut down */
-	Einuse,		/* device or object already in use */
-	Eio,		/* i/o error */
-	Eisdir,		/* file is a directory */
-	Ebaddirread,	/* directory read not quantized */
-	Esegaddr,	/* illegal segment addresses or size */
-	Enoenv,		/* no free environment resources */
-	Eprocdied,	/* process exited */
-	Enocreate,	/* mounted directory forbids creation */
-	Enotunion,	/* attempt to union with non-mounted directory */
-	Emount,		/* inconsistent mount */
-	Enosrv,		/* no free server slots */
-	Egreg,		/* it's all greg's fault */
-};
--- a/sys/src/cmd/disk/kfs/fns.h
+++ /dev/null
@@ -1,42 +1,0 @@
-#include "portfns.h"
-
-long	belong(char *);
-Chan*	chaninit(char*);
-void	check(Filsys *, long);
-int 	cmd_exec(char*);
-void	consserve(void);
-void	confinit(void);
-int	fsinit(int, int);
-void	*ialloc(ulong);
-int	nextelem(void);
-long	number(int, int);
-Device	scsidev(char*);
-int	skipbl(int);
-void	startproc(void (*)(void), char *);
-void	syncproc(void);
-void	syncall(void);
-
-int	fprint(int, char*, ...);
-void	wreninit(Device);
-int	wrencheck(Device);
-void	wrenream(Device);
-long	wrensize(Device);
-long	wrensuper(Device);
-long	wrenroot(Device);
-int	wrenread(Device, long, void *);
-int	wrenwrite(Device, long, void *);
-
-/*
- * macros for compat with bootes
- */
-#define	localfs			1
-
-#define devgrow(d, s)	0
-#define nofree(d, a)	0
-#define isro(d)		0
-
-#define	superaddr(d)		((*devcall[d.type].super)(d))
-#define	getraddr(d)		((*devcall[d.type].root)(d))
-#define devsize(d)		((*devcall[d.type].size)(d))
-#define	devwrite(d, a, v)	((*devcall[d.type].write)(d, a, v))
-#define	devread(d, a, v)	((*devcall[d.type].read)(d, a, v))
--- a/sys/src/cmd/disk/kfs/ialloc.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#include "all.h"
-
-void *ialloc(ulong n){
-	void *p;
-
-	if(p = malloc(n))
-		memset(p, 0, n);
-	return p;
-}
--- a/sys/src/cmd/disk/kfs/iobuf.c
+++ /dev/null
@@ -1,235 +1,0 @@
-#include	"all.h"
-
-#define	DEBUG	0
-
-long	niob;
-long	nhiob;
-Hiob	*hiob;
-
-Iobuf*
-getbuf(Device dev, long addr, int flag)
-{
-	Iobuf *p, *s;
-	Hiob *hp;
-	long h;
-
-	if(DEBUG)
-		print("getbuf %D(%ld) f=%x\n", dev, addr, flag);
-	h = addr +
-		dev.type*1009L +
-		dev.ctrl*10007L +
-		dev.unit*100003L +
-		dev.part*1000003L;
-	if(h < 0)
-		h = ~h;
-	h %= nhiob;
-	hp = &hiob[h];
-
-loop:
-	lock(hp);
-
-/*
- * look for it in the active list
- */
-	s = hp->link;
-	for(p=s;;) {
-		if(p->addr == addr && !devcmp(p->dev, dev)) {
-			if(p != s) {
-				p->back->fore = p->fore;
-				p->fore->back = p->back;
-				p->fore = s;
-				p->back = s->back;
-				s->back = p;
-				p->back->fore = p;
-				hp->link = p;
-			}
-			unlock(hp);
-			qlock(p);
-			if(p->addr != addr || devcmp(p->dev, dev)) {
-				qunlock(p);
-				goto loop;
-			}
-			p->flags |= flag;
-			cons.bhit.count++;
-			p->iobuf = p->xiobuf;
-			return p;
-		}
-		p = p->fore;
-		if(p == s)
-			break;
-	}
-	if(flag & Bprobe) {
-		unlock(hp);
-		return 0;
-	}
-
-/*
- * not found
- * take oldest unlocked entry in this queue
- */
-xloop:
-	p = s->back;
-	if(!canqlock(p)) {
-		if(p == hp->link) {
-			unlock(hp);
-			print("iobuf all locked\n");
-			goto loop;
-		}
-		s = p;
-		goto xloop;
-	}
-	/*
-	 * its dangerous to flush the pseudo
-	 * devices since they recursively call
-	 * getbuf/putbuf. deadlock!
-	 */
-	if(p->flags & Bres) {
-		qunlock(p);
-		if(p == hp->link) {
-			unlock(hp);
-			print("iobuf all resed\n");
-			goto loop;
-		}
-		s = p;
-		goto xloop;
-	}
-	if(p->flags & Bmod) {
-		unlock(hp);
-		if(!devwrite(p->dev, p->addr, p->xiobuf))
-			p->flags &= ~(Bimm|Bmod);
-		qunlock(p);
-		goto loop;
-	}
-	hp->link = p;
-	p->addr = addr;
-	p->dev = dev;
-	p->flags = flag;
-	unlock(hp);
-	p->iobuf = p->xiobuf;
-	if(flag & Bread) {
-		if(devread(p->dev, p->addr, p->iobuf)) {
-			p->flags = 0;
-			p->dev = devnone;
-			p->addr = -1;
-			p->iobuf = (char*)-1;
-			qunlock(p);
-			return 0;
-		}
-		cons.bread.count++;
-		return p;
-	}
-	cons.binit.count++;
-	return p;
-}
-
-/*
- * syncblock tries to put out a block per hashline
- * returns 0 all done,
- * returns 1 if it missed something
- */
-int
-syncblock(void)
-{
-	Iobuf *p, *s, *q;
-	Hiob *hp;
-	long h;
-	int flag;
-
-	flag = 0;
-	for(h=0; h<nhiob; h++) {
-		q = 0;
-		hp = &hiob[h];
-		lock(hp);
-		s = hp->link;
-		for(p=s;;) {
-			if(p->flags & Bmod) {
-				if(q)
-					flag = 1;	/* more than 1 mod/line */
-				q = p;
-			}
-			p = p->fore;
-			if(p == s)
-				break;
-		}
-		unlock(hp);
-		if(q) {
-			if(!canqlock(q)) {
-				flag = 1;		/* missed -- was locked */
-				continue;
-			}
-			if(!(q->flags & Bmod)) {
-				qunlock(q);
-				continue;
-			}
-			if(!devwrite(q->dev, q->addr, q->xiobuf))
-				q->flags &= ~(Bmod|Bimm);
-			qunlock(q);
-		}
-	}
-	return flag;
-}
-
-void
-sync(char *reason)
-{
-	long i;
-
-	print("sync: %s\n", reason);
-	for(i=10*nhiob; i>0; i--)
-		if(!syncblock())
-			return;
-	print("sync shorted\n");
-}
-
-void
-putbuf(Iobuf *p)
-{
-	if(canqlock(p))
-		print("buffer not locked %D(%ld)\n", p->dev, p->addr);
-	if(p->flags & Bimm) {
-		if(!(p->flags & Bmod))
-			print("imm and no mod %D(%ld)\n", p->dev, p->addr);
-		if(!devwrite(p->dev, p->addr, p->iobuf))
-			p->flags &= ~(Bmod|Bimm);
-	}
-	p->iobuf = (char*)-1;
-	qunlock(p);
-}
-
-int
-checktag(Iobuf *p, int tag, long qpath)
-{
-	Tag *t;
-
-	t = (Tag*)(p->iobuf+BUFSIZE);
-	if(t->tag != tag) {
-		if(1 || CHAT(0))
-			print("	tag = %G; expected %G; addr = %lud\n",
-				t->tag, tag, p->addr);
-		return 2;
-	}
-	if(qpath != QPNONE) {
-		qpath &= ~QPDIR;
-		if(qpath != t->path) {
-			if(qpath == (t->path&~QPDIR))	/* old bug */
-				return 0;
-			if(1 || CHAT(0))
-				print("	tag/path = %lux; expected %G/%lux\n",
-					t->path, tag, qpath);
-			return 1;
-		}
-	}
-	return 0;
-}
-
-void
-settag(Iobuf *p, int tag, long qpath)
-{
-	Tag *t;
-
-	t = (Tag*)(p->iobuf+BUFSIZE);
-	t->tag = tag;
-	if(qpath != QPNONE)
-		t->path = qpath & ~QPDIR;
-	p->flags |= Bmod;
-}
--- a/sys/src/cmd/disk/kfs/main.c
+++ /dev/null
@@ -1,558 +1,0 @@
-#include	"all.h"
-
-int	sfd;
-int	cmdmode = 0660;
-int	rfd;
-int	chat;
-extern	char *wrenfile;
-extern	int nwren;
-char	*myname;
-int	cmdfd;
-int	writeallow;	/* never on; for compatibility with fs */
-int	wstatallow;
-int	writegroup;
-int	allownone;
-int	noatime;
-int	srvfd(char*, int, int);
-void	usage(void);
-void	confinit(void);
-Chan	*chaninit(char*);
-void	consinit(void);
-void	forkserve(void);
-
-void
-main(int argc, char *argv[])
-{
-	Filsys *fs;
-	int ream, fsok;
-	int newbufsize, nocheck;
-	char buf[NAMELEN];
-	int pid, ctl;
-
-	progname = "kfs";
-	procname = "init";
-
-	/*
-	 * insulate from invoker's environment and keep it from swapping
-	 */
-	rfork(RFNAMEG|RFNOTEG|RFREND);
-
-	confinit();
-	sfd = -1;
-	ream = 0;
-	newbufsize = 0;
-	nocheck = 0;
-	wrenfile = "/dev/sdC0/fs";
-
-	pid = getpid();
-	snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
-	ctl = open(buf, OWRITE);
-	fprint(ctl, "noswap\n");
-	close(ctl);
-
-	buf[0] = '\0';
-
-	ARGBEGIN{
-	case 'b':
-		newbufsize = atol(ARGF());
-		break;
-	case 'c':
-		nocheck = 1;
-		break;
-	case 'f':
-		wrenfile = ARGF();
-		break;
-	case 'm':
-		nwren = atol(ARGF());
-		break;
-	case 'n':
-		strncpy(buf, ARGF(), NAMELEN-1);
-		buf[NAMELEN-1] = '\0';
-		break;
-	case 'p':
-		cmdmode = atol(ARGF());
-		break;
-	case 'r':
-		ream = 1;
-		break;
-	case 's':
-		sfd = 0;
-		rfd = dup(1, -1);
-		close(1);
-		if(open("/dev/cons", OWRITE) < 0)
-			open("#c/cons", OWRITE);
-		break;
-	case 'B':
-		conf.niobuf = strtoul(ARGF(), 0, 0);
-		break;
-	case 'C':
-		chat = 1;
-		break;
-	default:
-		usage();
-	}ARGEND
-
-	if(argc != 0)
-		usage();
-
-	cmdfd = 2;
-
-	if (access(wrenfile, AREAD|AWRITE) == -1)
-		sysfatal("%s cannot access device", wrenfile);
-
-	formatinit();
-	sublockinit();
-
-	if(buf[0])
-		sprint(service, "kfs.%s", buf);
-	else
-		strcpy(service, "kfs");
-	chan = chaninit(service);
-	consinit();
-	tlocks = ialloc(NTLOCK * sizeof *tlocks);
-	uid = ialloc(conf.nuid * sizeof(*uid));
-	uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
-	gidspace = ialloc(conf.gidspace * sizeof(*gidspace));
-
-	/*
-	 * init global locks
-	 */
-	wlock(&mainlock); wunlock(&mainlock);
-
-	/*
-	 * init the file system, ream it if needed, and get the block sizes
-	 */
-	ream = fsinit(ream, newbufsize);
-	iobufinit();
-	for(fs=filesys; fs->name; fs++)
-		if(fs->flags & FREAM){		/* set by fsinit if reamed */
-			ream++;
-			rootream(fs->dev, getraddr(fs->dev));
-			superream(fs->dev, superaddr(fs->dev));
-		}
-
-	boottime = time(nil);
-
-	consserve();
-	fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0);
-	if(!nocheck && !ream && !fsok)
-		cmd_exec("check fq");
-
-	startproc(forkserve, "srv");
-	startproc(syncproc, "sync");
-
-	exits(0);
-}
-
-void
-forkserve(void)
-{
-	serve(chan);
-}
-
-static
-struct
-{
-	int	nfilter;
-	Filter*	filters[100];
-}f;
-
-int alarmed;
-
-void
-catchalarm(void *regs, char *msg)
-{
-	USED(regs, msg);
-	if(strcmp(msg, "alarm") == 0){
-		alarmed = 1;
-		noted(NCONT);
-	} else
-		noted(NDFLT);
-}
-
-/*
- * process to synch blocks
- * it puts out a block/line every second
- * it waits 10 seconds if catches up.
- * in both cases, it takes about 10 seconds
- * to get up-to-date.
- *
- * it also updates the filter stats
- * and executes commands
- */
-void
-syncproc(void)
-{
-	char buf[4*1024];
-	Filter *ft;
-	ulong c0, c1;
-	long t, n, d;
-	int i, p[2];
-
-	/*
-	 * make a pipe for commands
-	 */
-	if(pipe(p) < 0)
-		panic("command pipe");
-	sprint(buf, "#s/%s.cmd", service);
-	srvfd(buf, cmdmode, p[0]);
-	close(p[0]);
-	cmdfd = p[1];
-	notify(catchalarm);
-
-	t = time(nil);
-	for(;;){
-		i = syncblock();
-		alarmed = 0;
-		alarm(i ? 1000: 10000);
-		n = read(cmdfd, buf, sizeof buf - 1);
-		if(n <= 0 && !alarmed)
-			sleep(i ? 1000: 10000);
-		alarm(0);
-		if(n > 0){
-			buf[n] = '\0';
-			if(cmd_exec(buf))
-				fprint(cmdfd, "done");
-			else
-				fprint(cmdfd, "unknown command");
-		}
-		n = time(nil);
-		d = n - t;
-		if(d < 0 || d > 5*60)
-			d = 0;
-		while(d >= 1) {
-			d -= 1;
-			for(i=0; i<f.nfilter; i++) {
-				ft = f.filters[i];
-				c0 = ft->count;
-				c1 = c0 - ft->oldcount;
-				ft->oldcount = c0;
-				ft->filter[0] = famd(ft->filter[0], c1, 59, 60);
-				ft->filter[1] = famd(ft->filter[1], c1, 599, 600);
-				ft->filter[2] = famd(ft->filter[2], c1, 5999, 6000);
-			}
-		}
-		t = n;
-	}
-}
-
-void
-dofilter(Filter *ft)
-{
-	int i;
-
-	i = f.nfilter;
-	if(i >= sizeof f.filters / sizeof f.filters[0]) {
-		print("dofilter: too many filters\n");
-		return;
-	}
-	f.filters[i] = ft;
-	f.nfilter = i+1;
-}
-
-void
-startproc(void (*f)(void), char *name)
-{
-	switch(rfork(RFMEM|RFFDG|RFPROC)){
-	case -1:
-		panic("can't fork");
-	case 0:
-		break;
-	default:
-		return;
-	}
-	procname = name;
-	f();
-	_exits(nil);
-}
-
-void
-confinit(void)
-{
-	conf.niobuf = 0;
-	conf.nuid = 600;
-	conf.nserve = 2;
-	conf.uidspace = conf.nuid*6;
-	conf.gidspace = conf.nuid*3;
-	cons.flags = 0;
-}
-
-static void
-dochaninit(Chan *cp, int fd)
-{
-	cp->chan = fd;
-	fileinit(cp);
-	wlock(&cp->reflock);
-	wunlock(&cp->reflock);
-	lock(&cp->flock);
-	unlock(&cp->flock);
-}
-
-Chan*
-chaninit(char *server)
-{
-	Chan *cp;
-	char buf[3*NAMELEN];
-	int p[2];
-
-	sprint(buf, "#s/%s", server);
-	if(sfd < 0){
-		if(pipe(p) < 0)
-			panic("can't make a pipe");
-		sfd = p[0];
-		rfd = p[1];
-	}
-	srvfd(buf, 0666, sfd);
-	close(sfd);
-	cp = ialloc(sizeof *cp);
-	cons.srvchan = cp;
-	dochaninit(cp, rfd);
-	return cp;
-}
-
-int
-netserve(char *netaddr)
-{
-	int afd, lfd, fd;
-	char adir[2*NAMELEN], ldir[2*NAMELEN];
-	Chan *netchan;
-
-	if(access("/net/tcp/clone", 0) < 0)
-		bind("#I", "/net", MAFTER);
-	if(access("/net.alt/tcp/clone", 0) < 0)
-		bind("#I1", "/net.alt", MAFTER);
-
-	afd = announce(netaddr, adir);
-	if (afd < 0)
-		return -1;
-	switch (rfork(RFMEM|RFFDG|RFPROC)) {
-	case -1:
-		return -1;
-	case 0:
-		break;
-	default:
-		return 0;
-	}
-	for (;;) {
-		lfd = listen(adir, ldir);
-		if (lfd < 0)
-			continue;
-		fd = accept(lfd, ldir);
-		if (fd < 0) {
-			close(lfd);
-			continue;
-		}
-		netchan = mallocz(sizeof(Chan), 1);
-		if(netchan == nil)
-			panic("out of memory");
-		dochaninit(netchan, fd);
-		switch (rfork(RFMEM|RFFDG|RFPROC)) {
-		case -1:
-			panic("can't fork");
-		case 0:
-			close(afd);
-			close(lfd);
-			serve(netchan);
-			free(netchan);
-			exits(0);
-		default:
-			close(fd);
-			close(lfd);
-			continue;
-		}
-	}
-}
-
-int
-srvfd(char *s, int mode, int sfd)
-{
-	int fd;
-	char buf[32];
-
-	fd = create(s, ORCLOSE|OWRITE, mode);
-	if(fd < 0){
-		remove(s);
-		fd = create(s, ORCLOSE|OWRITE, mode);
-		if(fd < 0)
-			panic(s);
-	}
-	sprint(buf, "%d", sfd);
-	if(write(fd, buf, strlen(buf)) != strlen(buf))
-		panic("srv write");
-	return sfd;
-}
-
-void
-consinit(void)
-{
-	int i;
-
-	cons.chan = ialloc(sizeof(Chan));
-	wlock(&cons.chan->reflock);
-	wunlock(&cons.chan->reflock);
-	lock(&cons.chan->flock);
-	unlock(&cons.chan->flock);
-	dofilter(&cons.work);
-	dofilter(&cons.rate);
-	dofilter(&cons.bhit);
-	dofilter(&cons.bread);
-	dofilter(&cons.binit);
-	for(i = 0; i < MAXTAG; i++)
-		dofilter(&cons.tags[i]);
-}
-
-/*
- * always called with mainlock locked
- */
-void
-syncall(void)
-{
-	for(;;)
-		if(!syncblock())
-			return;
-}
-
-int
-askream(Filsys *fs)
-{
-	char c;
-
-	print("File system %s inconsistent\n", fs->name);
-	print("Would you like to ream it (y/n)? ");
-	read(0, &c, 1);
-	return c == 'y';
-}
-
-ulong
-memsize(void)
-{
-	char *p, buf[128];
-	int fd, n, by2pg, secs;
-
-	by2pg = 4*1024;
-	p = getenv("cputype");
-	if(p && strcmp(p, "68020") == 0)
-		by2pg = 8*1024;
-
-	secs = 4*1024*1024;
-	
-	fd = open("/dev/swap", OREAD);
-	if(fd < 0)
-		return secs;
-	n = read(fd, buf, sizeof(buf)-1);
-	close(fd);
-	if(n <= 0)
-		return secs;
-	buf[n] = 0;
-	p = strchr(buf, '/');
-	if(p)
-		secs = strtoul(p+1, 0, 0)*by2pg;
-	return secs;
-}
-
-/*
- * init the devices
- * wipe some of the file systems, or all if ream is set
- * this code really assumes that only one file system exists
- */
-int
-fsinit(int ream, int newbufsize)
-{
-	Filsys *fs;
-
-	RBUFSIZE = 4 * 1024;
-	for(fs=filesys; fs->name; fs++)
-		(*devcall[fs->dev.type].init)(fs->dev);
-	if(newbufsize == 0)
-		newbufsize = RBUFSIZE;
-
-	if(conf.niobuf == 0) {
-		conf.niobuf = memsize()/10;
-		if(conf.niobuf > 2*1024*1024)
-			conf.niobuf = 2*1024*1024;
-		conf.niobuf /= newbufsize;
-		if(conf.niobuf < 30)
-			conf.niobuf = 30;
-	}
-
-	BUFSIZE = RBUFSIZE - sizeof(Tag);
-
-	for(fs=filesys; fs->name; fs++)
-		if(ream || (*devcall[fs->dev.type].check)(fs->dev) && askream(fs)){
-			RBUFSIZE = newbufsize;
-			BUFSIZE = RBUFSIZE - sizeof(Tag);
-			(*devcall[fs->dev.type].ream)(fs->dev);
-			fs->flags |= FREAM;
-			ream = 1;
-		}
-
-	/*
-	 * set up the block size dependant variables
-	 */
-	BUFSIZE = RBUFSIZE - sizeof(Tag);
-	DIRPERBUF = BUFSIZE / sizeof(Dentry);
-	INDPERBUF = BUFSIZE / sizeof(long);
-	INDPERBUF2 = INDPERBUF * INDPERBUF;
-	FEPERBUF = (BUFSIZE - sizeof(Super1) - sizeof(long)) / sizeof(long);
-	return ream;
-}
-
-/*
- * allocate rest of mem
- * for io buffers.
- */
-#define	HWIDTH	5	/* buffers per hash */
-void
-iobufinit(void)
-{
-	long i;
-	Iobuf *p, *q;
-	Hiob *hp;
-
-	i = conf.niobuf*RBUFSIZE;
-	niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH);
-	nhiob = niob / HWIDTH;
-	while(!prime(nhiob))
-		nhiob++;
-	if(chat)
-		print("	%ld buffers; %ld hashes\n", niob, nhiob);
-	hiob = ialloc(nhiob * sizeof(Hiob));
-	hp = hiob;
-	for(i=0; i<nhiob; i++) {
-		lock(hp);
-		unlock(hp);
-		hp++;
-	}
-	p = ialloc(niob * sizeof(Iobuf));
-	hp = hiob;
-	for(i=0; i<niob; i++) {
-		qlock(p);
-		qunlock(p);
-		if(hp == hiob)
-			hp = hiob + nhiob;
-		hp--;
-		q = hp->link;
-		if(q) {
-			p->fore = q;
-			p->back = q->back;
-			q->back = p;
-			p->back->fore = p;
-		} else {
-			hp->link = p;
-			p->fore = p;
-			p->back = p;
-		}
-		p->dev = devnone;
-		p->addr = -1;
-		p->xiobuf = ialloc(RBUFSIZE);
-		p->iobuf = (char*)-1;
-		p++;
-	}
-}
-
-void
-usage(void)
-{
-	fprint(2, "usage: kfs [-cCr] [-b bufsize] [-s infd outfd] [-f fsfile]\n");
-	exits(0);
-}
--- a/sys/src/cmd/disk/kfs/misc.c
+++ /dev/null
@@ -1,86 +1,0 @@
-#include "all.h"
-
-extern int cmdfd;
-
-Float
-famd(Float a, int b, int c, int d)
-{
-	ulong x, m;
-
-	x = (a + b) * c;
-	m = x % d;
-	x /= d;
-	if(m >= d / 2)
-		x++;
-	return x;
-}
-
-ulong
-fdf(Float a, int d)
-{
-	ulong x, m;
-
-	m = a % d;
-	x = a / d;
-	if(m >= d / 2)
-		x++;
-	return x;
-}
-
-long
-belong(char *s)
-{
-	uchar *x;
-
-	x = (uchar *)s;
-	return (x[0] << 24) + (x[1] << 16) + (x[2] << 8) + x[3]; 
-}
-
-void
-panic(char *fmt, ...)
-{
-	char buf[8192], *s;
-	va_list arg;
-
-
-	s = buf;
-	s += sprint(s, "%s %s %d: ", progname, procname, getpid());
-	va_start(arg, fmt);
-	s = vseprint(s, buf + sizeof(buf) / sizeof(*buf), fmt, arg);
-	va_end(arg);
-	*s++ = '\n';
-	write(2, buf, s - buf);
-abort();
-	exits(buf);
-}
-
-#define	SIZE	4096
-
-void
-cprint(char *fmt, ...)
-{
-	char buf[SIZE], *out;
-	va_list arg;
-
-	va_start(arg, fmt);
-	out = vseprint(buf, buf+SIZE, fmt, arg);
-	va_end(arg);
-	write(cmdfd, buf, (long)(out-buf));
-}
-
-/*
- * print goes to fd 2 [sic] because fd 1 might be
- * otherwise preoccupied when the -s flag is given to kfs.
- */
-int
-print(char *fmt, ...)
-{
-	va_list arg;
-	int n;
-
-	va_start(arg, fmt);
-	n = vfprint(2, fmt, arg);
-	va_end(arg);
-	return n;
-}
-
--- a/sys/src/cmd/disk/kfs/mkfile
+++ /dev/null
@@ -1,54 +1,0 @@
-</$objtype/mkfile
-
-TARG=kfs
-
-OFILES=\
-	9p1.$O\
-	9p1lib.$O\
-	9p2.$O\
-	9p12.$O\
-	auth.$O\
-	chk.$O\
-	con.$O\
-	console.$O\
-	dat.$O\
-	dentry.$O\
-	ialloc.$O\
-	iobuf.$O\
-	main.$O\
-	misc.$O\
-	porttime.$O\
-	sub.$O\
-	uid.$O\
-	ofcallfmt.$O\
-
-HFILES=\
-	all.h\
-	dat.h\
-	errno.h\
-	fns.h\
-	portfns.h\
-	portdat.h\
-
-BIN=/$objtype/bin/disk
-
-UPDATE=mkfile\
-	$HFILES\
-	${OFILES:%.$O=%.c}\
-
-</sys/src/cmd/mkone
-
-$O.out:	devwren.$O
-
-$O.gfs:	$OFILES devmulti.$O
-	$LD $LDFLAGS -o $target $prereq
-
-
-test:VQ:
-	echo rm -fr /srv/il!$sysname!11111
-	echo 'kill 8.out|rc'
-	echo rm /srv/il!$sysname!11111
-	echo 8.out -Crf /tmp/disk
-	echo disk/kfscmd ''''listen il!*!11111''''
-	echo srv il!$sysname!11111
-	echo mount /srv/il!$sysname!11111 /n/emelie
--- a/sys/src/cmd/disk/kfs/ofcallfmt.c
+++ /dev/null
@@ -1,181 +1,0 @@
-#include "all.h"
-#include "9p1.h"
-
-static void dumpsome(char*, char*, long);
-static void fdirconv(char*, Dentry*);
-
-int
-ofcallfmt(Fmt *f1)
-{
-	char buf[512];
-	Oldfcall *f;
-	int fid, type, tag, n;
-	Dentry d;
-
-	f = va_arg(f1->args, Oldfcall*);
-	type = f->type;
-	fid = f->fid;
-	tag = f->tag;
-	switch(type){
-	case Tnop9p1:	/* 50 */
-		sprint(buf, "Tnop9p1 tag %ud", tag);
-		break;
-	case Rnop9p1:
-		sprint(buf, "Rnop9p1 tag %ud", tag);
-		break;
-	case Tsession9p1:	/* 52 */
-		sprint(buf, "Tsession9p1 tag %ud", tag);
-		break;
-	case Rsession9p1:
-		sprint(buf, "Rsession9p1 tag %ud", tag);
-		break;
-	case Rerror9p1:	/* 55 */
-		sprint(buf, "Rerror9p1 tag %ud error %.64s", tag, f->ename);
-		break;
-	case Tflush9p1:	/* 56 */
-		sprint(buf, "Tflush9p1 tag %ud oldtag %d", tag, f->oldtag);
-		break;
-	case Rflush9p1:
-		sprint(buf, "Rflush9p1 tag %ud", tag);
-		break;
-	case Tattach9p1:	/* 58 */
-		sprint(buf, "Tattach9p1 tag %ud fid %d uname %.28s aname %.28s auth %.28s",
-			tag, f->fid, f->uname, f->aname, f->auth);
-		break;
-	case Rattach9p1:
-		sprint(buf, "Rattach9p1 tag %ud fid %d qid 0x%lux|0x%lux",
-			tag, fid, f->qid.path, f->qid.version);
-		break;
-	case Tclone9p1:	/* 60 */
-		sprint(buf, "Tclone9p1 tag %ud fid %d newfid %d", tag, fid, f->newfid);
-		break;
-	case Rclone9p1:
-		sprint(buf, "Rclone9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Twalk9p1:	/* 62 */
-		sprint(buf, "Twalk9p1 tag %ud fid %d name %.28s", tag, fid, f->name);
-		break;
-	case Rwalk9p1:
-		sprint(buf, "Rwalk9p1 tag %ud fid %d qid 0x%lux|0x%lux",
-			tag, fid, f->qid.path, f->qid.version);
-		break;
-	case Topen9p1:	/* 64 */
-		sprint(buf, "Topen9p1 tag %ud fid %d mode %d", tag, fid, f->mode);
-		break;
-	case Ropen9p1:
-		sprint(buf, "Ropen9p1 tag %ud fid %d qid 0x%lux|0x%lux",
-			tag, fid, f->qid.path, f->qid.version);
-		break;
-	case Tcreate9p1:	/* 66 */
-		sprint(buf, "Tcreate9p1 tag %ud fid %d name %.28s perm 0x%lux mode %d",
-			tag, fid, f->name, f->perm, f->mode);
-		break;
-	case Rcreate9p1:
-		sprint(buf, "Rcreate9p1 tag %ud fid %d qid 0x%lux|0x%lux",
-			tag, fid, f->qid.path, f->qid.version);
-		break;
-	case Tread9p1:	/* 68 */
-		sprint(buf, "Tread9p1 tag %ud fid %d offset %ld count %ld",
-			tag, fid, f->offset, f->count);
-		break;
-	case Rread9p1:
-		n = sprint(buf, "Rread9p1 tag %ud fid %d count %ld ", tag, fid, f->count);
-		dumpsome(buf+n, f->data, f->count);
-		break;
-	case Twrite9p1:	/* 70 */
-		n = sprint(buf, "Twrite9p1 tag %ud fid %d offset %ld count %ld ",
-			tag, fid, f->offset, f->count);
-		dumpsome(buf+n, f->data, f->count);
-		break;
-	case Rwrite9p1:
-		sprint(buf, "Rwrite9p1 tag %ud fid %d count %ld", tag, fid, f->count);
-		break;
-	case Tclunk9p1:	/* 72 */
-		sprint(buf, "Tclunk9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Rclunk9p1:
-		sprint(buf, "Rclunk9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Tremove9p1:	/* 74 */
-		sprint(buf, "Tremove9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Rremove9p1:
-		sprint(buf, "Rremove9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Tstat9p1:	/* 76 */
-		sprint(buf, "Tstat9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Rstat9p1:
-		n = sprint(buf, "Rstat9p1 tag %ud fid %d", tag, fid);
-		convM2D9p1(f->stat, &d);
-		sprint(buf+n, " stat ");
-		fdirconv(buf+n+6, &d);
-		break;
-	case Twstat9p1:	/* 78 */
-		convM2D9p1(f->stat, &d);
-		n = sprint(buf, "Twstat9p1 tag %ud fid %d stat ", tag, fid);
-		fdirconv(buf+n, &d);
-		break;
-	case Rwstat9p1:
-		sprint(buf, "Rwstat9p1 tag %ud fid %d", tag, fid);
-		break;
-	case Tclwalk9p1:	/* 81 */
-		sprint(buf, "Tclwalk9p1 tag %ud fid %d newfid %d name %.28s",
-			tag, fid, f->newfid, f->name);
-		break;
-	case Rclwalk9p1:
-		sprint(buf, "Rclwalk9p1 tag %ud fid %d qid 0x%lux|0x%lux",
-			tag, fid, f->qid.path, f->qid.version);
-		break;
-	default:
-		sprint(buf,  "unknown type %d", type);
-	}
-	return fmtstrcpy(f1, buf);
-}
-
-static void
-fdirconv(char *buf, Dentry *d)
-{
-	sprint(buf, "'%s' uid=%d gid=%d "
-		"q %lux|%lux m %uo "
-		"at %ld mt %ld l %ld ",
-			d->name, d->uid, d->gid,
-			d->qid.path, d->qid.version, d->mode,
-			d->atime, d->mtime, d->size);
-}
-
-/*
- * dump out count (or DUMPL, if count is bigger) bytes from
- * buf to ans, as a string if they are all printable,
- * else as a series of hex bytes
- */
-#define DUMPL 24
-
-static void
-dumpsome(char *ans, char *buf, long count)
-{
-	int i, printable;
-	char *p;
-
-	printable = 1;
-	if(count > DUMPL)
-		count = DUMPL;
-	for(i=0; i<count && printable; i++)
-		if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
-			printable = 0;
-	p = ans;
-	*p++ = '\'';
-	if(printable){
-		memmove(p, buf, count);
-		p += count;
-	}else{
-		for(i=0; i<count; i++){
-			if(i>0 && i%4==0)
-				*p++ = ' ';
-			sprint(p, "%2.2ux", buf[i]);
-			p += 2;
-		}
-	}
-	*p++ = '\'';
-	*p = 0;
-}
--- a/sys/src/cmd/disk/kfs/portdat.h
+++ /dev/null
@@ -1,368 +1,0 @@
-/*
- * fundamental constants
- */
-#define	NAMELEN		28		/* size of names */
-#define	NDBLOCK		6		/* number of direct blocks in Dentry */
-#define	MAXDAT		8192		/* max allowable data message */
-#define NTLOCK		200		/* number of active file Tlocks */
-
-typedef	struct	Fbuf	Fbuf;
-typedef	struct	Super1	Super1;
-typedef	struct	Superb	Superb;
-// typedef struct	Qid	Qid;
-typedef	struct	Dentry	Dentry;
-typedef	struct	Tag	Tag;
-
-typedef struct	Device	Device;
-typedef struct	Qid9p1	Qid9p1;
-typedef	struct	File	File;
-typedef	struct	Filsys	Filsys;
-typedef	struct	Filta	Filta;
-typedef	struct	Filter	Filter;
-typedef		ulong	Float;
-typedef	struct	Hiob	Hiob;
-typedef	struct	Iobuf	Iobuf;
-typedef	struct	P9call	P9call;
-typedef	struct	Tlock	Tlock;
-// typedef	struct	Tm	Tm;
-typedef	struct	Uid	Uid;
-typedef	struct	Wpath	Wpath;
-typedef struct	AuthRpc	AuthRpc;
-
-/*
- * DONT TOUCH -- data structures stored on disk
- */
-/* DONT TOUCH, this is the disk structure */
-struct	Qid9p1
-{
-	long	path;
-	long	version;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct	Dentry
-{
-	char	name[NAMELEN];
-	short	uid;
-	short	gid;
-	ushort	mode;
-		#define	DALLOC	0x8000
-		#define	DDIR	0x4000
-		#define	DAPND	0x2000
-		#define	DLOCK	0x1000
-		#define	DREAD	0x4
-		#define	DWRITE	0x2
-		#define	DEXEC	0x1
-	Qid9p1	qid;
-	long	size;
-	long	dblock[NDBLOCK];
-	long	iblock;
-	long	diblock;
-	long	atime;
-	long	mtime;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct	Tag
-{
-	short	pad;
-	short	tag;
-	long	path;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct	Super1
-{
-	long	fstart;
-	long	fsize;
-	long	tfree;
-	long	qidgen;		/* generator for unique ids */
-
-	long	fsok;		/* file system ok */
-
-	/*
-	 * garbage for WWC device
-	 */
-	long	roraddr;	/* dump root addr */
-	long	last;		/* last super block addr */
-	long	next;		/* next super block addr */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct	Fbuf
-{
-	long	nfree;
-	long	free[1];		/* changes based on BUFSIZE */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct	Superb
-{
-	Super1;
-	Fbuf	fbuf;
-};
-
-struct	Device
-{
-	char	type;
-	char	ctrl;
-	char	unit;
-	char	part;
-};
-
-/*
- * for load stats
- */
-struct	Filter
-{
-	ulong	count;			/* count and old count kept separate */
-	ulong	oldcount;		/* so interrput can read them */
-	Float	filter[3];		/* filters for 1m 10m 100m */ 
-};
-
-struct	Filta
-{
-	Filter*	f;
-	int	scale;
-};
-
-/*
- * array of qids that are locked
- */
-struct	Tlock
-{
-	Device	dev;
-	long	time;
-	long	qpath;
-	File*	file;
-};
-
-struct	File
-{
-	QLock;
-	Qid	qid;
-	Wpath*	wpath;
-	Chan*	cp;		/* null means a free slot */
-	Tlock*	tlock;		/* if file is locked */
-	File*	next;		/* in cp->flist */
-	File*	list;		/* in list of free files */
-	Filsys*	fs;
-	long	addr;
-	long	slot;
-	long	lastra;		/* read ahead address */
-	ulong	fid;
-	short	uid;
-	char	open;
-		#define	FREAD	1
-		#define	FWRITE	2
-		#define	FREMOV	4
-		#define	FWSTAT	8
-	long	doffset;	/* directory reading */
-	ulong	dvers;
-	long	dslot;
-
-	/* for network authentication */
-	AuthRpc	*rpc;
-	short	cuid;
-};
-
-struct	Filsys
-{
-	char*	name;		/* name of filesys */
-	Device	dev;		/* device that filesys is on */
-	int	flags;
-		#define	FREAM		(1<<1)	/* mkfs */
-		#define	FRECOVER	(1<<2)	/* install last dump */
-};
-
-struct	Hiob
-{
-	Iobuf*	link;
-	Lock;
-};
-
-struct	Iobuf
-{
-	QLock;
-	Device	dev;
-	Iobuf	*next;		/* for hash */
-	Iobuf	*fore;		/* for lru */
-	Iobuf	*back;		/* for lru */
-	char	*iobuf;		/* only active while locked */
-	char	*xiobuf;	/* "real" buffer pointer */
-	long	addr;
-	int	flags;
-};
-
-struct	P9call
-{
-	uchar	calln;
-	uchar	rxflag;
-	short	msize;
-	void	(*func)(Chan*, int);
-};
-
-// struct	Tm
-// {
-// 	/* see ctime(3) */
-// 	int	sec;
-// 	int	min;
-// 	int	hour;
-// 	int	mday;
-// 	int	mon;
-// 	int	year;
-// 	int	wday;
-// 	int	yday;
-// 	int	isdst;
-// };
-
-struct	Uid
-{
-	short	uid;		/* user id */
-	short	lead;		/* leader of group */
-	short	offset;		/* byte offset in uidspace */
-};
-
-struct	Wpath
-{
-	Wpath	*up;		/* pointer upwards in path */
-	Wpath	*list;		/* link in free chain */
-	long	addr;		/* directory entry addr of parent */
-	long	slot;		/* directory entry slot of parent */
-	short	refs;		/* number of files using this structure */
-};
-
-#define	MAXFDATA	8192
-
-/*
- * error codes generated from the file server
- */
-enum
-{
-	Ebadspc = 1,
-	Efid,
-	Efidinuse,
-	Echar,
-	Eopen,
-	Ecount,
-	Ealloc,
-	Eqid,
-	Eauth,
-	Eauthmsg,
-	Eaccess,
-	Eentry,
-	Emode,
-	Edir1,
-	Edir2,
-	Ephase,
-	Eexist,
-	Edot,
-	Eempty,
-	Ebadu,
-	Enotu,
-	Enotg,
-	Ename,
-	Ewalk,
-	Eronly,
-	Efull,
-	Eoffset,
-	Elocked,
-	Ebroken,
-	Etoolong,
-	Ersc,
-	Eqidmode,
-	Econvert,
-	Enotm,
-	Enotd,
-	Enotl,
-	Enotw,
-	Esystem,
-
-	MAXERR
-};
-
-/*
- * devnone block numbers
- */
-enum
-{
-	Cwio1 	= 1,
-	Cwio2,
-	Cwxx1,
-	Cwxx2,
-	Cwxx3,
-	Cwxx4,
-	Cwdump1,
-	Cwdump2,
-	Cuidbuf,
-};
-
-/*
- * tags on block
- */
-enum
-{
-	Tnone		= 0,
-	Tsuper,			/* the super block */
-	Tdir,			/* directory contents */
-	Tind1,			/* points to blocks */
-	Tind2,			/* points to Tind1 */
-	Tfile,			/* file contents */
-	Tfree,			/* in free list */
-	Tbuck,			/* cache fs bucket */
-	Tvirgo,			/* fake worm virgin bits */
-	Tcache,			/* cw cache things */
-	MAXTAG
-};
-
-/*
- * flags to getbuf
- */
-enum
-{
-	Bread	= (1<<0),	/* read the block if miss */
-	Bprobe	= (1<<1),	/* return null if miss */
-	Bmod	= (1<<2),	/* set modified bit in buffer */
-	Bimm	= (1<<3),	/* set immediate bit in buffer */
-	Bres	= (1<<4),	/* reserved, never renammed */
-};
-
-/*
- * open modes passed into P9 open/create
- */
-enum
-{
-	MREAD	= 0,
-	MWRITE,
-	MBOTH,
-	MEXEC,
-	MTRUNC	= (1<<4),	/* truncate on open */
-	MCEXEC	= (1<<5),	/* close on exec (host) */
-	MRCLOSE	= (1<<6),	/* remove on close */
-};
-
-/*
- * check flags
- */
-enum
-{
-	Crdall	= (1<<0),	/* read all files */
-	Ctag	= (1<<1),	/* rebuild tags */
-	Cpfile	= (1<<2),	/* print files */
-	Cpdir	= (1<<3),	/* print directories */
-	Cfree	= (1<<4),	/* rebuild free list */
-	Cream	= (1<<6),	/* clear all bad tags */
-	Cbad	= (1<<7),	/* clear all bad blocks */
-	Ctouch	= (1<<8),	/* touch old dir and indir */
-	Cquiet	= (1<<9),	/* report just nasty things */
-};
-
-/*
- * buffer size variables
- */
-extern int	RBUFSIZE;
-extern int	BUFSIZE;
-extern int	DIRPERBUF;
-extern int	INDPERBUF;
-extern int	INDPERBUF2;
-extern int	FEPERBUF;
--- a/sys/src/cmd/disk/kfs/portfns.h
+++ /dev/null
@@ -1,104 +1,0 @@
-void	accessdir(Iobuf*, Dentry*, int);
-void	authfree(File*);
-void	addfree(Device, long, Superb*);
-long	balloc(Device, int, long);
-void	bfree(Device, long, int);
-int	byname(void*, void*);
-int	byuid(void*, void*);
-int	checkname(char*);
-int	checktag(Iobuf*, int, long);
-void 	cmd_user(void);
-char*	cname(char*);
-int	con_attach(int, char*, char*);
-int	con_clone(int, int);
-int	con_create(int, char*, int, int, long, int);
-int	con_open(int, int);
-int	con_path(int, char*);
-int	con_read(int, char*, long, int);
-int	con_remove(int);
-int	con_stat(int, char*);
-int	con_swap(int, int);
-int	con_clri(int);
-int	con_session(void);
-int	con_walk(int, char*);
-int	con_write(int, char*, long, int);
-int	con_wstat(int, char*);
-void	cprint(char*, ...);
-void	datestr(char*, long);
-void	dbufread(Iobuf*, Dentry*, long);
-Qid	dentryqid(Dentry*);
-int	devcmp(Device, Device);
-Iobuf*	dnodebuf(Iobuf*, Dentry*, long, int);
-Iobuf*	dnodebuf1(Iobuf*, Dentry*, long, int);
-void	dofilter(Filter*);
-int	doremove(File *, int);
-void	dtrunc(Iobuf*, Dentry*);
-void	exit(void);
-Float	famd(Float, int, int, int);
-int	fchar(void);
-ulong	fdf(Float, int);
-void	fileinit(Chan*);
-void	sublockinit(void);
-File*	filep(Chan*, int, int);
-int	fname(char*);
-void	formatinit(void);
-void	freefp(File*);
-void	freewp(Wpath*);
-Filsys*	fsstr(char*);
-Iobuf*	getbuf(Device, long, int);
-Dentry*	getdir(Iobuf*, int);
-long	getraddr(Device);
-Wpath*	getwp(Wpath*);
-void	hexdump(void*, int);
-int	iaccess(File*, Dentry*, int);
-long	indfetch(Iobuf*, Dentry*, long, long , int, int);
-int	ingroup(int, int);
-void	iobufinit(void);
-int	leadgroup(int, int);
-void	mkchallenge(Chan*);
-void	mkqid(Qid*, Dentry*, int);
-int	mkqidcmp(Qid*, Dentry*);
-void	mkqid9p1(Qid9p1*, Qid*);
-void	mkqid9p2(Qid*, Qid9p1*, int);
-int	netserve(char*);
-File*	newfp(Chan*);
-Qid	newqid(Device);
-void	newstart(void);
-Wpath*	newwp(void);
-int	oconvD2M(Dentry*, void*);
-int	oconvM2D(void*, Dentry*);
-int	ofcallfmt(Fmt*);
-void	panic(char*, ...);
-int	prime(long);
-void	putbuf(Iobuf*);
-void	putwp(Wpath*);
-long	qidpathgen(Device*);
-void	rootream(Device, long);
-void	settag(Iobuf*, int, long);
-void serve(Chan*);
-void	serve9p1(Chan*, uchar*, int);
-void	serve9p2(Chan*, uchar*, int);
-void	strrand(void*, int);
-int	strtouid(char*);
-int	strtouid1(char*);
-int	superok(Device, long, int);
-void	superream(Device, long);
-void	sync(char*);
-int	syncblock(void);
-int	Tfmt(Fmt*);
-Tlock*	tlocked(Iobuf*, Dentry*);
-void	uidtostr(char*,int);
-void	uidtostr1(char*,int);
-
-#pragma varargck	argpos	cprint	1
-#pragma varargck	argpos	panic	1
-
-#pragma varargck	type	"C"	Chan*
-#pragma varargck	type	"D"	Device
-#pragma varargck	type 	"A"	Filta
-#pragma varargck	type	"G"	int
-#pragma varargck	type	"T"	long
-#pragma varargck	type	"F"	Fcall*
-
-typedef struct Oldfcall Oldfcall;	/* needed for pragma */
-#pragma varargck	type	"O"	Oldfcall*
--- a/sys/src/cmd/disk/kfs/porttime.c
+++ /dev/null
@@ -1,243 +1,0 @@
-#include	"all.h"
-
-static	int	sunday(Tm *t, int d);
-static	int	dysize(int);
-static	void	ct_numb(char*, int);
-static	void	klocaltime(long tim, Tm *ct);
-static	void	kgmtime(long tim, Tm *ct);
-
-static	char	dmsize[12] =
-{
-	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/*
- * The following table is used for 1974 and 1975 and
- * gives the day number of the first day after the Sunday of the
- * change.
- */
-static	struct
-{
-	short	yrfrom;
-	short	yrto;
-	short	daylb;
-	short	dayle;
-} daytab[] =
-{
-	87,	999,	97,	303,
-	76,	86,	119,	303,
-	75,	75,	58,	303,
-	74,	74,	5,	333,
-	0,	73,	119,	303,
-};
-
-static struct
-{
-	short	minuteswest;	/* minutes west of Greenwich */
-	short	dsttime;	/* dst correction */
-} timezone =
-{
-	5*60, 1
-};
-
-static void
-klocaltime(long tim, Tm *ct)
-{
-	int daylbegin, daylend, dayno, i;
-	long copyt;
-
-	copyt = tim - timezone.minuteswest*60L;
-	kgmtime(copyt, ct);
-	dayno = ct->yday;
-	for(i=0;; i++)
-		if(ct->year >= daytab[i].yrfrom &&
-		   ct->year <= daytab[i].yrto) {
-			daylbegin = sunday(ct, daytab[i].daylb);
-			daylend = sunday(ct, daytab[i].dayle);
-			break;
-		}
-	if(timezone.dsttime &&
-	    (dayno>daylbegin || (dayno==daylbegin && ct->hour>=2)) &&
-	    (dayno<daylend || (dayno==daylend && ct->hour<1))) {
-		copyt += 60L*60L;
-		kgmtime(copyt, ct);
-	}
-}
-
-/*
- * The argument is a 0-origin day number.
- * The value is the day number of the last
- * Sunday before or after the day.
- */
-static
-sunday(Tm *t, int d)
-{
-	if(d >= 58)
-		d += dysize(t->year) - 365;
-	return d - (d - t->yday + t->wday + 700) % 7;
-}
-
-static void
-kgmtime(long tim, Tm *ct)
-{
-	int d0, d1;
-	long hms, day;
-
-	/*
-	 * break initial number into days
-	 */
-	hms = tim % 86400L;
-	day = tim / 86400L;
-	if(hms < 0) {
-		hms += 86400L;
-		day -= 1;
-	}
-
-	/*
-	 * generate hours:minutes:seconds
-	 */
-	ct->sec = hms % 60;
-	d1 = hms / 60;
-	ct->min = d1 % 60;
-	d1 /= 60;
-	ct->hour = d1;
-
-	/*
-	 * day is the day number.
-	 * generate day of the week.
-	 * The addend is 4 mod 7 (1/1/1970 was Thursday)
-	 */
-
-	ct->wday = (day + 7340036L) % 7;
-
-	/*
-	 * year number
-	 */
-	if(day >= 0)
-		for(d1 = 70; day >= dysize(d1); d1++)
-			day -= dysize(d1);
-	else
-		for (d1 = 70; day < 0; d1--)
-			day += dysize(d1-1);
-	ct->year = d1;
-	ct->yday = d0 = day;
-
-	/*
-	 * generate month
-	 */
-
-	if(dysize(d1) == 366)
-		dmsize[1] = 29;
-	for(d1 = 0; d0 >= dmsize[d1]; d1++)
-		d0 -= dmsize[d1];
-	dmsize[1] = 28;
-	ct->mday = d0 + 1;
-	ct->mon = d1;
-}
-
-void
-datestr(char *s, long t)
-{
-	Tm tm;
-
-	klocaltime(t, &tm);
-	sprint(s, "%.4d%.2d%.2d", tm.year+1900, tm.mon+1, tm.mday);
-}
-
-int
-Tfmt(Fmt *f1)
-{
-	char s[30];
-	char *cp;
-	long t;
-	Tm tm;
-
-	t = va_arg(f1->args, long);
-	if(t == 0)
-		return fmtstrcpy(f1, "The Epoch");
-
-	klocaltime(t, &tm);
-	strcpy(s, "Day Mon 00 00:00:00 1900");
-	cp = &"SunMonTueWedThuFriSat"[tm.wday*3];
-	s[0] = cp[0];
-	s[1] = cp[1];
-	s[2] = cp[2];
-	cp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[tm.mon*3];
-	s[4] = cp[0];
-	s[5] = cp[1];
-	s[6] = cp[2];
-	ct_numb(s+8, tm.mday);
-	ct_numb(s+11, tm.hour+100);
-	ct_numb(s+14, tm.min+100);
-	ct_numb(s+17, tm.sec+100);
-	if(tm.year >= 100) {
-		s[20] = '2';
-		s[21] = '0';
-	}
-	ct_numb(s+22, tm.year+100);
-
-	return fmtstrcpy(f1, s);
-}
-
-static
-dysize(int y)
-{
-
-	if((y%4) == 0)
-		return 366;
-	return 365;
-}
-
-static
-void
-ct_numb(char *cp, int n)
-{
-
-	if(n >= 10)
-		cp[0] = (n/10)%10 + '0';
-	else
-		cp[0] = ' ';
-	cp[1] = n%10 + '0';
-}
-
-/*
- * compute the next time after t
- * that has hour hr and is not on
- * day in bitpattern --
- * for automatic dumps
- */
-long
-nextime(long t, int hr, int day)
-{
-	Tm tm;
-	int nhr;
-
-	if(hr < 0 || hr >= 24)
-		hr = 5;
-	if((day&0x7f) == 0x7f)
-		day = 0;
-
-loop:
-	klocaltime(t, &tm);
-	t -= tm.sec;
-	t -= tm.min*60;
-	nhr = tm.hour;
-	do {
-		t += 60*60;
-		nhr++;
-	} while(nhr%24 != hr);
-	klocaltime(t, &tm);
-	if(tm.hour != hr) {
-		t += 60*60;
-		klocaltime(t, &tm);
-		if(tm.hour != hr) {
-			t -= 60*60;
-			klocaltime(t, &tm);
-		}
-	}
-	if(day & (1<<tm.wday)) {
-		t += 12*60*60;
-		goto loop;
-	}
-	return t;
-}
--- a/sys/src/cmd/disk/kfs/print.c
+++ /dev/null
@@ -1,288 +1,0 @@
-#include	"all.h"
-
-#define	PTR	sizeof(char*)
-#define	SHORT	sizeof(int)
-#define	INT	sizeof(int)
-#define	LONG	sizeof(long)
-#define	IDIGIT	30
-#define	MAXCON	30
-
-static	int	convcount  = { 10 };
-
-#define	PUT(o, c)	if((o)->p < (o)->ep) *(o)->p++ = c
-
-static	int	noconv(Op*);
-static	int	cconv(Op*);
-static	int	dconv(Op*);
-static	int	hconv(Op*);
-static	int	lconv(Op*);
-static	int	oconv(Op*);
-static	int	sconv(Op*);
-static	int	uconv(Op*);
-static	int	xconv(Op*);
-static	int	percent(Op*);
-
-static
-int	(*fmtconv[MAXCON])(Op*) =
-{
-	noconv,
-	cconv, dconv, hconv, lconv,
-	oconv, sconv, uconv, xconv,
-	percent,
-};
-static
-char	fmtindex[128] =
-{
-	['c'] 1,
-	['d'] 2,
-	['h'] 3,
-	['l'] 4,
-	['o'] 5,
-	['s'] 6,
-	['u'] 7,
-	['x'] 8,
-	['%'] 9,
-};
-
-int
-fmtinstall(char c, int (*f)(Op*))
-{
-
-	c &= 0177;
-	if(fmtindex[c] == 0) {
-		if(convcount >= MAXCON)
-			return 1;
-		fmtindex[c] = convcount++;
-	}
-	fmtconv[fmtindex[c]] = f;
-	return 0;
-}
-
-char*
-doprint(char *p, char *ep, char *fmt, void *argp)
-{
-	int sf1, c;
-	Op o;
-
-	o.p = p;
-	o.ep = ep;
-	o.argp = argp;
-
-loop:
-	c = *fmt++;
-	if(c != '%') {
-		if(c == 0) {
-			if(o.p < o.ep)
-				*o.p = 0;
-			return o.p;
-		}
-		PUT(&o, c);
-		goto loop;
-	}
-	o.f1 = 0;
-	o.f2 = -1;
-	o.f3 = 0;
-	c = *fmt++;
-	sf1 = 0;
-	if(c == '-') {
-		sf1 = 1;
-		c = *fmt++;
-	}
-	while(c >= '0' && c <= '9') {
-		o.f1 = o.f1*10 + c-'0';
-		c = *fmt++;
-	}
-	if(sf1)
-		o.f1 = -o.f1;
-	if(c != '.')
-		goto l1;
-	c = *fmt++;
-	while(c >= '0' && c <= '9') {
-		if(o.f2 < 0)
-			o.f2 = 0;
-		o.f2 = o.f2*10 + c-'0';
-		c = *fmt++;
-	}
-l1:
-	if(c == 0)
-		fmt--;
-	c = (*fmtconv[fmtindex[c&0177]])(&o);
-	if(c < 0) {
-		o.f3 |= -c;
-		c = *fmt++;
-		goto l1;
-	}
-	o.argp = (char*)o.argp + c;
-	goto loop;
-}
-
-int
-numbconv(Op *op, int base)
-{
-	char b[IDIGIT];
-	int i, f, n, r;
-	long v;
-	short h;
-
-	f = 0;
-	switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
-	case FLONG:
-		v = *(long*)op->argp;
-		r = LONG;
-		break;
-
-	case FUNSIGN|FLONG:
-		v = *(ulong*)op->argp;
-		r = LONG;
-		break;
-
-	case FSHORT:
-		h = *(int*)op->argp;
-		v = h;
-		r = SHORT;
-		break;
-
-	case FUNSIGN|FSHORT:
-		h = *(int*)op->argp;
-		v = (ushort)h;
-		r = SHORT;
-		break;
-
-	default:
-		v = *(int*)op->argp;
-		r = INT;
-		break;
-
-	case FUNSIGN:
-		v = *(unsigned*)op->argp;
-		r = INT;
-		break;
-	}
-	if(!(op->f3 & FUNSIGN) && v < 0) {
-		v = -v;
-		f = 1;
-	}
-	b[IDIGIT-1] = 0;
-	for(i = IDIGIT-2;; i--) {
-		n = (ulong)v % base;
-		n += '0';
-		if(n > '9')
-			n += 'a' - ('9'+1);
-		b[i] = n;
-		if(i < 2)
-			break;
-		v = (ulong)v / base;
-		if(op->f2 >= 0 && i >= IDIGIT-op->f2)
-			continue;
-		if(v <= 0)
-			break;
-	}
-sout:
-	if(f)
-		b[--i] = '-';
-	strconv(b+i, op, op->f1, -1);
-	return r;
-}
-
-void
-strconv(char *o, Op *op, int f1, int f2)
-{
-	int n, c;
-	char *p;
-
-	n = strlen(o);
-	if(f1 >= 0)
-		while(n < f1) {
-			PUT(op, ' ');
-			n++;
-		}
-	for(p=o; c = *p++;)
-		if(f2 != 0) {
-			PUT(op, c);
-			f2--;
-		}
-	if(f1 < 0) {
-		f1 = -f1;
-		while(n < f1) {
-			PUT(op, ' ');
-			n++;
-		}
-	}
-}
-
-static	int
-noconv(Op *op)
-{
-
-	strconv("***", op, 0, -1);
-	return 0;
-}
-
-static	int
-cconv(Op *op)
-{
-	char b[2];
-
-	b[0] = *(int*)op->argp;
-	b[1] = 0;
-	strconv(b, op, op->f1, -1);
-	return INT;
-}
-
-static	int
-dconv(Op *op)
-{
-
-	return numbconv(op, 10);
-}
-
-static	int
-hconv(Op *op)
-{
-	USED(op);
-	return -FSHORT;
-}
-
-static	int
-lconv(Op *op)
-{
-	USED(op);
-	return -FLONG;
-}
-
-static	int
-oconv(Op *op)
-{
-	USED(op);
-	return numbconv(op, 8);
-}
-
-static	int
-sconv(Op *op)
-{
-
-	strconv(*(char**)op->argp, op, op->f1, op->f2);
-	return PTR;
-}
-
-static	int
-uconv(Op *op)
-{
-	USED(op);
-	return -FUNSIGN;
-}
-
-static	int
-xconv(Op *op)
-{
-
-	return numbconv(op, 16);
-}
-
-static	int
-percent(Op *op)
-{
-
-	PUT(op, '%');
-	return 0;
-}
--- a/sys/src/cmd/disk/kfs/sub.c
+++ /dev/null
@@ -1,687 +1,0 @@
-#include	"all.h"
-
-Lock wpathlock;
-
-struct {
-	Lock	flock;
-	File*	ffree;		/* free file structures */
-	Wpath*	wfree;
-} suballoc;
-
-enum{
-	Finc=	128,	/* allocation chunksize for files */
-	Fmax=	10000,	/* maximum file structures to be allocated */
-	
-	Winc=	8*128,	/* allocation chunksize for wpath */
-	Wmax=	8*10000,	/* maximum wpath structures to be allocated */
-};
-
-
-Filsys*
-fsstr(char *p)
-{
-	Filsys *fs;
-
-	for(fs=filesys; fs->name; fs++)
-		if(strcmp(fs->name, p) == 0)
-			return fs;
-	return 0;
-}
-
-void
-fileinit(Chan *cp)
-{
-	File *f;
-	Tlock *t;
-
-loop:
-	lock(&cp->flock);
-	f = cp->flist;
-	if(!f) {
-		unlock(&cp->flock);
-		return;
-	}
-	cp->flist = f->next;
-	unlock(&cp->flock);
-
-	qlock(f);
-	if(t = f->tlock) {
-		t->time = 0;
-		f->tlock = 0;
-	}
-	if(f->open & FREMOV)
-		doremove(f, 0);
-	freewp(f->wpath);
-	f->open = 0;
-	f->cp = 0;
-	qunlock(f);
-
-	goto loop;
-}
-
-/*
- * returns a locked file structure
- */
-File*
-filep(Chan *cp, int fid, int flag)
-{
-	File *f, *prev;
-
-	if(fid == NOF)
-		return 0;
-
-loop:
-	lock(&cp->flock);
-	for(prev=0,f=cp->flist; f; prev=f,f=f->next) {
-		if(f->fid != fid)
-			continue;
-		if(prev) {
-			prev->next = f->next;
-			f->next = cp->flist;
-			cp->flist = f;
-		}
-		goto out;
-	}
-	if(flag) {
-		f = newfp(cp);
-		if(f) {
-			f->fid = fid;
-			goto out;
-		}
-	}
-else print("cannot find %p.%ud (list=%p)\n", cp, fid, cp->flist);
-	unlock(&cp->flock);
-	return 0;
-
-out:
-	unlock(&cp->flock);
-	qlock(f);
-	if(f->fid != fid) {
-		qunlock(f);
-		goto loop;
-	}
-	return f;
-}
-
-void
-sublockinit(void)
-{
-	lock(&suballoc.flock);
-	lock(&wpathlock);
-	conf.nfile = 0;
-	conf.nwpath = 0;
-	unlock(&suballoc.flock);
-	unlock(&wpathlock);
-}	
-
-/*
- * always called with cp->flock locked
- */
-File*
-newfp(Chan *cp)
-{
-	File *f, *e;
-
-retry:
-	lock(&suballoc.flock);
-	f = suballoc.ffree;
-	if(f != nil){
-		suballoc.ffree = f->list;
-		unlock(&suballoc.flock);
-		f->list = 0;
-		f->cp = cp;
-		f->next = cp->flist;
-		f->wpath = 0;
-		f->tlock = 0;
-		f->dslot = 0;
-		f->doffset = 0;
-		f->uid = 0;
-		f->cuid = 0;
-		cp->flist = f;
-		return f;
-	}
-	unlock(&suballoc.flock);
-
-	if(conf.nfile > Fmax){
-		print("%d: out of files\n", cp->chan);
-		return 0;
-	}
-
-	/*
-	 *  create a few new files
-	 */
-	f = malloc(Finc*sizeof(*f));
-	memset(f, 0, Finc*sizeof(*f));
-	lock(&suballoc.flock);
-	for(e = f+Finc; f < e; f++){
-		qlock(f);
-		qunlock(f);
-		f->list = suballoc.ffree;
-		suballoc.ffree = f;
-	}
-	conf.nfile += Finc;
-	unlock(&suballoc.flock);
-	goto retry;
-}
-
-void
-freefp(File *fp)
-{
-	Chan *cp;
-	File *f, *prev;
-
-	if(!fp || !(cp = fp->cp))
-		return;
-	authfree(fp);
-	lock(&cp->flock);
-	for(prev=0,f=cp->flist; f; prev=f,f=f->next) {
-		if(f != fp)
-			continue;
-		if(prev)
-			prev->next = f->next;
-		else
-			cp->flist = f->next;
-		f->cp = 0;
-		lock(&suballoc.flock);
-		f->list = suballoc.ffree;
-		suballoc.ffree = f;
-		unlock(&suballoc.flock);
-		break;
-	}
-	unlock(&cp->flock);
-}
-
-Wpath*
-newwp(void)
-{
-	Wpath *w, *e;
-
-retry:
-	lock(&wpathlock);
-	w = suballoc.wfree;
-	if(w != nil){
-		suballoc.wfree = w->list;
-		unlock(&wpathlock);
-		memset(w, 0, sizeof(*w));
-		w->refs = 1;
-		w->up = 0;
-		return w;
-	}
-	unlock(&wpathlock);
-
-	if(conf.nwpath > Wmax){
-		print("out of wpaths\n");
-		return 0;
-	}
-
-	/*
-	 *  create a few new wpaths
-	 */
-	w = malloc(Winc*sizeof(*w));
-	memset(w, 0, Winc*sizeof(*w));
-	lock(&wpathlock);
-	for(e = w+Winc; w < e; w++){
-		w->list = suballoc.wfree;
-		suballoc.wfree = w;
-	}
-	conf.nwpath += Winc;
-	unlock(&wpathlock);
-	goto retry;
-}
-
-/*
- *  increment the references for the whole path
- */
-Wpath*
-getwp(Wpath *w)
-{
-	Wpath *nw;
-
-	lock(&wpathlock);
-	for(nw = w; nw; nw=nw->up)
-		nw->refs++;
-	unlock(&wpathlock);
-	return w;
-}
-
-/*
- *  decrement the reference for each element of the path
- */
-void
-freewp(Wpath *w)
-{
-	lock(&wpathlock);
-	for(; w; w=w->up){
-		w->refs--;
-		if(w->refs == 0){
-			w->list = suballoc.wfree;
-			suballoc.wfree = w;
-		}
-	}
-	unlock(&wpathlock);
-}
-
-/*
- *  decrement the reference for just this element
- */
-void
-putwp(Wpath *w)
-{
-	lock(&wpathlock);
-	w->refs--;
-	if(w->refs == 0){
-		w->list = suballoc.wfree;
-		suballoc.wfree = w;
-	}
-	unlock(&wpathlock);
-}
-
-int
-iaccess(File *f, Dentry *d, int m)
-{
-	if(wstatallow)
-		return 0;
-
-	/*
-	 * owner is next
-	 */
-	if(f->uid == d->uid)
-		if((m<<6) & d->mode)
-			return 0;
-	/*
-	 * group membership is hard
-	 */
-	if(ingroup(f->uid, d->gid))
-		if((m<<3) & d->mode)
-			return 0;
-	/*
-	 * other access for everyone except members of group 9999
-	 */
-	if(m & d->mode){
-		/* 
-		 *  walk directories regardless.
-		 *  otherwise its impossible to get
-		 *  from the root to noworld's directories.
-		 */
-		if((d->mode & DDIR) && (m == DEXEC))
-			return 0;
-		if(!ingroup(f->uid, 9999))
-			return 0;
-	}
-	return 1;
-}
-
-Tlock*
-tlocked(Iobuf *p, Dentry *d)
-{
-	Tlock *t, *t1;
-	long qpath, tim;
-	Device dev;
-
-	tim = time(0);
-	qpath = d->qid.path;
-	dev = p->dev;
-	t1 = 0;
-	for(t=tlocks+NTLOCK-1; t>=tlocks; t--) {
-		if(t->qpath == qpath)
-		if(t->time >= tim)
-		if(devcmp(t->dev, dev) == 0)
-			return 0;		/* its locked */
-		if(!t1 && t->time < tim)
-			t1 = t;			/* steal first lock */
-	}
-	if(t1) {
-		t1->dev = dev;
-		t1->qpath = qpath;
-		t1->time = tim + TLOCK;
-	}
-	/* botch
-	 * out of tlock nodes simulates
-	 * a locked file
-	 */
-	return t1;
-}
-
-Qid
-newqid(Device dev)
-{
-	Iobuf *p;
-	Superb *sb;
-	Qid qid;
-
-	p = getbuf(dev, superaddr(dev), Bread|Bmod);
-	if(!p || checktag(p, Tsuper, QPSUPER))
-		panic("newqid: super block");
-	sb = (Superb*)p->iobuf;
-	sb->qidgen++;
-	qid.path = sb->qidgen;
-	qid.vers = 0;
-	qid.type = 0;
-	putbuf(p);
-	return qid;
-}
-
-/*
- * what are legal characters in a name?
- * only disallow control characters.
- * a) utf avoids control characters.
- * b) '/' may not be the separator
- */
-int
-checkname(char *n)
-{
-	int i, c;
-
-	for(i=0; i<NAMELEN; i++) {
-		c = *n & 0xff;
-		if(c == 0) {
-			if(i == 0)
-				return 1;
-			memset(n, 0, NAMELEN-i);
-			return 0;
-		}
-		if(c <= 040)
-			return 1;
-		n++;
-	}
-	return 1;	/* too long */
-}
-
-void
-bfree(Device dev, long addr, int d)
-{
-	Iobuf *p;
-	long a;
-	int i;
-
-	if(!addr)
-		return;
-	if(d > 0) {
-		d--;
-		p = getbuf(dev, addr, Bread);
-		if(p) {
-			for(i=INDPERBUF-1; i>=0; i--) {
-				a = ((long*)p->iobuf)[i];
-				bfree(dev, a, d);
-			}
-			putbuf(p);
-		}
-	}
-	/*
-	 * stop outstanding i/o
-	 */
-	p = getbuf(dev, addr, Bprobe);
-	if(p) {
-		p->flags &= ~(Bmod|Bimm);
-		putbuf(p);
-	}
-	/*
-	 * dont put written worm
-	 * blocks into free list
-	 */
-	if(nofree(dev, addr))
-		return;
-	p = getbuf(dev, superaddr(dev), Bread|Bmod);
-	if(!p || checktag(p, Tsuper, QPSUPER))
-		panic("bfree: super block");
-	addfree(dev, addr, (Superb*)p->iobuf);
-	putbuf(p);
-}
-
-long
-balloc(Device dev, int tag, long qid)
-{
-	Iobuf *bp, *p;
-	Superb *sb;
-	long a;
-	int n;
-
-	p = getbuf(dev, superaddr(dev), Bread|Bmod);
-	if(!p || checktag(p, Tsuper, QPSUPER))
-		panic("balloc: super block");
-	sb = (Superb*)p->iobuf;
-
-loop:
-	n = --sb->fbuf.nfree;
-	sb->tfree--;
-	if(n < 0 || n >= FEPERBUF)
-		panic("balloc: bad freelist");
-	a = sb->fbuf.free[n];
-	if(n <= 0) {
-		if(a == 0) {
-			sb->tfree = 0;
-			sb->fbuf.nfree = 1;
-			if(devgrow(dev, sb))
-				goto loop;
-			putbuf(p);
-			return 0;
-		}
-		bp = getbuf(dev, a, Bread);
-		if(!bp || checktag(bp, Tfree, QPNONE)) {
-			if(bp)
-				putbuf(bp);
-			putbuf(p);
-			return 0;
-		}
-		memmove(&sb->fbuf, bp->iobuf, (FEPERBUF+1)*sizeof(long));
-		putbuf(bp);
-	}
-	bp = getbuf(dev, a, Bmod);
-	memset(bp->iobuf, 0, RBUFSIZE);
-	settag(bp, tag, qid);
-	if(tag == Tind1 || tag == Tind2 || tag == Tdir)
-		bp->flags |= Bimm;
-	putbuf(bp);
-	putbuf(p);
-	return a;
-}
-
-void
-addfree(Device dev, long addr, Superb *sb)
-{
-	int n;
-	Iobuf *p;
-
-	if(addr >= sb->fsize){
-		print("addfree: bad addr %lux\n", addr);
-		return;
-	}
-	n = sb->fbuf.nfree;
-	if(n < 0 || n > FEPERBUF)
-		panic("addfree: bad freelist");
-	if(n >= FEPERBUF) {
-		p = getbuf(dev, addr, Bmod);
-		if(p == 0)
-			panic("addfree: getbuf");
-		memmove(p->iobuf, &sb->fbuf, (FEPERBUF+1)*sizeof(long));
-		settag(p, Tfree, QPNONE);
-		putbuf(p);
-		n = 0;
-	}
-	sb->fbuf.free[n++] = addr;
-	sb->fbuf.nfree = n;
-	sb->tfree++;
-	if(addr >= sb->fsize)
-		sb->fsize = addr+1;
-}
-
-int
-Cfmt(Fmt *f1)
-{
-	Chan *cp;
-
-	cp = va_arg(f1->args, Chan*);
-	return fmtprint(f1, "C%d.%.3d", cp->type, cp->chan);
-}
-
-int
-Dfmt(Fmt *f1)
-{
-	Device d;
-
-	d = va_arg(f1->args, Device);
-	return fmtprint(f1, "D%d.%d.%d.%d", d.type, d.ctrl, d.unit, d.part);
-}
-
-int
-Afmt(Fmt *f1)
-{
-	Filta a;
-
-	a = va_arg(f1->args, Filta);
-	return fmtprint(f1, "%6lud %6lud %6lud",
-		fdf(a.f->filter[0], a.scale*60),
-		fdf(a.f->filter[1], a.scale*600),
-		fdf(a.f->filter[2], a.scale*6000));
-}
-
-int
-Gfmt(Fmt *f1)
-{
-	int t;
-
-	t = va_arg(f1->args, int);
-	if(t >= 0 && t < MAXTAG)
-		return fmtstrcpy(f1, tagnames[t]);
-	else
-		return fmtprint(f1, "<badtag %d>", t);
-}
-
-void
-formatinit(void)
-{
-
-	fmtinstall('C', Cfmt);	/* print channels */
-	fmtinstall('D', Dfmt);	/* print devices */
-	fmtinstall('A', Afmt);	/* print filters */
-	fmtinstall('G', Gfmt);	/* print tags */
-	fmtinstall('T', Tfmt);	/* print times */
-	fmtinstall('O', ofcallfmt);	/* print old fcalls */
-}
-int
-devcmp(Device d1, Device d2)
-{
-
-	if(d1.type == d2.type)
-	if(d1.ctrl == d2.ctrl)
-	if(d1.unit == d2.unit)
-	if(d1.part == d2.part)
-		return 0;
-	return 1;
-}
-
-void
-rootream(Device dev, long addr)
-{
-	Iobuf *p;
-	Dentry *d;
-
-	p = getbuf(dev, addr, Bmod|Bimm);
-	memset(p->iobuf, 0, RBUFSIZE);
-	settag(p, Tdir, QPROOT);
-	d = getdir(p, 0);
-	strcpy(d->name, "/");
-	d->uid = -1;
-	d->gid = -1;
-	d->mode = DALLOC | DDIR | 0775;
-	d->qid = QID9P1(QPROOT|QPDIR,0);
-	d->atime = time(0);
-	d->mtime = d->atime;
-	putbuf(p);
-}
-
-int
-superok(Device dev, long addr, int set)
-{
-	Iobuf *p;
-	Superb *s;
-	int ok;
-
-	p = getbuf(dev, addr, Bread|Bmod|Bimm);
-	s = (Superb*)p->iobuf;
-	ok = s->fsok;
-	s->fsok = set;
-	putbuf(p);
-	return ok;
-}
-
-void
-superream(Device dev, long addr)
-{
-	Iobuf *p;
-	Superb *s;
-	long i;
-
-	p = getbuf(dev, addr, Bmod|Bimm);
-	memset(p->iobuf, 0, RBUFSIZE);
-	settag(p, Tsuper, QPSUPER);
-
-	s = (Superb*)p->iobuf;
-	s->fstart = 1;
-	s->fsize = devsize(dev);
-	s->fbuf.nfree = 1;
-	s->qidgen = 10;
-	for(i=s->fsize-1; i>=addr+2; i--)
-		addfree(dev, i, s);
-	putbuf(p);
-}
-
-/*
- * returns 1 if n is prime
- * used for adjusting lengths
- * of hashing things.
- * there is no need to be clever
- */
-int
-prime(long n)
-{
-	long i;
-
-	if((n%2) == 0)
-		return 0;
-	for(i=3;; i+=2) {
-		if((n%i) == 0)
-			return 0;
-		if(i*i >= n)
-			return 1;
-	}
-}
-
-void
-hexdump(void *a, int n)
-{
-	char s1[30], s2[4];
-	uchar *p;
-	int i;
-
-	p = a;
-	s1[0] = 0;
-	for(i=0; i<n; i++) {
-		sprint(s2, " %.2ux", p[i]);
-		strcat(s1, s2);
-		if((i&7) == 7) {
-			print("%s\n", s1);
-			s1[0] = 0;
-		}
-	}
-	if(s1[0])
-		print("%s\n", s1);
-}
-
-long
-qidpathgen(Device *dev)
-{
-	Iobuf *p;
-	Superb *sb;
-	long path;
-
-	p = getbuf(*dev, superaddr((*dev)), Bread|Bmod);
-	if(!p || checktag(p, Tsuper, QPSUPER))
-		panic("newqid: super block");
-	sb = (Superb*)p->iobuf;
-	sb->qidgen++;
-	path = sb->qidgen;
-	putbuf(p);
-	return path;
-}
-
--- a/sys/src/cmd/disk/kfs/uid.c
+++ /dev/null
@@ -1,427 +1,0 @@
-#include "all.h"
-
-struct
-{
-	RWLock	uidlock;
-	char*	uidbuf;
-	int	flen;
-	int	find;
-} uidgc;
-
-int
-byuid(void *a1, void *a2)
-{
-	Uid *u1, *u2;
-
-	u1 = a1;
-	u2 = a2;
-	return u2->uid - u1->uid;
-}
-
-int
-byname(void *a1, void *a2)
-{
-	Uid *u1, *u2;
-
-	u1 = a1;
-	u2 = a2;
-	return strcmp(uidspace+u2->offset, uidspace+u1->offset);
-}
-
-int
-fchar(void)
-{
-
-	if(uidgc.find >= uidgc.flen) {
-		uidgc.find = 0;
-		uidgc.flen = con_read(FID2, uidgc.uidbuf, cons.offset, MAXDAT);
-		if(uidgc.flen <= 0)
-			return 0;
-		cons.offset += uidgc.flen;
-	}
-	return uidgc.uidbuf[uidgc.find++];
-}
-
-int
-fname(char *name)
-{
-	int i, c;
-
-	memset(name, 0, NAMELEN);
-	for(i=0;; i++) {
-		c = fchar();
-		switch(c) {
-		case ':':
-		case '\n':
-		case ',':
-		case ' ':
-		case '#':
-		case 0:
-			return c;
-		}
-		if(i < NAMELEN-1)
-			name[i] = c;
-	}
-}
-
-#ifdef sometime
-/*
- * file format is
- * uid:name:lead:member,member,...\n
- */
-void
-read_user(void)
-{
-	int c;
-
-	if((c=fname(ustr))!=':' || (c=fname(name))!=':' || (c=fname(lead))!=':')
-		goto skipline;
-	n = atol(ustr);
-	if(n == 0)
-		goto skipline;
-	if(readu){
-		o -= strlen(name)+1;
-		if(o < 0) {
-			cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
-			return -1;
-		}
-		strcpy(uidspace+o, name);
-		uid[u].uid = n;
-		uid[u].offset = o;
-		u++;
-		if(u >= conf.nuid) {
-			cprint("conf.nuid(%ld) too small\n", conf.nuid);
-			goto initu;
-		}
-	}else{
-		o = strtouid1(name);
-		if(o == 0 && strcmp(name, "") != 0)
-			o = n;
-		for(c=0; c<u; c++)
-			if(uid[c].uid == n) {
-				uid[c].lead = o;
-				break;
-			}
-		while(((c=fname(name))==',' || c=='\n') && name[0]){
-work here		
-			if(c=='\n')
-				break;
-		}
-	}
-	
-skipline:
-	while(c != '\n')
-		fname(ustr);
-}
-#endif
-
-/*
-	-1:adm:adm:
-	0:none:adm:
-	1:tor:tor:
-	10000:sys::
-	10001:map:map:
-	10002:doc::
-	10003:upas:upas:
-	10004:font::
-	10005:bootes:bootes:
-*/
-
-struct {
-	int	uid;
-	char	*name;
-	int	leader;
-}
-admusers[] = {
-	-1,	"adm",	-1,
-	 0,	"none",	-1,
-	 1,	"tor",	1,
-	 2,	"glenda",	2,
-	10000,	"sys",	0,
-	10001,	"upas",	10001,
-	10002,	"bootes",	10002,
-	0,	0,	0,
-};
-
-
-void
-cmd_user(void)
-{
-	int c, n, o, u, g, i;
-	char name[NAMELEN];
-
-	if(con_clone(FID1, FID2))
-		goto ainitu;
-	if(con_path(FID2, "/adm/users"))
-		goto ainitu;
-	if(con_open(FID2, 0)){
-		goto ainitu;
-	}
-
-	wlock(&uidgc.uidlock);
-	uidgc.uidbuf = malloc(MAXDAT);
-
-	memset(uid, 0, conf.nuid * sizeof(*uid));
-	memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
-	memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
-
-	uidgc.flen = 0;
-	uidgc.find = 0;
-	cons.offset = 0;
-	u = 0;
-	o = conf.uidspace;
-
-ul1:
-	c = fname(name);
-	if(c != ':')
-		goto uskip;
-	n = atol(name);
-	if(n == 0)
-		goto uskip;
-	c = fname(name);
-	if(c != ':')
-		goto uskip;
-	o -= strlen(name)+1;
-	if(o < 0) {
-		cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
-		goto initu;
-	}
-	strcpy(uidspace+o, name);
-	uid[u].uid = n;
-	uid[u].offset = o;
-	u++;
-	if(u >= conf.nuid) {
-		cprint("conf.nuid(%ld) too small\n", conf.nuid);
-		goto initu;
-	}
-
-uskip:
-	if(c == '\n')
-		goto ul1;
-	if(c) {
-		c = fname(name);
-		goto uskip;
-	}
-/*	cprint("%d uids read\n", u);/**/
-	qsort(uid, u, sizeof(uid[0]), byuid);
-	for(c=u-1; c>0; c--)
-		if(uid[c].uid == uid[c-1].uid) {
-			cprint("duplicate uids: %d\n", uid[c].uid);
-			cprint("	%s", uidspace+uid[c].offset);
-			cprint(" %s\n", uidspace+uid[c-1].offset);
-		}
-	qsort(uid, u, sizeof(uid[0]), byname);
-	for(c=u-1; c>0; c--)
-		if(!strcmp(uidspace+uid[c].offset,
-		   uidspace+uid[c-1].offset)) {
-			cprint("kfs: duplicate names: %s\n", uidspace+uid[c].offset);
-			cprint("	%d", uid[c].uid);
-			cprint(" %d\n", uid[c-1].uid);
-		}
-	if(cons.flags & Fuid)
-		for(c=0; c<u; c++)
-			cprint("%6d %s\n", uid[c].uid, uidspace+uid[c].offset);
-
-	uidgc.flen = 0;
-	uidgc.find = 0;
-	cons.offset = 0;
-	g = 0;
-
-gl1:
-	c = fname(name);
-	if(c != ':')
-		goto gskip;
-	n = atol(name);		/* number */
-	if(n == 0)
-		goto gskip;
-	c = fname(name);	/* name */
-	if(c != ':')
-		goto gskip;
-	c = fname(name);	/* leader */
-	if(c != ':')
-		goto gskip;
-	o = strtouid1(name);
-	if(o == 0 && strcmp(name, "") != 0)
-		o = n;
-	for(c=0; c<u; c++)
-		if(uid[c].uid == n) {
-			uid[c].lead = o;
-			break;
-		}
-	c = fname(name);	/* list of members */
-	if(c != ',' && c != '\n')
-		goto gskip;
-	if(!name[0])
-		goto gskip;
-	gidspace[g++] = n;
-gl2:
-	n = strtouid1(name);
-	if(n)
-		gidspace[g++] = n;
-	if(g >= conf.gidspace-2) {
-		cprint("conf.gidspace(%ld) too small\n", conf.gidspace);
-		goto initu;
-	}
-	if(c == '\n')
-		goto gl3;
-	c = fname(name);
-	if(c == ',' || c == '\n')
-		goto gl2;
-	cprint("gid truncated\n");
-
-gl3:
-	gidspace[g++] = 0;
-
-gskip:
-	if(c == '\n')
-		goto gl1;
-	if(c) {
-		c = fname(name);
-		goto gskip;
-	}
-	if(cons.flags & Fuid) {
-		o = 0;
-		for(c=0; c<g; c++) {
-			n = gidspace[c];
-			if(n == 0) {
-				o = 0;
-				continue;
-			}
-			uidtostr1(name, n);
-			if(o) {
-				if(o > 6) {
-					cprint("\n       %s", name);
-					o = 1;
-				} else
-					cprint(" %s", name);
-			} else
-				cprint("\n%6s", name);
-			o++;
-		}
-		cprint("\n");
-	}
-	goto out;
-
-ainitu:
-	wlock(&uidgc.uidlock);
-	uidgc.uidbuf = malloc(MAXDAT);
-
-initu:
-	cprint("initializing minimal user table\n");
-	memset(uid, 0, conf.nuid * sizeof(*uid));
-	memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
-	memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
-	o = conf.uidspace;
-	u = 0;
-
-	for(i=0; admusers[i].name; i++){
-		o -= strlen(admusers[i].name)+1;
-		strcpy(uidspace+o, admusers[i].name);
-		uid[u].uid = admusers[i].uid;
-		uid[u].lead = admusers[i].leader;
-		uid[u].offset = o;
-		u++;
-	}
-
-out:
-	free(uidgc.uidbuf);
-	writegroup = strtouid1("write");
-	wunlock(&uidgc.uidlock);
-
-}
-
-void
-uidtostr(char *name, int id)
-{
-	rlock(&uidgc.uidlock);
-	uidtostr1(name, id);
-	runlock(&uidgc.uidlock);
-}
-
-void
-uidtostr1(char *name, int id)
-{
-	Uid *u;
-	int i;
-
-	if(id == 0){
-		strncpy(name, "none", NAMELEN);
-		return;
-	}
-	for(i=0, u=uid; i<conf.nuid; i++,u++) {
-		if(u->uid == id) {
-			strncpy(name, uidspace+u->offset, NAMELEN);
-			return;
-		}
-	}
-	strncpy(name, "none", NAMELEN);
-}
-
-int
-strtouid(char *s)
-{
-	int i;
-
-	rlock(&uidgc.uidlock);
-	i = strtouid1(s);
-	runlock(&uidgc.uidlock);
-	return i;
-}
-
-int
-strtouid1(char *s)
-{
-	Uid *u;
-	int i;
-
-	for(i=0, u=uid; i<conf.nuid; i++,u++)
-		if(!strcmp(s, uidspace+u->offset))
-			return u->uid;
-	return 0;
-}
-
-int
-ingroup(int u, int g)
-{
-	short *p;
-
-	if(u == g)
-		return 1;
-	rlock(&uidgc.uidlock);
-	for(p=gidspace; *p;) {
-		if(*p != g) {
-			for(p++; *p++;)
-				;
-			continue;
-		}
-		for(p++; *p; p++)
-			if(*p == u) {
-				runlock(&uidgc.uidlock);
-				return 1;
-			}
-	}
-	runlock(&uidgc.uidlock);
-	return 0;
-}
-
-int
-leadgroup(int ui, int gi)
-{
-	Uid *u;
-	int i;
-
-	rlock(&uidgc.uidlock);
-	for(i=0, u=uid; i<conf.nuid; i++,u++) {
-		if(u->uid == gi) {
-			i = u->lead;
-			runlock(&uidgc.uidlock);
-			if(i == ui)
-				return 1;
-			if(i == 0)
-				return ingroup(ui, gi);
-			return 0;
-		}
-	}
-	runlock(&uidgc.uidlock);
-	return 0;
-}
--- a/sys/src/cmd/disk/kfscmd.c
+++ /dev/null
@@ -1,56 +1,0 @@
-#include <u.h>
-#include <libc.h>
-
-void
-main(int argc, char *argv[])
-{
-	char *name, buf[4*1024];
-	int fd, n, i, errs;
-
-	name = 0;
-	ARGBEGIN{
-	case 'n':
-		name = ARGF();
-		break;
-	default:
-		fprint(2, "usage: kfscmd [-n server] commands\n");
-		exits("usage");
-	}ARGEND
-
-	if(name)
-		snprint(buf, sizeof buf, "/srv/kfs.%s.cmd", name);
-	else
-		strcpy(buf, "/srv/kfs.cmd");
-	fd = open(buf, ORDWR);
-	if(fd < 0){
-		fprint(2, "kfscmd: can't open commands file\n");
-		exits("commands file");
-	}
-
-	errs = 0;
-	for(i = 0; i < argc; i++){
-		if(write(fd, argv[i], strlen(argv[i])) != strlen(argv[i])){
-			fprint(2, "%s: error writing %s: %r", argv0, argv[i]);
-			errs++;
-			continue;
-		}
-		for(;;){
-			n = read(fd, buf, sizeof buf - 1);
-			if(n < 0){
-				fprint(2, "%s: error executing %s: %r", argv0, argv[i]);
-				errs++;
-				break;
-			}
-			buf[n] = '\0';
-			if(strcmp(buf, "done") == 0 || strcmp(buf, "success") == 0)
-				break;
-			if(strcmp(buf, "unknown command") == 0){
-				errs++;
-				print("kfscmd: command %s not recognized\n", argv[i]);
-				break;
-			}
-			write(1, buf, n);
-		}
-	}
-	exits(errs ? "errors" : 0);		
-}
--- a/sys/src/cmd/disk/mkfile
+++ b/sys/src/cmd/disk/mkfile
@@ -2,7 +2,6 @@
 
 TARG=exsort\
 	format\
-	kfscmd\
 	mbr\
 	mkext\
 	mkfs\
@@ -10,7 +9,6 @@
 
 DIRS=\
 	9660\
-	kfs\
 	prep\
 	smart\
 #	sacfs\
@@ -29,23 +27,20 @@
 
 </sys/src/cmd/mkmany
 
-all:V:	all-kfs
+all:V:	all-dirs
 
-install:V:	install-kfs ksync
+install:V:	install-dirs
 
-clean:V:	clean-kfs
+clean:V:	clean-dirs
 
-nuke:V:		nuke-kfs
+nuke:V:		nuke-dirs
 
-installall:V:	installall-kfs
+installall:V:	installall-dirs
 
-%-kfs:V:
+%-dirs:V:
 	for(i in $DIRS) @{
 		cd $i
 		mk $MKFLAGS $stem
 	}
-
-ksync:
-	touch $BIN/ksync
 
 $O.format: /$objtype/lib/libdisk.a