ref: b36a5dfc910b36a587f505420e6e082bd69d8b08
parent: ac2e6cf02063ca9f9769b669ef53ce5c1a764f4e
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Thu May 12 08:07:03 EDT 2011
cwfs: +t
--- a/sys/src/cmd/cwfs/9p2.c
+++ b/sys/src/cmd/cwfs/9p2.c
@@ -18,6 +18,8 @@
mode |= DAPND;
if(mode9p2 & DMDIR)
mode |= DDIR;
+ if(mode9p2 & DMTMP)
+ mode |= DTMP;
return mode;
}
@@ -45,6 +47,8 @@
type |= QTAPPEND;
if(mode9p1 & DDIR)
type |= QTDIR;
+ if(mode9p1 & DTMP)
+ type |= QTTMP;
return type;
}
@@ -61,6 +65,8 @@
mode |= DMAPPEND;
if(mode9p1 & DDIR)
mode |= DMDIR;
+ if(mode9p1 & DTMP)
+ mode |= DMTMP;
return mode;
}
@@ -1488,7 +1494,7 @@
error = Ewstatq;
goto out;
}
- if(dir.mode & ~(DMDIR|DMAPPEND|DMEXCL|0777)){
+ if(dir.mode & ~(DMDIR|DMAPPEND|DMEXCL|DMTMP|0777)){
error = Ewstatb;
goto out;
}
--- a/sys/src/cmd/cwfs/cw.c
+++ b/sys/src/cmd/cwfs/cw.c
@@ -1233,6 +1233,7 @@
putbuf(p);
p = 0;
}
+
state = cwio(cw->dev, addr, 0, Onone); /* read the state (twice?) */
switch(state) {
default:
@@ -1249,7 +1250,7 @@
/*
* 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");
@@ -1256,6 +1257,7 @@
break;
}
}
+
na = cw->fsize;
cw->fsize = na+1;
cwio(cw->dev, na, 0, Ogrow);
@@ -1293,8 +1295,9 @@
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 @@
}
cw->depth++;
+ b = nil;
switch(tag) {
default:
fprint(2, "cwrecur: unknown tag %d %s\n", tag, cw->name);
@@ -1334,9 +1338,12 @@
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 @@
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 @@
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 @@
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 @@
}
}
}
+
+ 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 @@
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 @@
}
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;
}
--- a/sys/src/cmd/cwfs/portdat.h
+++ b/sys/src/cmd/cwfs/portdat.h
@@ -126,6 +126,7 @@
#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 @@
Cwdump2,
Cuidbuf,
Cckbuf,
+ Cwtmp,
};
/*