shithub: riscv

Download patch

ref: 159f96c534563f26edeeb227cd00f1bdd3bd2596
parent: 8561a843070582d48ef7f99e1138941c3509975f
author: cinap_lenrek <[email protected]>
date: Wed Jun 19 18:58:16 EDT 2019

cwfs: properly handle 64 bit qid path

for historical reasons, kenfs stores directory entries in pre 9p2000
format with directories having the QPDIR bit 31 set in the qid path.

however, the 64 bit fileserver allows 64 bit qid paths.

given that we do not support pre 9p2000 clients and do not rely on
the QPDIR, but want to keep the block check tags consistent, we will
*INVERT* the QPDIR bit in directory entry qid paths for directories.

this preserves the on-disk semantics (for < 31 bit qmax) but does
not complicate qid generation and recovery. also makes it easy to
convert between directory entry qid and 9p format.

--- a/sys/src/cmd/cwfs/9p2.c
+++ b/sys/src/cmd/cwfs/9p2.c
@@ -27,11 +27,9 @@
 void
 mkqid9p1(Qid9p1* qid9p1, Qid* qid)
 {
-	if(qid->path & 0xFFFFFFFF00000000LL)
-		panic("mkqid9p1: path %lluX", (Wideoff)qid->path);
-	qid9p1->path = qid->path & 0xFFFFFFFF;
+	qid9p1->path = qid->path;
 	if(qid->type & QTDIR)
-		qid9p1->path |= QPDIR;
+		qid9p1->path ^= QPDIR;
 	qid9p1->version = qid->vers;
 }
 
@@ -74,7 +72,9 @@
 void
 mkqid9p2(Qid* qid, Qid9p1* qid9p1, int mode9p1)
 {
-	qid->path = (ulong)(qid9p1->path & ~QPDIR);
+	qid->path = qid9p1->path;
+	if(mode9p1 & DDIR)
+		qid->path ^= QPDIR;
 	qid->vers = qid9p1->version;
 	qid->type = mktype9p2(mode9p1);
 }
@@ -399,7 +399,7 @@
 	Iobuf *p, *p1;
 	Dentry *d, *d1;
 	int error, slot, mask;
-	Off addr, qpath;
+	Off addr;
 
 	p = p1 = nil;
 
@@ -482,10 +482,9 @@
 				goto out;
 			}
 		}
-		qpath = d->qid.path;
 		p1 = dnodebuf1(p, d, addr, 0, file->uid);
 		p = nil;
-		if(p1 == nil || checktag(p1, Tdir, qpath)){
+		if(p1 == nil || checktag(p1, Tdir, d->qid.path ^ QPDIR)){
 			error = Eentry;
 			goto out;
 		}
@@ -854,7 +853,7 @@
 			error = Efull;
 			goto out;
 		}
