linux-fakestat-avoid-mtpt-fillin-issue-20080415
authorRainer Toebbicke <rtb@pclella.cern.ch>
Tue, 15 Apr 2008 13:29:20 +0000 (13:29 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 15 Apr 2008 13:29:20 +0000 (13:29 +0000)
LICENSE IPL10
FIXES 93898

"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."

src/afs/LINUX/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_lookup.c

index 3c7a818..6a324c8 100644 (file)
@@ -821,8 +821,14 @@ afs_linux_dentry_revalidate(struct dentry *dp)
        if (vcp == afs_globalVp)
            goto good_dentry;
 
-       if (*dp->d_name.name != '/' && vcp->mvstat == 2)        /* root vnode */
-           check_bad_parent(dp);       /* check and correct mvid */
+       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 */
 
 #ifdef notdef
        /* If the last looker changes, we should make sure the current
index 59ed1f0..6389263 100644 (file)
@@ -1208,6 +1208,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED
     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;
@@ -1596,8 +1597,6 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED
     }                          /* sub-block just to reduce stack usage */
 
     if (tvc) {
-       int force_eval = afs_fakestat_enable ? 0 : 1;
-
        if (adp->states & CForeign)
            tvc->states |= CForeign;
        tvc->parentVnode = adp->fid.Fid.Vnode;
@@ -1618,6 +1617,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED
                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 */
@@ -1743,7 +1745,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED
             * 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