code: mafs

Download patch

ref: 9699d5434fadf3d775757f3d037a0f1cf86bbf75
parent: 264f5a53b0c6e8ad5ed23a8ad89f0379fcc9f0fd
author: 9ferno <gophone2015@gmail.com>
date: Wed Nov 30 09:15:25 EST 2022

fixed bugs in the Tdata trailing path

--- a/all.h
+++ b/all.h
@@ -82,6 +82,7 @@
 	Iobuf *back;	/* for lru */
 	union{
 		u8	*xiobuf;	/* "real" buffer pointer */
+		u64	*xiobuf64;
 		Data *io;
 		Metadata *m;
 	};
--- a/blk.c
+++ b/blk.c
@@ -105,7 +105,8 @@
 		showdentry(fd, buf);
 		return;
 	}else if(tag == Tdata){
-		fprint(fd, "%s %llud %llud %d\n", tagnames[tag], t->path, t->dblkno, t->len);
+		fprint(fd, "%s %llud %llud %d\n",
+			tagnames[tag], ((u64*)buf)[t->len*Nu64perblock -1], t->dblkno, t->len);
 		showdata(fd, buf);
 		return;
 	}else if(tag < Maxtind)
--- a/block.c
+++ b/block.c
@@ -18,8 +18,10 @@
 void
 main(int argc, char *argv[])
 {
+	u8 tag;
 	u64 size, blkno;
-	u8 buf[Blocksize+1];
+	u8 buf[Maxdatablocksize];
+	Data *da;
 
 	ARGBEGIN{
 	default:	usage();
@@ -50,7 +52,13 @@
 	// nunits = size/Blocksize;
 	memset(buf, 0, Blocksize);
 	devread(blkno, buf, 1);
-	showblock(1, buf);
+	tag = buf[0];
+	if(tag == Tdata){
+		da = (Data*)buf;
+		devread(blkno, buf, da->len);
+		showblock(1, buf);
+	}else
+		showblock(1, buf);
 	close(devfd);
 	exits(0);
 }
--- a/dat.h
+++ b/dat.h
@@ -59,6 +59,8 @@
 
 	Maxdatablockunits = 2048,
 	Nindperblock= (Blocksize-3*sizeof(u64))/sizeof(u64),/* number of pointers per block */
+	Nu64perblock= (Blocksize/sizeof(u64)),		/* number of u64's in a block */
+	Dpathidx	= (Blocksize/sizeof(u64) -1),	/* index of path in the last data block, last u64 */
 
 	Namelen = 127,	/* maximum length of a file name, calculated manually */
 	Ndblock	= 32,	/* number of direct blocks in a Dentry */
@@ -142,13 +144,13 @@
 	u8 unused;	/* for alignment and future use */
 	u16 len;
 	u64 dblkno;	/* block number of the directory entry */
-	u64 path;	/* same as qid.path */
+	// u64 path;	/* same as qid.path */
 };
 #pragma pack off
 
 enum {
 	/* max possible size of data that can be stuffed into a Dentry */
-	Ddatasize = Blocksize -sizeof(u64 /* path */) -sizeof(Dentryhdr),
+	Ddatasize = Blocksize -sizeof(Dentryhdr) -sizeof(u64 /* trailing path */),
 	Maxdatablocksize = Maxdatablockunits*Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */),
 };
 
@@ -208,7 +210,7 @@
 {
 	Datahdr;
 	u8 buf[1];	/* upto Maxdatablocksize, followed by u64 qid.path */
-	/* u64 path; same as qid.path at the end of the data content */
+	/* u64 path; same as qid.path at the end of the data content - check consistency */
 };
 #pragma pack off
 
--- a/find.c
+++ b/find.c
@@ -197,12 +197,12 @@
 
 /* returns 0 for invalid, 1 for valid blocks */
 u8
