ref: 5982c50fa4d29c7b2230d180959c679278c6a88f
parent: 7f57d5d9c58d9a471181f3f91e3c037b49cede9f
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;
--
⑨