code: mafs

Download patch

ref: 7038b412045ad003366804789e7fecaf0552f77c
parent: ce708f49bf5ec6c6b3fe1bb29d401c42b841b649
author: 9ferno <gophone2015@gmail.com>
date: Sun Jan 15 00:18:41 EST 2023

bug fixes

--- a/9p.c
+++ b/9p.c
@@ -672,6 +672,7 @@
 	u32 perm;
 	Fid *fid;
 	Tlock *t;
+	Qid qid;
 
 	if(waserror()){
 		responderror(req);
@@ -746,6 +747,13 @@
 		if(canaccess(aux->uid, dchild, DMWRITE) == 0)
 			error(errstring[Eaccess]);
 
+		if((req->ifcall.mode&DMDIR) != (dchild->mode&DMDIR)){
+			if(dchild->mode&DMDIR)
+				error(errstring[Edexist]);
+			else
+				error(errstring[Eexist]);
+		}
+
 		/* req->ifcall.name matched, truncate file and use it */
 		if(permcheck(dchild->uid, dchild->gid, aux->uid, perm, ORDWR) == 0)
 			error(errstring[Eperm]);
@@ -795,11 +803,6 @@
 			freeblockbuf(cbuf);
 			nexterror();
 		}
-		blkno = cbuf->blkno;
-		/* only add it to the directory dentry if we are adding a new dentry block
-			if we are reusing a zero'ed out slot, it already exists in the
-			directory dentry */
-		addrelative(dparent, dbuf->blkno, reli, cbuf->blkno);
 	}else{
 		cbuf = egetmetachk(blkno, Bwritable, Tdentry, Qpnone);
 		if(waserror()){
@@ -807,12 +810,6 @@
 			nexterror();
 		}
 	}
-	if(addname(dparent, aux->uid, reli, req->ifcall.name) == 0)
-		error(errstring[Ephase]);
-
-	if(perm&DMDIR &&
-		allocdentries(3, iobufs, qpath+1) < 3)
-		error(errstring[Efull]);
 	cbuf->d->qpath = cbuf->d->path = qpath;
 
 	dchild = cbuf->d;
@@ -824,11 +821,6 @@
 	dchild->uid = dchild->muid = aux->uid;
 	dchild->gid = dparent->gid;
 	dchild->version = 0;
-	if(perm&DMDIR){
-		dchild->mode = DMDIR | (perm & (~0777 | (dparent->mode & 0777)));
-		newnames(dchild, aux->uid, blkno, iobufs);
-	}else
-		dchild->mode = perm & (~0666 | (dparent->mode & 0666));
 
 	/* TODO DMAPPEND attributes? */
 	if(perm&DMAPPEND)
@@ -835,7 +827,7 @@
 		dchild->mode |= DMAPPEND;
 	if(perm&DMEXCL)
 		dchild->mode |= DMEXCL;
-	fid->qid = (Qid){dchild->path, 0, (perm&DMDIR) ? QTDIR : QTFILE};
+	qid = (Qid){dchild->path, 0, (perm&DMDIR) ? QTDIR : QTFILE};
 	aux->dblkno = cbuf->blkno;
 	aux->pdblkno = dchild->pdblkno;
 	aux->pqpath = dchild->pqpath;
@@ -858,8 +850,35 @@
 		aux->tlocked = 1;
 	}else
 		aux->tlocked = 0;