-		if(checktag(p1, Tdir, d->qid.path)){
+		if(checktag(p1, Tdir, d->qid.path ^ QPDIR)){
 			putbuf(p1);
 			goto phase;
 		}
@@ -904,7 +903,7 @@
 	if((p1 = getbuf(file->fs->dev, addr1, Brd|Bimm|Bmod)) == nil)
 		goto phase;
 	d1 = getdir(p1, slot1);
-	if(d1 == nil || checktag(p1, Tdir, d->qid.path)) {
+	if(d1 == nil || checktag(p1, Tdir, d->qid.path ^ QPDIR)) {
 		putbuf(p1);
 		goto phase;
 	}
@@ -929,7 +928,7 @@
 	d1->mode = DALLOC | (f->perm & 0777);
 	if(f->perm & DMDIR) {
 		d1->mode |= DDIR;
-		d1->qid.path |= QPDIR;
+		d1->qid.path ^= QPDIR;
 	}
 	if(f->perm & DMAPPEND)
 		d1->mode |= DAPND;
@@ -1359,7 +1358,7 @@
 		p1 = dnodebuf(p, d, addr, 0, f->uid);
 		if(!p1)
 			break;
-		if(checktag(p1, Tdir, d->qid.path)) {
+		if(checktag(p1, Tdir, d->qid.path ^ QPDIR)) {
 			err = Ephase;
 			goto out;
 		}
@@ -1688,7 +1687,7 @@
 		for(addr = 0; ; addr++){
 			if((p = dnodebuf(p1, d1, addr, 0, file->uid)) == nil)
 				break;
-			if(checktag(p, Tdir, d1->qid.path)){
+			if(checktag(p, Tdir, d1->qid.path ^ QPDIR)){
 				putbuf(p);
 				continue;
 			}
--- a/sys/src/cmd/cwfs/chk.c
+++ b/sys/src/cmd/cwfs/chk.c
@@ -430,7 +430,9 @@
 	}
 
 	/* check qid */
-	edent.qpath = d->qid.path & ~QPDIR;
+	edent.qpath = d->qid.path;
+	if(d->mode & DDIR)
+		edent.qpath ^= QPDIR;
 	qmark(edent.qpath);
 	if(edent.qpath > maxq)
 		maxq = edent.qpath;
--- a/sys/src/cmd/cwfs/con.c
+++ b/sys/src/cmd/cwfs/con.c
@@ -513,8 +513,10 @@
 	mod = 0;
 	qpath = d->qid.path;
 	typ = Tfile;
-	if(d->mode & DDIR)
+	if(d->mode & DDIR){
+		qpath ^= QPDIR;
 		typ = Tdir;
+	}
 	for(i=0; i<NDBLOCK; i++) {
 		print("dblock[%d] = %lld\n", i, (Wideoff)d->dblock[i]);
 		ckblock(p->dev, d->dblock[i], typ, qpath);
--- a/sys/src/cmd/cwfs/cw.c
+++ b/sys/src/cmd/cwfs/cw.c
@@ -1311,11 +1311,11 @@
 }
 
 Off
-cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp)
+cwrecur(Cw *cw, Off addr, int tag, int tag1, Off qp)
 {
 	Iobuf *p;
 	Dentry *d;
-	long qp1;
+	Off qp1;
 	int i, j, shouldstop;
 	Off na;
 	char *np;
@@ -1373,14 +1373,16 @@
 			d = getdir(p, i);
 			if((d->mode & (DALLOC|DTMP)) != DALLOC)
 				continue;
-			qp1 = d->qid.path & ~QPDIR;
 			if(np)
 				strncpy(np, d->name, NAMELEN);
 			else if(i > 0)
 				fprint(2, "cwrecur: root with >1 directory\n");
+			qp1 = d->qid.path;
 			tag1 = Tfile;
-			if(d->mode & DDIR)
+			if(d->mode & DDIR){
+				qp1 ^= QPDIR;
 				tag1 = Tdir;
+			}
 			for(j=0; j<NDBLOCK; j++) {
 				na = d->dblock[j];
 				if(na) {
--- a/sys/src/cmd/cwfs/dentry.c
+++ b/sys/src/cmd/cwfs/dentry.c
@@ -65,6 +65,8 @@
 	}
 	dev = p->dev;
 	qpath = d->qid.path;
+	if(d->mode & DDIR)
+		qpath ^= QPDIR;
 
 	/* is `a' a direct block? */
 	if(a < NDBLOCK) {
--- a/sys/src/cmd/cwfs/iobuf.c
+++ b/sys/src/cmd/cwfs/iobuf.c
@@ -201,19 +201,18 @@
 checktag(Iobuf *p, int tag, Off qpath)
 {
 	Tag *t;
-	ulong pc;
+	uintptr pc;
 
-	qpath &= ~QPDIR;
 	t = (Tag*)(p->iobuf+BUFSIZE);
-	if((tag != t->tag) || ((qpath != QPNONE) && (qpath != t->path))){
+	if(tag != t->tag || qpath != QPNONE && qpath != t->path){
 		pc = getcallerpc(&p);
 
 		if(qpath == QPNONE){
-			fprint(2, "checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G\n",
+			fprint(2, "checktag pc=%p %Z(%llux) tag/path=%G/%llud; expected %G\n",
 				pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag);
 		} else {
-			fprint(2, "checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n",
-				pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, qpath);
+			fprint(2, "checktag pc=%p %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n",
+				pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath);
 		}
 		return 1;
 	}	
@@ -221,7 +220,7 @@
 }
 
 void
-settag(Iobuf *p, int tag, long qpath)
+settag(Iobuf *p, int tag, Off qpath)
 {
 	Tag *t;
 
@@ -228,7 +227,7 @@
 	t = (Tag*)(p->iobuf+BUFSIZE);
 	t->tag = tag;
 	if(qpath != QPNONE)
-		t->path = qpath & ~QPDIR;
+		t->path = qpath;
 	p->flags |= Bmod;
 }
 
--- a/sys/src/cmd/cwfs/portfns.h
+++ b/sys/src/cmd/cwfs/portfns.h
@@ -160,7 +160,7 @@
 void	fs_send(Queue*, void*);
 void	serve(void *);
 int	serve9p2(Msgbuf*);
-void	settag(Iobuf*, int, long);
+void	settag(Iobuf*, int, Off);
 int	strtouid(char*);
 Off	superaddr(Device*);
 void	superream(Device*, Off);
--- a/sys/src/cmd/cwfs/sub.c
+++ b/sys/src/cmd/cwfs/sub.c
@@ -380,8 +380,9 @@
 	if(!p || checktag(p, Tsuper, QPSUPER))
 		panic("newqid: super block");
 	sb = (Superb*)p->iobuf;
-	sb->qidgen++;
-	path = sb->qidgen;
+	do {
+		path = ++sb->qidgen;
+	} while(path == QPDIR);
 	putbuf(p);
 	return path;
 }