-checkvalid(u64 blkno, u8 dtag, u64 dpath, u64 dqpath, u8 tag, u64 qpath, u16 len)
+checkvalid(u64 blkno, u8 dtag, u64 dpath, u8 tag, u64 qpath, u16 len)
 {
-	if(dtag != tag || dpath != qpath || dqpath != qpath){
+	if(dtag != tag || dpath != qpath){
 		/* if(debug) */
-			fprint(2, "checkvalid invalid %llud tag/path expected %s/%llud actual %s/%llud %llud\n",
-					blkno, tagnames[tag], qpath, tagnames[dtag], dpath, dqpath);
+			fprint(2, "checkvalid invalid %llud tag/path expected %s/%llud actual %s/%llud\n",
+					blkno, tagnames[tag], qpath, tagnames[dtag], dpath);
 		fprint(2, "invalid used: %llud\n", blkno);
 		return 0;
 	}else if(debug)
@@ -214,9 +214,10 @@
 walkindir(s8 depth, u64 blkno, u8 tag, u8 bottomtag, u64 qpath)
 {
 	u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+	u64 ebuf[Nu64perblock];
 	Indirect *t;
 	Data *ct;
-	u64 cblkno;
+	u64 cblkno, path;
 	int i;
 
 	devread(blkno, buf, Metadataunits);
@@ -236,7 +237,9 @@
 				else{
 					devread(cblkno, cbuf, 1);
 					ct = (Data*)cbuf;
-					if(checkvalid(cblkno, ct->tag, ct->path, bottomtag, qpath, ct->len) &&
+					devread(cblkno+ct->len-1, ebuf, 1);
+					path = ebuf[Dpathidx];
+					if(checkvalid(cblkno, ct->tag, path, bottomtag, qpath, ct->len) &&
 						issearchblock(cblkno, ct->len))
 						return Found;
 				}
@@ -259,10 +262,11 @@
 walkfile(s8 depth, u64 blkno)
 {
 	u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+	u64 ebuf[Nu64perblock];
 	Dentry *d;
 	Data *ct;
 	Indirect *it;
-	u64 cblkno;
+	u64 cblkno, path;
 	int i;
 
 	devread(blkno, buf, Metadataunits);
@@ -290,7 +294,10 @@
 			return Notfound;
 		devread(cblkno, cbuf, 1);
 		ct = (Data*)cbuf;
-		if(checkvalid(cblkno, ct->tag, ct->path, Tdata, d->qpath, ct->len) &&
+		devread(cblkno+ct->len-1, ebuf, 1);
+		path = ebuf[Dpathidx];
+		if(checkvalid(cblkno, ct->tag, path,
+						Tdata, d->qpath, ct->len) &&
 			issearchblock(cblkno, ct->len))
 			return Found;
 	}
--- a/free.c
+++ b/free.c
@@ -89,9 +89,10 @@
 {
 	s8 *buf;
 
-	buf = emalloc(Metadatablocksize);
-	devread(blkno, buf, Metadataunits);
-	loadextents(&frees, buf, Maxdatablocksize);
+	buf = emalloc(Maxdatablocksize);
+	devread(blkno, buf, 1);
+	devread(blkno, buf, ((Data*)buf)->len);
+	loadextents(&frees, buf, ((Data*)buf)->len*Blocksize);
 	free(buf);
 }
 
--- a/iobuf.c
+++ b/iobuf.c
@@ -561,20 +561,19 @@
 {
 	uintptr pc;
 	u16 ptag;
-	u64 pqpath, ppath;
+	u64 pqpath;
 
 	if(tag == Tdata){
 		ptag = p->io->tag;
-		pqpath = p->io->path;
-		ppath = p->xiobuf[len*Blocksize -sizeof(u64)];
+		pqpath = p->xiobuf64[p->len*Nu64perblock -1];
 	}else{
 		ptag = ((Dentry*)p->cur)->tag;
-		pqpath = ppath = ((Dentry*)p->cur)->path;
+		pqpath = ((Dentry*)p->cur)->path;
 	}
 
 	if(len != p->len ||
 		tag != ptag ||
-		(qpath != Qpnone && (pqpath != qpath || ppath != qpath))){
+		(qpath != Qpnone && pqpath != qpath)){
 		pc = getcallerpc(&p);
 
 		dprint("	tag = %G; expected %G; blkno = %llud\n",
@@ -587,12 +586,12 @@
 					tagnames[tag],
 					len, p->len);
 		} else {
-				dprint("	tag/path = %G/%llux %llux; expected %G/%llux\n",
-						(uint)ptag, pqpath, ppath, tag, qpath);
-				dprint("checktag pc=%p disk %s(block %llud) tag/path=%s/%llud %llud;"
+				dprint("	tag/path = %G/%llux; expected %G/%llux\n",
+						(uint)ptag, pqpath, tag, qpath);
+				dprint("checktag pc=%p disk %s(block %llud) tag/path=%s/%llud;"
 						" expected %s/%llud\n",
 						pc, devfile, p->blkno,
-						tagnames[ptag], pqpath, ppath,
+						tagnames[ptag], pqpath,
 						tagnames[tag], qpath);
 				panic("checktag failed\n");
 		}
@@ -612,7 +611,7 @@
 				devfile, (u64)p->blkno, tagnames[tag], qpath);
 	if(tag == Tdata){
 		p->io->tag = Tdata;
-		p->io->path = qpath;
+		p->xiobuf64[p->len*Nu64perblock -1] = qpath;
 	}else{
 		((Dentry*)p->new)->tag = tag;
 		((Dentry*)p->new)->path = qpath;
--- a/sub.c
+++ b/sub.c
@@ -90,7 +90,7 @@
 	memset(buf->xiobuf, 0, len*Blocksize);
 	if(tag == Tdata){
 		buf->io->len = len;
-		buf->xiobuf[len*Blocksize -sizeof(u64)] = qpath;
+		buf->xiobuf64[len*Nu64perblock -1] = qpath;
 	}else
 		recentmetadata(buf->m, &buf->cur, &buf->new);
 	settag(buf, tag, qpath);
--- a/tests/test.2/blocks/24
+++ b/tests/test.2/blocks/24
@@ -43,4 +43,5 @@
 0123456789
 0123456789
 0123456789
-01234567
\ No newline at end of file
+0123456789
+0123456789
--- a/tests/test.2/notes
+++ b/tests/test.2/notes
@@ -2,6 +2,9 @@
 
 Write to a /file1 and update the file using different offsets. Check that the contents match after each addition.
 
+# to see the raw contents of block 24
+dd -if test.2/disk -bs 512 -skip 24 -count 1 | xd -c
+
 block	- description
 0		- magic dir entry and data
 2		- /adm/config dir entry
--- a/tests/testextents.c
+++ b/tests/testextents.c
@@ -37,7 +37,7 @@
 	bp = Bfdopen(0, OREAD);
 	Blethal(bp, nil);
 
-	initextents(&es, "testextents");
+	initextents(&es, "testextents", nil);
 	while((line = Brdstr(bp, '\n', 1)) != nil) {
 		bno = strtoull(line, &p, 10);
 		p++;	/* for the space */
--- a/updatefrees.c
+++ b/updatefrees.c
@@ -9,6 +9,9 @@
 	disk/unused <{disk/used tests/test.0/disk} 32 | tr -d '	' > /mnt/term/tmp/unused.blocks
 	cat /mnt/term/tmp/unused.blocks
 	disk/updatefrees tests/test.0/disk /mnt/term/tmp/unused.blocks
+
+	TODO
+		does not work when the size of free extents > Blocksize-(3*8)
  */
 
 int debug = 0;
@@ -27,8 +30,9 @@
 	u64 size, freeblkno;
 	s32 nfreesize;
 	s8 buf[Metadatablocksize], frees[Maxdatablocksize];
+	u64 freesdata[Nu64perblock];
 	int fd;
-	Data *c;
+	Data *f;
 	Dentry *d;
 
 	ARGBEGIN{
@@ -47,7 +51,7 @@
 	if(freesfile == nil)
 		sysfatal("no frees file");
 
-	memset(buf,0,Metadatablocksize);
+	memset(buf, 0, Metadatablocksize);
 	memset(frees, 0, Maxdatablocksize);
 
 	fd = open(freesfile, OREAD);
@@ -54,14 +58,18 @@
 	if(fd < 0)
 		sysfatal("updatefrees: cannot open freesfile %s\n", freesfile);
 
-	nfreesize = read(fd, frees, Maxdatablocksize);
+	nfreesize = readn(fd, frees, Maxdatablocksize);
 	if(nfreesize <= 0)
 		sysfatal("updatefrees: nfreesize %d <= 0\n", nfreesize);
+	if(nfreesize > (Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */)))
+		sysfatal("updatefrees: unsupported nfreesize %d needs more than a block Datablocksize %llud\n",
+					nfreesize, Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
 	if(nfreesize > Maxdatablocksize)
 		sysfatal("updatefrees: unsupported nfreesize %d > Datablocksize %llud\n",
 					nfreesize, Maxdatablocksize);
 	close(fd);
 
+	/* use the first block to write */
 	freeblkno = atoll((s8*)frees);
 
 	if (access(devfile, AREAD|AWRITE) == -1)
@@ -91,12 +99,15 @@
 			print("changed dblocks[0]: %llud to %llud\n", d->dblocks[0], freeblkno);
 		d->dblocks[0] = freeblkno;
 
-		c = (Data*)frees;
-		c->tag = Tdata;
-		c->path = Qpfrees;
+		f = (Data*)freesdata;
+		f->tag = Tdata;
+		f->len = 1;
+		memcpy(f->buf, frees, Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
+		freesdata[Dpathidx] = Qpfrees;
 
 		devwrite(Bdfrees, buf, Metadataunits);
-		devwrite(freeblkno, frees, nlastdatablocks(nfreesize));
+		// devwrite(freeblkno, frees, nlastdatablocks(nfreesize));
+		devwrite(freeblkno, (s8*)freesdata, 1);
 	}
 	close(devfd);
 	exits(0);
--- a/used.c
+++ b/used.c
@@ -92,9 +92,10 @@
 walkindir(u64 blkno, u16 tag, u16 bottomtag, u64 qpath)
 {
 	u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+	u64 ebuf[Nu64perblock];
 	Indirect *t;
 	Data *da;
-	u64 cblkno;
+	u64 cblkno, path;
 	int i;
 	Dentry *cd;
 
@@ -116,7 +117,9 @@
 				}else{
 					devread(cblkno, cbuf, 1);
 					da = (Data*)cbuf;
-					checkvalid(cblkno, da->tag, da->path, Tdata, da->path, da->len);
+					devread(cblkno+da->len-1, ebuf, 1);
+					path = ebuf[Dpathidx];
+					checkvalid(cblkno, da->tag, path, Tdata, qpath, da->len);
 				}
 			}
 		}else{
@@ -190,10 +193,11 @@
 walkfile(u64 blkno)
 {
 	u8 buf[Metadatablocksize], cbuf[Metadatablocksize];
+	u64 ebuf[Nu64perblock];
 	Dentry *d;
 	Data *ct;
 	Indirect *it;
-	u64 cblkno;
+	u64 cblkno, path;
 	int i;
 
 	devread(blkno, buf, Metadataunits);
@@ -223,7 +227,9 @@
 			return;
 		devread(cblkno, cbuf, 1);
 		ct = (Data*)cbuf;
-		checkvalid(cblkno, ct->tag, ct->path, Tdata, d->qpath, ct->len);
+		devread(cblkno+ct->len-1, ebuf, 1);
+		path = ebuf[Dpathidx];
+		checkvalid(cblkno, ct->tag, path, Tdata, d->qpath, ct->len);
 	}
 	for(i = 0; i<Niblock; i++){
 		cblkno = d->iblocks[i];
@@ -237,115 +243,6 @@
 			fprint(2, "invalid indir tag of block %llud %d %s\n",
 					cblkno, it->tagi, tagnames[it->tagi]);
 			fprint(2, "%llud\n", cblkno);
-		}
-	}
-	return;
-}
-
-/* checks the ending path and takes too long */
-void
-walkfileproper(u64 blkno)
-{
-	u8 buf[Metadatablocksize], *cbuf;
-	Dentry *d;
-	Data *ct;
-	Indirect *it;
-	u64 cblkno;
-	int i;
-
-	devread(blkno, buf, Metadataunits);
-	recentmetadata(buf, &d, nil);
-	if(chatty9p)
-		print("walkfile %llud tag %s name %s d->qid.path %llud\n",
-				blkno, tagnames[d->tag], d->name, d->qpath);
-	if(d->tag != Tdentry || d->path != d->qpath){
-		if(chatty9p)
-			print("walkfile invalid %llud tag/path expected %s/%llud actual %s/%llud\n",
-					blkno, tagnames[Tdentry], d->qpath, tagnames[d->tag], d->path);
-		fprint(2, "%llud\n", blkno);
-	}else{
-		// print("%llud\n", blkno);
-		add(&useds, blkno, Metadataunits);
-	}
-	/* do not list the data blocks used by /adm/frees
-		as they are considered to be free blocks */
-	if(blkno == Bdfrees)
-		return;
-	if(d->size <= Ddatasize)
-		return;
-
-	cbuf = malloc(Maxdatablockunits*Blocksize);
-	for(i = 0; i<Ndblock; i++){
-		cblkno = d->dblocks[i];
-		if(cblkno == 0){
-			free(cbuf);
-			return;
-		}
-		devread(cblkno, cbuf, 1);
-		ct = (Data*)cbuf;
-		checkvalid(cblkno, ct->tag, ct->path, Tdata, d->qpath, ct->len);
-	}
-	for(i = 0; i<Niblock; i++){
-		cblkno = d->iblocks[i];
-		if(cblkno == 0){
-			free(cbuf);
-			return;
-		}
-		devread(cblkno, cbuf, Metadataunits);
-		recentmetadata(cbuf, &it, nil);
-		if(it->tagi == Tind0+i){
-			walkindir(cblkno, Tind0+i, Tdata, d->qpath);
-		}else{
-			fprint(2, "invalid indir tag of block %llud\n", cblkno);
-			fprint(2, "%llud\n", cblkno);
-		}
-	}
-	free(cbuf);
-	return;
-}
-
-void
-walkindirproper(u64 blkno, u16 tag, u16 bottomtag, u64 qpath)
-{
-	u8 buf[Metadatablocksize], *cbuf;
-	Indirect *t;
-	Data *da;
-	u64 cblkno;
-	int i;
-	Dentry *cd;
-
-	devread(blkno, buf, Metadataunits);
-	recentmetadata(buf, &t, nil);
-	if(checkvalid(blkno, t->tagi, t->path, tag, qpath, Metadataunits)){
-		if(tag == Tind0){
-			for(i = 0; i<Nindperblock; i++){
-				cblkno = t->bufa[i];
-				if(cblkno == 0)
-					return;
-				if(bottomtag == Tdentry){
-					cbuf = malloc(Metadatablocksize);
-					devread(cblkno, cbuf, Metadataunits);
-					recentmetadata(cbuf, &cd, nil);
-					if((cd->mode & DMDIR) > 0)
-						walkdirectory(cblkno);
-					else
-						walkfile(cblkno);
-					free(cbuf);
-				}else{
-					cbuf = malloc(Maxdatablockunits*Blocksize);
-					devread(cblkno, cbuf, 1);
-					da = (Data*)cbuf;
-					checkvalid(cblkno, da->tag, da->path, Tdata, da->path, da->len);
-					free(cbuf);
-				}
-			}
-		}else{
-			for(i = 0; i<Nindperblock; i++){
-				cblkno = t->bufa[i];
-				if(cblkno == 0)
-					return;
-				walkindir(cblkno, tag-1,  bottomtag, qpath);
-			}
 		}
 	}
 	return;