We ran into this over a year ago and fixed it, but I must have
forgotten to submit the fix.
It is actually the detection of a "cell" in the mount point string
which triggers the (loosely consistent) fakestat handling - it's
treated like a foreign cell and the mount point is never "completely
evaluated", i.e. logically replaced by the root directory of the
volume in question. As a result, callbacks are ignored, as they go
against the directory and not the mount point.
The attached patch takes care of that.
(Bcc'ed openafs-bugs)
Stephan Wiesand schrieb:
If a client runs with the -fakestat[-all] option, and has a file cached
that resides in the root directory of a volume affected by fakestat, it
fails to invalidate its cache for this file when it's deleted:
ClientA: touch x
ClientB: ls -l x
... 0 Apr 10 13:10 x
ClientA: echo a >> x
ClientB: ls -l x; cat x
... 2 Apr 10 13:11 x
a
ClientA: rm x
ClientB: ls -l x; cat x
... 2 Apr 10 13:11 x (!)
a (!)
ClientA: echo b > x
ClientB: ls -l x; cat x
... 2 Apr 10 13:11 x (!)
a (!)
ClientB: fs flushv; ls -l x; cat x
... 2 Apr 10 13:12 x
b
I guess it's the same issue reported by Jack Neely on March 17th. We're
not running with -fakestat-all, just -fakestat. The problem struck when
mount points for local volumes were accidentally created with the -cell
option. We can reproduce the problem with local and foreign volumes.
Turning off fakestat eliminates it reliably.
We observe this with various Linux clients. OpenAFS 1.4.6 or 1.4.7pre3,
SL3/4/5, 32/64-bit.
An SL3 client still running 1.2.13 does not exhibit this problem.
Bcc to openafs-bugs.
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rainer Toebbicke
European Laboratory for Particle Physics(CERN) - Geneva, Switzerland
Phone: +41 22 767 8985 Fax: +41 22 767 7155
--- openafs/src/afs/LINUX/osi_vnodeops.c 2006-05-09 16:30:58.000000000
+0200
+++ openafs/src/afs/LINUX/osi_vnodeops.c 2007-02-02 15:26:01.000000000
+0100
@@ -894,9 +894,16 @@
vcp = VTOAFS(dp->d_inode);
pvcp = VTOAFS(dp->d_parent->d_inode); /* dget_parent()? */
+
if (vcp == afs_globalVp)
goto good_dentry;
+ if (vcp->mvstat == 1) { /* mount point */
+ if (vcp->mvid && (vcp->states & CMValid)) {
+ /* a mount point, not yet replaced by its directory */
+ goto bad_dentry;
+ }
+ } else
if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
check_bad_parent(dp); /* check and correct mvid */
--- openafs/src/afs/VNOPS/afs_vnop_lookup.c 2006-02-18 05:09:36.000000000
+0100
+++ openafs/src/afs/VNOPS/afs_vnop_lookup.c 2007-02-02 15:04:22.000000000
+0100
@@ -1120,6 +1120,7 @@
register afs_int32 code;
register afs_int32 bulkcode = 0;
int pass = 0, hit = 0;
+ int force_eval = afs_fakestat_enable ? 0 : 1;
long dirCookie;
extern afs_int32 afs_mariner; /*Writing activity to log? */
afs_hyper_t versionNo;
@@ -1437,7 +1438,6 @@
} /* sub-block just to reduce stack usage */
if (tvc) {
- int force_eval = afs_fakestat_enable ? 0 : 1;
if (adp->states & CForeign)
tvc->states |= CForeign;
@@ -1459,6 +1459,8 @@
force_eval = 1;
ReleaseReadLock(&tvc->lock);
}
+ if (tvc->mvstat == 1 && (tvc->states & CMValid) && tvc->mvid != NULL)
+ force_eval = 1; /* This is now almost for free, get it
correct */
#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
if (!(flags & AFS_LOOKUP_NOEVAL))
/* don't eval mount points */
@@ -1584,7 +1586,7 @@
* rather than the vc of the mount point itself. we can still find
the
* mount point's vc in the vcache by its fid. */
#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
- if (!hit) {
+ if (!hit && force_eval) {
osi_dnlc_enter(adp, aname, tvc, &versionNo);
} else {
#ifdef AFS_LINUX20_ENV