git: 9front

Download patch

ref: 894d4418ee951e5c468a3febe70322f7b8473aa2
parent: db15c129dbdd25447e73743b11dc809fc339a7a8
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri Oct 11 02:01:55 EDT 2013

cwfs: more checking for cfsdump(), cleanup Tsuper hack in cwrecur()

add checktag and nil checks in cfsdump() making sure to notice
when the roroot directory structures is corrupted.

cwrecur() used tag == Tsuper to indicate that this is the first
level recursive invocation. this is confusing as we really expect
Tdir tag in that case for the root directory. instead, we now
pass the correct tag (Tdir) and use cw->depth > 1 to see if we
are past the root.

the block tag was only checked when the block was not in
the memory cache. check the tag always!

--- a/sys/src/cmd/cwfs/cw.c
+++ b/sys/src/cmd/cwfs/cw.c
@@ -1331,24 +1331,15 @@
 	switch(tag) {
 	default:
 		fprint(2, "cwrecur: unknown tag %d %s\n", tag, cw->name);
+		break;
 
 	case Tfile:
+		if(p && checktag(p, tag, qp))
+			fprint(2, "cwrecur: Tfile %s\n", cw->name);
 		break;
 
-	case Tsuper:
 	case Tdir:
-		if(!p) {
-			p = getbuf(cw->dev, addr, Brd);
-			if(!p || checktag(p, tag, qp)) {
-				fprint(2, "cwrecur: Tdir p null %s\n", cw->name);
-				if(p){
-					putbuf(p);
-					p = nil;
-				}
-				break;
-			}
-		}
-		if(tag == Tdir) {
+		if(cw->depth > 1) {
 			cw->namepad[0] = 0;	/* force room */
 			np = strchr(cw->name, 0);
 			*np++ = '/';
@@ -1356,13 +1347,18 @@
 			np = 0;	/* set */
 			cw->name[0] = 0;
 		}
-
+		if(!p)
+			p = getbuf(cw->dev, addr, Brd);
+		if(!p || checktag(p, tag, qp)) {
+			fprint(2, "cwrecur: Tdir %s\n", cw->name);
+			break;
+		}
 		for(i=0; i<DIRPERBUF; i++) {
 			d = getdir(p, i);
 			if((d->mode & (DALLOC|DTMP)) != DALLOC)
 				continue;
 			qp1 = d->qid.path & ~QPDIR;
-			if(tag == Tdir)
+			if(np)
 				strncpy(np, d->name, NAMELEN);
 			else if(i > 0)
 				fprint(2, "cwrecur: root with >1 directory\n");
@@ -1405,16 +1401,11 @@
 #endif
 		j = tag-1;
 	tind:
-		if(!p) {
+		if(!p)
 			p = getbuf(cw->dev, addr, Brd);
-			if(!p || checktag(p, tag, qp)) {
-				fprint(2, "cwrecur: Tind p null %s\n", cw->name);
-				if(p){
-					putbuf(p);
-					p = nil;
-				}
-				break;
-			}
+		if(!p || checktag(p, tag, qp)) {
+			fprint(2, "cwrecur: Tind %s\n", cw->name);
+			break;
 		}
 		for(i=0; i<INDPERBUF; i++) {
 			na = ((Off *)p->iobuf)[i];
@@ -1493,7 +1484,7 @@
 	cons.noage = 1;
 	cw->all = cw->allflag | noatime | noatimeset;
 	noatimeset = 0;
-	rba = cwrecur(cw, orba, Tsuper, 0, QPROOT);
+	rba = cwrecur(cw, orba, Tdir, 0, QPROOT);
 	if(rba == 0)
 		rba = orba;
 	if(chatty)
@@ -1504,6 +1495,8 @@
 	 * partial super block
 	 */
 	p = getbuf(cw->dev, cwsaddr(cw->dev), Brd|Bmod|Bimm);
+	if(!p || checktag(p, Tsuper, QPSUPER))
+		goto bad;
 	s = (Superb*)p->iobuf;
 	s->fsize = cw->fsize;
 	s->cwraddr = rba;
@@ -1513,6 +1506,8 @@
 	 * partial cache block
 	 */
 	p = getbuf(cw->cdev, CACHE_ADDR, Brd|Bmod|Bimm|Bres);
+	if(!p || checktag(p, Tcache, QPSUPER))
+		goto bad;
 	h = (Cache*)p->iobuf;
 	h->fsize = cw->fsize;
 	h->cwraddr = rba;
@@ -1523,6 +1518,8 @@
 	 */
 	oroa = cwraddr(cw->rodev);
 	pr = getbuf(cw->dev, oroa, Brd|Bmod);
+	if(!pr || checktag(pr, Tdir, QPROOT))
+		goto bad;
 	dr = getdir(pr, 0);
 
 	datestr(tstr, time(nil));	/* tstr = "yyyymmdd" */
@@ -1529,7 +1526,7 @@
 	n = 0;
 	for(a=0;; a++) {
 		p1 = dnodebuf(pr, dr, a, Tdir, 0);
-		if(!p1)
+		if(!p1 || checktag(p1, Tdir, QPNONE))
 			goto bad;
 		n++;
 		for(i=0; i<DIRPERBUF; i++) {
@@ -1549,6 +1546,8 @@
 	 */
 found1:
 	p = getbuf(cw->dev, rba, Brd);
+	if(!p || checktag(p, Tdir, QPROOT))
+		goto bad;
 	d = getdir(p, 0);
 	d1->qid = d->qid;
 	d1->qid.version += n;
@@ -1572,7 +1571,7 @@
 	m = 0;
 	for(a=0;; a++) {
 		p1 = dnodebuf(pr, dr, a, Tdir, 0);
-		if(!p1)
+		if(!p1 || checktag(p1, Tdir, QPNONE))
 			goto bad;
 		n++;
 		for(i=0; i<DIRPERBUF; i++) {
@@ -1595,6 +1594,8 @@
 		sprint(tstr+8, "%ld", m);
 
 	p = getbuf(cw->dev, rba, Brd);
+	if(!p || checktag(p, Tdir, QPROOT))
+		goto bad;
 	d = getdir(p, 0);
 	*d1 = *d;				/* qid is QPROOT */
 	putbuf(p);
@@ -1612,7 +1613,7 @@
 
 	cons.noage = 0;
 	cw->all = 0;
-	roa = cwrecur(cw, oroa, Tsuper, 0, QPROOT);
+	roa = cwrecur(cw, oroa, Tdir, 0, QPROOT);
 	if(roa == 0)
 		roa = oroa;
 	if(chatty)
@@ -1626,6 +1627,8 @@
 	if(chatty)
 		fprint(2, "sblock %lld", (Wideoff)a);
 	p = getbuf(cw->dev, a, Brd|Bmod|Bimm);
+	if(!p || checktag(p, Tsuper, QPSUPER))
+		goto bad;
 	s = (Superb*)p->iobuf;
 	s->last = a;
 	sba = s->next;
@@ -1646,6 +1649,8 @@
 	 * final cache block
 	 */
 	p = getbuf(cw->cdev, CACHE_ADDR, Brd|Bmod|Bimm|Bres);
+	if(!p || checktag(p, Tcache, QPSUPER))
+		goto bad;
 	h = (Cache*)p->iobuf;
 	h->fsize = cw->fsize;
 	h->roraddr = roa;
--