summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@centraldogma>2011-05-12 12:07:03 +0000
committercinap_lenrek <cinap_lenrek@centraldogma>2011-05-12 12:07:03 +0000
commitb36a5dfc910b36a587f505420e6e082bd69d8b08 (patch)
tree0d81a12afa8aa5789eeb6f4df0f7756578fbe66e
parentac2e6cf02063ca9f9769b669ef53ce5c1a764f4e (diff)
cwfs: +t
-rw-r--r--sys/src/cmd/cwfs/9p2.c8
-rw-r--r--sys/src/cmd/cwfs/cw.c80
-rw-r--r--sys/src/cmd/cwfs/portdat.h2
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,
};
/*