diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-01-12 20:13:20 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-01-12 20:13:20 +0100 |
commit | 47f07b2669e74eb957db56befa2237df5afa8474 (patch) | |
tree | 63239fa5b8ff90cae4c817111465b2ea2180d0c3 /sys/src/9/port/devmnt.c | |
parent | 4aeefba6811e57afe04a909fe147a29bb419d06b (diff) |
kernel: make the mntcache robust against fileserver like fossil that do not change the qid.vers on wstat
introducing new ctrunc() function that invalidates any caches
for the passed in chan, invoked when handling wstat with a
specified file length or on file creation/truncation.
test program to reproduce the problem:
#include <u.h>
#include <libc.h>
#include <libsec.h>
void
main(int argc, char *argv[])
{
int fd;
Dir *d, nd;
fd = create("xxx", ORDWR, 0666);
write(fd, "1234", 4);
d = dirstat("xxx");
assert(d->length == 4);
nulldir(&nd);
nd.length = 0;
dirwstat("xxx", &nd);
d = dirstat("xxx");
assert(d->length == 0);
fd = open("xxx", OREAD);
assert(read(fd, (void*)&d, 4) == 0);
}
Diffstat (limited to 'sys/src/9/port/devmnt.c')
-rw-r--r-- | sys/src/9/port/devmnt.c | 12 |
1 files changed, 10 insertions, 2 deletions
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; } |