diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-12 12:07:03 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-12 12:07:03 +0000 |
commit | b36a5dfc910b36a587f505420e6e082bd69d8b08 (patch) | |
tree | 0d81a12afa8aa5789eeb6f4df0f7756578fbe66e /sys/src/cmd/cwfs | |
parent | ac2e6cf02063ca9f9769b669ef53ce5c1a764f4e (diff) |
cwfs: +t
Diffstat (limited to 'sys/src/cmd/cwfs')
-rw-r--r-- | sys/src/cmd/cwfs/9p2.c | 8 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/cw.c | 80 | ||||
-rw-r--r-- | sys/src/cmd/cwfs/portdat.h | 2 |
3 files changed, 72 insertions, 18 deletions
diff --git a/sys/src/cmd/cwfs/9p2.c b/sys/src/cmd/cwfs/9p2.c index 731e1c3a3..1133a3fdf 100644 --- a/sys/src/cmd/cwfs/9p2.c +++ b/sys/src/cmd/cwfs/9p2.c @@ -18,6 +18,8 @@ mkmode9p1(ulong mode9p2) mode |= DAPND; if(mode9p2 & DMDIR) mode |= DDIR; + if(mode9p2 & DMTMP) + mode |= DTMP; return mode; } @@ -45,6 +47,8 @@ mktype9p2(int mode9p1) type |= QTAPPEND; if(mode9p1 & DDIR) type |= QTDIR; + if(mode9p1 & DTMP) + type |= QTTMP; return type; } @@ -61,6 +65,8 @@ mkmode9p2(int mode9p1) mode |= DMAPPEND; if(mode9p1 & DDIR) mode |= DMDIR; + if(mode9p1 & DTMP) + mode |= DMTMP; return mode; } @@ -1488,7 +1494,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) error = Ewstatq; goto out; } - if(dir.mode & ~(DMDIR|DMAPPEND|DMEXCL|0777)){ + if(dir.mode & ~(DMDIR|DMAPPEND|DMEXCL|DMTMP|0777)){ error = Ewstatb; goto out; } diff --git a/sys/src/cmd/cwfs/cw.c b/sys/src/cmd/cwfs/cw.c index 05a400c2d..2017e3388 100644 --- a/sys/src/cmd/cwfs/cw.c +++ b/sys/src/cmd/cwfs/cw.c @@ -1233,6 +1233,7 @@ split(Cw *cw, Iobuf *p, Off addr) putbuf(p); p = 0; } + state = cwio(cw->dev, addr, 0, Onone); /* read the state (twice?) */ switch(state) { default: @@ -1249,13 +1250,14 @@ split(Cw *cw, Iobuf *p, Off addr) /* * botch.. could be done by relabeling */ - if(!p) { + if(!p){ p = getbuf(cw->dev, addr, Brd); if(p == nil) { fprint(2, "split: null getbuf\n"); break; } } + na = cw->fsize; cw->fsize = na+1; cwio(cw->dev, na, 0, Ogrow); @@ -1293,8 +1295,9 @@ isdirty(Cw *cw, Iobuf *p, Off addr, int tag) Off cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) { - Iobuf *p; + Iobuf *p, *b; Dentry *d; + long qp1; int i, j, shouldstop; Off na; char *np; @@ -1323,6 +1326,7 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) } cw->depth++; + b = nil; switch(tag) { default: fprint(2, "cwrecur: unknown tag %d %s\n", tag, cw->name); @@ -1334,9 +1338,12 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) case Tdir: if(!p) { p = getbuf(cw->dev, addr, Brd); - if(p == nil) { - fprint(2, "cwrecur: Tdir p null %s\n", - cw->name); + if(!p || checktag(p, tag, qp)) { + fprint(2, "cwrecur: Tdir p null %s\n", cw->name); + if(p){ + putbuf(p); + p = nil; + } break; } } @@ -1353,11 +1360,12 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) d = getdir(p, i); if(!(d->mode & DALLOC)) continue; - qp = d->qid.path & ~QPDIR; + if(d->mode & DTMP) + continue; + qp1 = d->qid.path & ~QPDIR; if(tag == Tdir) strncpy(np, d->name, NAMELEN); - else - if(i > 0) + else if(i > 0) fprint(2, "cwrecur: root with >1 directory\n"); tag1 = Tfile; if(d->mode & DDIR) @@ -1365,7 +1373,7 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) for(j=0; j<NDBLOCK; j++) { na = d->dblock[j]; if(na) { - na = cwrecur(cw, na, tag1, 0, qp); + na = cwrecur(cw, na, tag1, 0, qp1); if(na) { d->dblock[j] = na; p->flags |= Bmod; @@ -1375,7 +1383,7 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) for (j = 0; j < NIBLOCK; j++) { na = d->iblocks[j]; if(na) { - na = cwrecur(cw, na, Tind1+j, tag1, qp); + na = cwrecur(cw, na, Tind1+j, tag1, qp1); if(na) { d->iblocks[j] = na; p->flags |= Bmod; @@ -1383,6 +1391,20 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) } } } + + for(i=0; i<DIRPERBUF; i++){ + d = getdir(p, i); + if(!(d->mode & DALLOC)) + continue; + if(d->mode & DTMP){ + if(!b){ + b = getbuf(devnone, Cwtmp, 0); + memmove(b->iobuf, p->iobuf, RBUFSIZE); + } + memset(d, 0, sizeof(Dentry)); + p->flags |= Bmod; + } + } break; case Tind1: @@ -1400,8 +1422,12 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) tind: if(!p) { p = getbuf(cw->dev, addr, Brd); - if(p == nil) { + if(!p || checktag(p, tag, qp)) { fprint(2, "cwrecur: Tind p null %s\n", cw->name); + if(p){ + putbuf(p); + p = nil; + } break; } } @@ -1417,15 +1443,35 @@ cwrecur(Cw *cw, Off addr, int tag, int tag1, long qp) } break; } + na = split(cw, p, addr); + cw->depth--; - if(na && shouldstop) { - if(cw->falsehits < 10) - fprint(2, "shouldstop %lld %lld t=%s %s\n", - (Wideoff)addr, (Wideoff)na, - tagnames[tag], cw->name); - cw->falsehits++; + + if(na){ + if(b){ + p = getbuf(cw->dev, na, Brd); + if(!p || checktag(p, tag, qp)){ + fprint(2, "cwrecur: b/p null %s\n", cw->name); + na = 0; + } else { + memmove(p->iobuf, b->iobuf, RBUFSIZE); + p->flags |= Bmod|Bimm; + } + if(p) + putbuf(p); + } + if(shouldstop){ + if(cw->falsehits < 10) + fprint(2, "shouldstop %lld %lld t=%s %s\n", + (Wideoff)addr, (Wideoff)na, + tagnames[tag], cw->name); + cw->falsehits++; + } } + if(b) + putbuf(b); + return na; } diff --git a/sys/src/cmd/cwfs/portdat.h b/sys/src/cmd/cwfs/portdat.h index a0bca86e0..460e8abed 100644 --- a/sys/src/cmd/cwfs/portdat.h +++ b/sys/src/cmd/cwfs/portdat.h @@ -126,6 +126,7 @@ struct Dentry #define DDIR 0x4000 #define DAPND 0x2000 #define DLOCK 0x1000 + #define DTMP 0x0800 #define DREAD 0x4 #define DWRITE 0x2 #define DEXEC 0x1 @@ -621,6 +622,7 @@ enum Cwdump2, Cuidbuf, Cckbuf, + Cwtmp, }; /* |