-	req->ofcall.qid = fid->qid;
+	if(perm&DMDIR){
+		if(allocdentries(3, iobufs, qpath+1) < 3)
+			error(errstring[Efull]);
+		if(waserror()){
+			truncatefile(iobufs[0]->d->qpath, iobufs[0]->blkno, aux->uid);
+			truncatefile(iobufs[1]->d->qpath, iobufs[1]->blkno, aux->uid);
+			truncatefile(iobufs[2]->d->qpath, iobufs[2]->blkno, aux->uid);
+			nexterror();
+		}
+		dchild->mode = DMDIR | (perm & (~0777 | (dparent->mode & 0777)));
+		newnames(dchild, aux->uid, cbuf->blkno, iobufs);
+	}else
+		dchild->mode = perm & (~0666 | (dparent->mode & 0666));
+	if(blkno == 0){
+		blkno = cbuf->blkno; USED(blkno);
+		/* only add it to the directory dentry if we are adding a new dentry block
+			if we are reusing a zero'ed out slot, it already exists in the
+			directory dentry */
+		addrelative(dparent, dbuf->blkno, reli, cbuf->blkno);
+		if(addname(dparent, aux->uid, reli, req->ifcall.name) == 0)
+			error(errstring[Ephase]);
+	}else if(updatename(dparent, aux->uid, reli, req->ifcall.name) == 0)
+		error(errstring[Ephase]);
+
+	fid->qid = qid;
+	req->ofcall.qid = qid;
 	req->ofcall.iounit = Iounit;
+	if(perm&DMDIR)
+		poperror();
 	poperror();
 	putbuf(cbuf, 1);	/* save Iobuf of the content */
 	poperror();
@@ -1481,7 +1500,7 @@
 		if(buf->len == Maxdatablockunits)
 			datablocksize = Maxdatablocksize;
 		else
-			datablocksize = buf->len*Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */);
+			datablocksize = buf->io->len*Blocksize -Ddataidssize;
 		n = min(datablocksize-((offset+sent)%Maxdatablocksize), tosend-sent);
 		memcpy(rbuf+sent, buf->io->buf+((offset+sent)%Maxdatablocksize), n);
 		sent += n;
@@ -1523,15 +1542,11 @@
 		nblocks = nlastdatablocks(d->size);
 		nblockssize = nblocks*Blocksize -Ddataidssize;
 	}
+
 	oldbuf = egetbufchk(oldblkno, nblocks, Bwritable, Tdata, d->path, getcallerpc(&d));
 
-	/* update with the new contents */
-	to = offset%Maxdatablocksize;
-	howmuch = min(nblockssize-to, wbufsize);
-	memcpy(oldbuf->io->buf+to, wbuf, howmuch);
-
 	/* allocate new blocks to copy on write */
-	newbuf = allocblocks(nblocks,Tdata, d->path);
+	newbuf = allocblocks(nblocks, Tdata, d->path);
 	newblkno = newbuf->blkno;
 	newbuf->io->dblkno = dblkno;
 	newbuf->io->flags = d->flags;
@@ -1541,7 +1556,17 @@
 	}
 
 	/* put the old contents in these new blocks */
-	memcpy(newbuf->io->buf, oldbuf->io->buf, nblocks*Blocksize);
+	if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64) < newbuf->io->buf+nblockssize)
+		panic("update put old contents in new blocks overstepping the bounds");
+	memcpy(newbuf->io->buf, oldbuf->io->buf, nblockssize);
+
+	/* update with the new contents */
+	to = offset%Maxdatablocksize;
+	howmuch = min(nblockssize-to, wbufsize);
+	if(oldbuf->xiobuf+(oldbuf->io->len*Blocksize)-sizeof(u64) < oldbuf->io->buf+to+howmuch)
+		panic("update with new contents overstepping the bounds");
+	memcpy(oldbuf->io->buf+to, wbuf, howmuch);
+
 	putbuf(newbuf, 1);
 
 	/* add the newly allocated blocks to the Dentry */
@@ -1580,6 +1605,8 @@
 		}
 
 		/* add the contents of append to those new blocks */
+		if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64) < newbuf->io->buf+Maxdatablocksize)
+			panic("writefullappend contents overstepping the bounds");
 		memcpy(newbuf->io->buf, dbuf->append, Maxdatablocksize);
 
 		putbuf(newbuf, 1);
@@ -1617,6 +1644,8 @@
 			oldblkno = rel2abs(d, d->size/Maxdatablocksize);
 			oldbuf = egetbufchk(oldblkno, nlastdatablocks(lastdatablksize),
 								Bwritable, Tdata, d->path, getcallerpc(&dbuf));
