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

Reply via email to