summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/port/cache.c45
-rw-r--r--sys/src/9/port/devmnt.c12
-rw-r--r--sys/src/9/port/portfns.h3
3 files changed, 47 insertions, 13 deletions
diff --git a/sys/src/9/port/cache.c b/sys/src/9/port/cache.c
index 306228731..37a4d6813 100644
--- a/sys/src/9/port/cache.c
+++ b/sys/src/9/port/cache.c
@@ -187,7 +187,7 @@ ccache(Chan *c)
return nil;
}
-void
+int
copen(Chan *c)
{
Mntcache *m, *f, **l;
@@ -195,19 +195,20 @@ copen(Chan *c)
/* directories aren't cacheable */
if(c->qid.type&QTDIR){
c->mcp = nil;
- return;
+ return 0;
}
lock(&cache);
- m = clookup(c, 1);
- if(m == nil)
- m = cache.head;
- else if(m->qid.vers == c->qid.vers) {
+ m = clookup(c, 0);
+ if(m != nil){
ctail(m);
unlock(&cache);
c->mcp = m;
- return;
+ return 1;
}
+ m = clookup(c, 1);
+ if(m == nil)
+ m = cache.head;
ctail(m);
l = &cache.hash[m->qid.path%NHASH];
@@ -234,7 +235,7 @@ copen(Chan *c)
unlock(&cache);
cacheunlock(m);
c->mcp = f;
- return;
+ return 1;
}
}
@@ -251,10 +252,9 @@ copen(Chan *c)
m->rah.vers = m->qid.vers;
mntrahinit(&m->rah);
cnodata(m);
-
cacheunlock(m);
-
c->mcp = m;
+ return 0;
}
enum {
@@ -483,6 +483,31 @@ cwrite(Chan* c, uchar *buf, int len, vlong off)
}
void
+ctrunc(Chan *c)
+{
+ Mntcache *m;
+
+ if(c->qid.type&QTDIR)
+ return;
+
+ if((c->flag&COPEN) == 0){
+ lock(&cache);
+ c->mcp = clookup(c, 0);
+ unlock(&cache);
+ }
+
+ m = ccache(c);
+ if(m == nil)
+ return;
+ mntrahinit(&m->rah);
+ cnodata(m);
+ cacheunlock(m);
+
+ if((c->flag&COPEN) == 0)
+ c->mcp = nil;
+}
+
+void
cclunk(Chan *c)
{
Mntcache *m;
diff --git a/sys/src/9/port/devmnt.c b/sys/src/9/port/devmnt.c
index 095381d57..fc5ccbf1e 100644
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -521,8 +521,11 @@ mntopencreate(int type, Chan *c, char *name, int omode, ulong perm)
poperror();
mntfree(r);
- if(c->flag & CCACHE)
- copen(c);
+ if(c->flag & CCACHE){
+ if(copen(c))
+ if(type == Tcreate || (omode&OTRUNC) != 0)
+ ctrunc(c);
+ }
return c;
}
@@ -620,6 +623,11 @@ mntwstat(Chan *c, uchar *dp, int n)
mountrpc(m, r);
poperror();
mntfree(r);
+
+ if(c->flag & CCACHE)
+ if(GBIT64(&dp[STATFIXLEN-4*BIT16SZ-BIT64SZ]) != ~0ULL)
+ ctrunc(c);
+
return n;
}
diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h
index 7c7eec461..5564ce0c8 100644
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -41,13 +41,14 @@ void confinit(void);
int consactive(void);
void (*consdebug)(void);
void cpushutdown(void);
-void copen(Chan*);
+int copen(Chan*);
void cclunk(Chan*);
Block* concatblock(Block*);
Block* copyblock(Block*, int);
void copypage(Page*, Page*);
void countpagerefs(ulong*, int);
int cread(Chan*, uchar*, int, vlong);
+void ctrunc(Chan*);
void cunmount(Chan*, Chan*);
void cupdate(Chan*, uchar*, int, vlong);
void cwrite(Chan*, uchar*, int, vlong);