+			if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64) < newbuf->io->buf+lastdatablksize)
+				panic("writefullappend last block overstepping the bounds");
 			memcpy(newbuf->io->buf, oldbuf->io->buf, lastdatablksize);
 			newbufsize = lastdatablksize;
 		}
@@ -1623,6 +1652,8 @@
 
 		/* add the contents of append to those new blocks */
 		howmuch = Maxdatablocksize-newbufsize;
+		if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64) < newbuf->io->buf+newbufsize+howmuch)
+			panic("writefullappend contents overstepping the bounds");
 		memcpy(newbuf->io->buf+newbufsize, dbuf->append, howmuch);
 
 		/* move the left over append stuff to the front */
@@ -1690,6 +1721,9 @@
 		}
 
 		/* add the contents of append to those new blocks */
+		if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64)
+			 < newbuf->io->buf+dbuf->appendsize)
+			panic("writeallappend contents overstepping the bounds");
 		memcpy(newbuf->io->buf, dbuf->append, dbuf->appendsize);
 
 		putbuf(newbuf, 1);
@@ -1726,6 +1760,9 @@
 			freeblocks(newblkno, newblocks, Tdata, d->path);
 			return -1;
 		}
+		if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64)
+			 < newbuf->io->buf+lastdatablksize)
+			panic("writeallappend last block overstepping the bounds");
 		memcpy(newbuf->io->buf, oldbuf->io->buf, lastdatablksize);
 		newbufsize = lastdatablksize;
 	}
@@ -1732,6 +1769,9 @@
 
 	/* add the contents of append to those new blocks */
 	/* writefullappend() takes care of bigger sizes */
+	if(newbuf->xiobuf+(newbuf->io->len*Blocksize)-sizeof(u64)
+		 < newbuf->io->buf+newbufsize+dbuf->appendsize)
+		panic("writeallappend add overstepping the bounds");
 	memcpy(newbuf->io->buf+newbufsize, dbuf->append, dbuf->appendsize);
 	newbuf->io->len = newblocks;
 
@@ -1787,6 +1827,9 @@
 
 	// little data, stuff it in the Dentry
 	if(d->size+dbuf->appendsize<=Ddatasize && offset+wbufsize <= Ddatasize){
+		if(dbuf->xiobuf+(dbuf->io->len*Blocksize)-sizeof(u64)
+			 < (u8*)dbuf->d->buf+offset+wbufsize)
+			panic("writefile little data overstepping the bounds");
 		memcpy(d->buf+offset, wbuf, wbufsize);
 		if(offset+wbufsize > d->size)
 			d->size = offset+wbufsize;
--- a/blk.c
+++ b/blk.c
@@ -60,7 +60,7 @@
 		showmagic(fd, buf);
 	else if(d->size <= Ddatasize && (d->mode&DMDIR) == 0 &&
 			d->path != Qproot0){
-		if(d->preli == 0 && d->flags&~Fsys == Fn){
+		if(d->preli == 0 && (d->flags&~Fsys) == Fn){
 			for(i = 0; i < d->size/sizeof(Name); i++){
 				nm = (Name*)d->buf+i;
 				fprint(fd, "%llud %hud ", i, nm->namelen);
--- a/custom.acid
+++ b/custom.acid
@@ -2,29 +2,33 @@
 include("../libextents/extents.acid");
 
 defn
-Qid9p1(addr) {
-	complex Qid9p1 addr;
-	print("	version	", addr.version\X, "\n");
-	print("	path	", addr.path\Z, "\n");
+Dentryhdr1(addr) {
+	complex Dentryhdr addr;
+	print("	tag	", addr.tag, "\n");
+	print("	flags	", addr.flags, "\n");
+	print("	uid	", addr.uid\d, "\n");
+	print("	gid	", addr.gid\d, "\n");
+	print("	muid	", addr.muid\d, "\n");
+	print("	size	", addr.size\Z, "\n");
+	print("	pdblkno	", addr.pdblkno\Z, "\n");
+	print("	pqpath	", addr.pqpath\Z, "\n");
+	print("	preli	", addr.preli\Z, "\n");
+	print("	mtime	", addr.mtime\Z, "\n");
+	print("	qpath	", addr.qpath\Z, "\n");
+	print("	version	", addr.version\D, "\n");
+	print("	mode	", addr.mode\O, " ", addr.mode\X, "\n");
 };
 
 defn
-Dentry1(addr) {
-	complex Dentry1 addr;
+Dentry(addr) {
+	complex Dentry addr;
 	local i;
 
-	i = 0;
-	print("Qid9p1 qid {\n");
-	Qid9p1(addr.qid);
+	print("Dentryhdr {\n");
+		Dentryhdr1(addr);
 	print("}\n");
-	print("	size	", addr.size\Z, "\n");
-	print("	pdblkno	", addr.pdblkno\Z, "\n");
-	print("	pqpath	", addr.pqpath\Z, "\n");
-	print("	mtime	", addr.mtime\Z, "\n");
-	print("	mode	", addr.mode\O, "\n");
-	print("	uid	", addr.uid\d, "\n");
-	print("	gid	", addr.gid\d, "\n");
-	print("	muid	", addr.muid\d, "\n");
+
+	i = 0;
 	print("	dblocks	", addr.dblocks, "\n");
 	loop 1, Ndblock do {
 		print(i\d, ": ", addr.dblocks[i]\Z , "\n");
@@ -35,18 +39,10 @@
 		print(i\d, ": ", addr.iblocks[i]\Z , "\n");
 		i = i+1;
 	}
+	print("	path	", addr.path\Z, "\n");
 };
 
 defn
-Dentry(addr) {
-	complex Dentry addr;
-	print("Dentry1 {\n");
-		Dentry1(addr+0);
-	print("}\n");
-	print("	name	", *(addr.name\s), "\n");
-};
-
-defn
 Showextentpointers(addr) {
 	complex Extent addr;
 	local start, len;
@@ -81,9 +77,13 @@
 	complex Extent addr;
 	local start, len;
 
-	start = addr.start\Z;
-	len = addr.len\Z;
-	print(start\Z, " ", (start+len-1)\Z," ", len\Z, " ", addr\Y);
+	if addr == 0 then {
+		print("nil");
+	}else{
+		start = addr.start\Z;
+		len = addr.len\Z;
+		print(start\Z, " ", (start+len-1)\Z," ", len\Z, " ", addr\Y);
+	}
 };
 
 defn
@@ -90,7 +90,6 @@
 Showextents(addr) {
 	complex Extents addr;
 	complex Extent eaddr;
-	complex Extent lru;
 	complex Extent elow;
 
 	print(*(addr.name\s), " n ", addr.n\Z,
@@ -102,19 +101,20 @@
 	while eaddr != 0 do {
 		Showextent(eaddr);
 		print("\n");
-		eaddr = eaddr.high;
+		eaddr = ((Extent)eaddr).high;
 	}
 	print("by size:\n");
 	eaddr = addr.lowest;
+	elow = addr.lowest;
 	while eaddr != 0 do {
-		elow = eaddr;
-		eaddr = eaddr.small;
+		elow = ((Extent)eaddr);
+		eaddr = ((Extent)eaddr).small;
 	}
 	eaddr = elow;
 	while eaddr != 0 do {
 		Showextent(eaddr);
 		print("\n");
-		eaddr = eaddr.big;
+		eaddr = ((Extent)eaddr).big;
 	}
 	print("lru:\n");
 	eaddr = addr.lru;
@@ -121,11 +121,11 @@
 	if eaddr != 0 then {
 		Showextent(eaddr);
 		print("\n");
-		eaddr = eaddr.next;
+		eaddr = ((Extent)eaddr).next;
 		while eaddr != addr.lru do {
 			Showextent(eaddr);
 			print("\n");
-			eaddr = eaddr.next;
+			eaddr = ((Extent)eaddr).next;
 		}
 	}
 };
@@ -133,4 +133,10 @@
 defn
 Es(addr) {
 	Showextents(addr);
+};
+
+defn
+E(addr) {
+	Showextent(addr);
+	print("\n");
 };
--- a/dat.c
+++ b/dat.c
@@ -29,6 +29,7 @@
 	[Echar]		"bad character in directory name",
 	[Econvert]	"protocol botch",
 	[Ecount]	"read/write -- count too big",
+	[Edexist]	"create -- directory exists",
 	[Edir1]		"walk -- in a non-directory",
 	[Edir2]		"create -- in a non-directory",
 	[Edirty]	"dirty filesystem",
--- a/dat.h
+++ b/dat.h
@@ -319,6 +319,7 @@
 	Echar,
 	Econvert,
 	Ecount,
+	Edexist,
 	Edir1,
 	Edir2,
 	Edirty,
--- a/dentry.c
+++ b/dentry.c
@@ -486,7 +486,7 @@
 
 	/* writing the actual extents now */
 	truncatefile(qpath, blkno, uid);
-	writefile(blkno, qpath, uid, buf, nbuf, 0);
+	writefile(blkno, qpath, uid, buf, nbuf+1, 0);
 	free(buf);
 }
 
--- a/docs/mafs.ms
+++ b/docs/mafs.ms
@@ -1466,6 +1466,7 @@
 	touch /n/ramfs/file
 	dd -if /dev/zero -of /n/ramfs/file -count 1k -bs 2m
 
+	cd
 	disk/mafs -r mafs_ramfs_file /n/ramfs/file
 	mount -c /srv/mafs_ramfs_file /n/mafs_ramfs_file
 	cd /n/mafs_ramfs_file
@@ -1472,6 +1473,8 @@
 	time dd -if /dev/zero -of /n/mafs_ramfs_file/file -count 500 -bs 1m
 	time dd -if /n/mafs_ramfs_file/file -of /dev/null -count 500 -bs 1m
 	rm /n/mafs_ramfs_file/file
+	mkdir /n/mafs_ramfs_file/plan9front
+	time clone -p 20:80 /dist/plan9front ./plan9front # kvik's clone which transfers in parallel
 	time git/clone /dist/plan9front
 	time walk plan9front >/dev/null
 	time cat `{walk plan9front}>/dev/null
@@ -1523,6 +1526,8 @@
 85.92u 33.49s 175.44r 	 git/clone /dist/plan9front
 : mafs_ramfs_file ; 	time walk plan9front >/dev/null
 0.12u 0.28s 4.40r 	 walk plan9front
+: mafs_ramfs_file ; 	time cat `{walk plan9front}>/dev/null
+0.08u 2.02s 27.96r 	 cat plan9front/.git/fs plan9front/.git/objects/pack/bbf8e5461ce218a8b35073482679f457f2df8c7a.pack plan9front/.git/objects/pack/bbf8e5461ce218a8b35073482679f457f2df8c7a.idx plan9front/.git/objects/pack ...
 : mafs_ramfs_file ; 	time du -sh plan9front
 302.097M	plan9front
 0.06u 0.34s 4.84r 	 du -sh plan9front
--- a/iobuf.c
+++ b/iobuf.c
@@ -61,10 +61,8 @@
 	u32 n;
 	char locked[32];
 	u8 tag;
-	char *name;
-	u16 namelen;
-	Iobuf *pdbuf;
-	Dentry *pd;
+//	char *name;
+//	u16 namelen;
 
 	if(p == nil)
 		return 0;
@@ -74,8 +72,6 @@
 		wunlock(p);
 	}else
 		strcpy(locked, "locked");
-	name = nil;
-	namelen = 0;
 	if(p->tag == Tdata)
 		n = snprint(buf, nbuf, "%s %llud %s\n",
 					tagnames[p->tag], p->blkno, locked);
@@ -605,29 +601,47 @@
 checktag(Iobuf *p, u16 len, u8 tag, u64 qpath)
 {
 	uintptr pc;
-	u16 buftag;
+	u8 buftag;
 	u64 bufqpath;
 
-	if(tag == Tdata){
-		buftag = p->io->tag;
-		bufqpath = p->xiobuf64[p->len*Nu64perblock -1];
-	}else{
-		buftag = p->d->tag;
-		bufqpath = p->d->path;
-	}
+	buftag = p->xiobuf[0];
+	bufqpath = p->xiobuf64[p->len*Nu64perblock -1];
 
+	if(tag == Tdata &&
+		len != p->io->len){
+		pc = getcallerpc(&p);
+		dprint("checktag Tdata len failed: p->blkno %llud:"
+				" actual p->len %hud p->io->len %hud tag/path %G/%llud;"
+				" expected len %hud tag/path %G/%llud\n",
+				p->blkno,
+				p->len, p->io->len, buftag, bufqpath,
+				len, tag, qpath);
+		dprint("checktag Tdata len failed: pc=%p disk %s(block %llud)"
+				" p->len %hud p->io->len %hud tag/path=%s/%llud;"
+				" expected len %hud tag/path=%s/%llud\n",
+				pc, devfile, p->blkno,
+				p->len, p->io->len, tagnames[buftag], bufqpath,
+				len, tagnames[tag], qpath);
+		panic("checktag failed\n");
+		error(errstring[Ephase]); // use a better error message
+	}
 	if(len != p->len ||
 		tag != buftag ||
 		qpath != bufqpath){
 		pc = getcallerpc(&p);
 
-		dprint("checktag blkno %llud tag/path = %G/%llud; expected %G/%llud\n",
-				(uint)buftag, bufqpath, tag, qpath);
-		dprint("checktag pc=%p disk %s(block %llud) tag/path=%s/%llud;"
-				" expected %s/%llud\n",
+		dprint("checktag p->blkno %llud:"
+				" actual len %hud tag/path %G/%llud;"
+				" expected len %hud tag/path %G/%llud\n",
+				p->blkno,
+				p->len, buftag, bufqpath,
+				len, tag, qpath);
+		dprint("checktag pc=%p disk %s(block %llud)"
+				" len %hud tag/path=%s/%llud;"
+				" expected len %hud tag/path=%s/%llud\n",
 				pc, devfile, p->blkno,
-				tagnames[buftag], bufqpath,
-				tagnames[tag], qpath);
+				p->len, tagnames[buftag], bufqpath,
+				len, tagnames[tag], qpath);
 		panic("checktag failed\n");
 		error(errstring[Ephase]);
 		return 0;
@@ -644,14 +658,9 @@
 	if(p->io == nil)
 		panic("settag %s(%llux) tag/path=%s/%llud: p->io == nil\n",
 				devfile, (u64)p->blkno, tagnames[tag], qpath);
-	if(tag == Tdata){
-		p->io->tag = Tdata;
-		p->xiobuf64[p->len*Nu64perblock -1] = qpath;
-	}else{
-		p->d->tag = tag;
-		p->d->path = qpath;
-	}
-	p->tag = tag;
+
+	p->tag = p->xiobuf[0] = tag;
+	p->xiobuf64[p->len*Nu64perblock -1] = qpath;
 }
 
 void *amalloc(u64 n){
--- a/names.c
+++ b/names.c
@@ -9,8 +9,13 @@
 	Name nm;
 
 	/* is this valid? */
-	if(d == nil || searchname == nil || relip == nil)
-		panic("searchnames: should not be happening");
+	if(d == nil || searchname == nil || relip == nil ||
+		d->dblocks[In] == 0 || d->dblocks[Inl] == 0 ||
+		d->dblocks[Inle] == 0){
+		showdentry(2, (u8*)d);
+		panic("searchnames: should not be happening. searchname %s *relip %llud\n",
+				searchname, *relip);
+	}
 
 	searchnamelen = strlen(searchname);
 	if(searchnamelen == 0)
@@ -133,7 +138,7 @@
 			freeextents(nes);
 			nexterror();
 		}
-		snprint(esname, 32, "%llud", pd->qpath);
+		snprint(esname, 32, ".nle block %llud", pd->dblocks[Inle]);
 		initextents(nes, esname, 0, 0, 2, nil, dprintfd, panic, malloc9p);
 		loadextentsfile(pd->dblocks[Inle], pd->qpath+1+Inle, nes);
 		ufree(nes, nm.noffset, nm.namelen);
@@ -155,6 +160,8 @@
 	u64 start, size;
 	Name nm;
 
+//	dprint("addnamelen name %s len %d to In %llud Inl %llud preli %llud\n",
+//			name, namelen, pd->dblocks[In], pd->dblocks[Inl], preli);
 	nm.namelen = namelen;
 	strncpy(nm.name, name, Nfirst);
 	if(nm.namelen <= Nfirst){
@@ -170,7 +177,7 @@
 		freeextents(nes);
 		nexterror();
 	}
-	snprint(esname, 32, "%llud", pd->qpath);
+	snprint(esname, 32, ".nle block %llud", pd->dblocks[Inle]);
 	initextents(nes, esname, 0, 0, 2, nil, dprintfd, panic, malloc9p);
 	loadextentsfile(pd->dblocks[Inle], pd->qpath+1+Inle, nes);
 
@@ -206,6 +213,8 @@
 	u16 newlen, n;
 	Name nm;
 
+//	dprint("updatename name %s to In %llud Inl %llud preli %llud\n",
+//		name, pd->dblocks[In], pd->dblocks[Inl], preli);
 	/* if the namelen matches with the existing, change in-place */
 	newlen = strlen(name);
 	n = readfile(pd->dblocks[In], pd->qpath+1+In, (s8*)&nm, sizeof(Name), preli*sizeof(Name));
--- a/sub.c
+++ b/sub.c
@@ -266,6 +266,7 @@
 	b = egetmeta(Bdrootnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qprootnames);
 	d = b->d;
+	d->flags = Fsys|Fn;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -282,6 +283,7 @@
 	b = egetmeta(Bdrootlnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qprootlnames);
 	d = b->d;
+	d->flags = Fsys;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -298,6 +300,7 @@
 	b = egetmeta(Bdrootlnamesextents, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qprootlnamesextents);
 	d = b->d;
+	d->flags = Fsys|Fe;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -338,6 +341,7 @@
 	b = egetmeta(Bdanames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpanames);
 	d = b->d;
+	d->flags = Fsys|Fn;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -354,6 +358,7 @@
 	b = egetmeta(Bdalnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpalnames);
 	d = b->d;
+	d->flags = Fsys;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -370,6 +375,7 @@
 	b = egetmeta(Bdalnamesextents, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpalnamesextents);
 	d = b->d;
+	d->flags = Fsys|Fe;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -422,6 +428,7 @@
 	b = egetmeta(Bdbkpnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpbkpnames);
 	d = b->d;
+	d->flags = Fsys|Fn;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -438,6 +445,7 @@
 	b = egetmeta(Bdbkplnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpbkplnames);
 	d = b->d;
+	d->flags = Fsys;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -454,6 +462,7 @@
 	b = egetmeta(Bdbkplnamesextents, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpbkplnamesextents);
 	d = b->d;
+	d->flags = Fsys|Fe;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -501,6 +510,7 @@
 	b = egetmeta(Bdusersnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpusersnames);
 	d = b->d;
+	d->flags = Fsys|Fn;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -517,6 +527,7 @@
 	b = egetmeta(Bduserslnames, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpuserslnames);
 	d = b->d;
+	d->flags = Fsys;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |
@@ -533,6 +544,7 @@
 	b = egetmeta(Bduserslnamesextents, Bwritable, Bfreshalloc);
 	settag(b, Tdentry, Qpuserslnamesextents);
 	d = b->d;
+	d->flags = Fsys|Fe;
 	d->uid = d->muid = d->gid = -1;
 	d->mode =
 		((DMREAD) << 6) |