]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
A better way to do cross-cell-only fakestat, which should
authorNickolai Zeldovich <kolya@mit.edu>
Thu, 14 Nov 2002 21:24:30 +0000 (21:24 +0000)
committerGarry Zacheiss <zacheiss@mit.edu>
Thu, 14 Nov 2002 21:24:30 +0000 (21:24 +0000)
also avoid problems with Linux's attribute validation.

(cherry picked from commit 2d182a7fc1aa17bce1f63164944995663f567c12)

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

index 30a2eaf4753be1c14dd4b01cfd3b66e3781b1127..e58af0ac7d2cdddbec3a48d376febd3ac74a83a9 100644 (file)
@@ -675,19 +675,14 @@ static int afs_linux_revalidate(struct dentry *dp)
     struct vrequest treq;
     struct vcache *vcp = ITOAFS(dp->d_inode);
     struct vcache *rootvp = NULL;
-    struct afs_fakestat_state fakestat;
 
     AFS_GLOCK();
 
-    afs_InitFakeStat(&fakestat);
-    if (vcp->mvstat == 1) {
-      afs_InitReq(&treq, credp);
-      rootvp = vcp;
-      code = afs_TryEvalFakeStat(&rootvp, &fakestat, &treq);
-      if (code) {
-       AFS_GUNLOCK();
-       return -code;
-      }
+    if (afs_fakestat_enable && vcp->mvstat == 1 && vcp->mvid &&
+       (vcp->states & CMValid) && (vcp->states & CStatd)) {
+       ObtainSharedLock(&afs_xvcache, 680);
+       rootvp = afs_FindVCache(vcp->mvid, 0, 0, 0, 0);
+       ReleaseSharedLock(&afs_xvcache);
     }
 
 #ifdef AFS_LINUX24_ENV
@@ -698,14 +693,14 @@ static int afs_linux_revalidate(struct dentry *dp)
     if (vcp->states & CStatd) {
        if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
            check_bad_parent(dp); /* check and correct mvid */
-       if (rootvp && rootvp != vcp)
+       if (rootvp)
            vcache2fakeinode(rootvp, vcp);
        else
            vcache2inode(vcp);
 #ifdef AFS_LINUX24_ENV
        unlock_kernel();
 #endif
-       afs_PutFakeStat(&fakestat);
+       if (rootvp) afs_PutVCache(rootvp);
        AFS_GUNLOCK();
        return 0;
     }
@@ -718,7 +713,6 @@ static int afs_linux_revalidate(struct dentry *dp)
 #ifdef AFS_LINUX24_ENV
     unlock_kernel();
 #endif
-    afs_PutFakeStat(&fakestat);
     AFS_GUNLOCK();
     crfree(credp);
 
index 0a57b58a8138b07baaea1b45954a255e6a955079..0c393fb32145c4e4c1275320d827e9cf1d3663a2 100644 (file)
@@ -54,7 +54,7 @@ extern struct inode_operations afs_symlink_iops, afs_dir_iops;
 
 afs_int32 afs_bulkStatsDone;
 static int bulkStatCounter = 0;        /* counter for bulk stat seq. numbers */
-int afs_fakestat_enable = 0;
+int afs_fakestat_enable = 0;   /* 1: fakestat-all, 2: fakestat-crosscell */
 
 
 /* this would be faster if it did comparison as int32word, but would be 
@@ -265,9 +265,11 @@ afs_InitFakeStat(state)
  *
  * The actual implementation of afs_EvalFakeStat and afs_TryEvalFakeStat,
  * which is called by those wrapper functions.
+ *
+ * Only issues RPCs if canblock is non-zero.
  */
-static int afs_EvalFakeStat_int(stricr vcache **avcp,
-      struct afs_fakestat_state *state, struct vrequest *areq, int canblock)
+int afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state,
+       struct vrequest *areq, int canblock)
 {
     struct vcache *tvc, *root_vp;
     struct volume *tvolp = NULL;
@@ -282,29 +284,10 @@ static int afs_EvalFakeStat_int(stricr vcache **avcp,
     if (tvc->mvstat != 1)
        return 0;
 
+    /* Is the call to VerifyVCache really necessary? */
     code = afs_VerifyVCache(tvc, areq);
     if (code)
        goto done;
-
-    if (afs_fakestat_enable == 2 && !canblock) {
-       ObtainSharedLock(&tvc->lock, 680);
-       if (!tvc->linkData) {
-           UpgradeSToWLock(&tvc->lock, 681);
-           code = afs_HandleLink(tvc, areq);
-           if (code) {
-               ReleaseWriteLock(&tvc->lock);
-               goto done;
-           }
-           ConvertWToRLock(&tvc->lock);
-       } else {
-           ConvertSToRLock(&tvc->lock);
-       }
-
-       if (!afs_strchr(tvc->linkData, ':'))
-           canblock = 1;
-       ReleaseReadLock(&tvc->lock);
-    }
-
     if (canblock) {
        ObtainWriteLock(&tvc->lock, 599);
        code = EvalMountPoint(tvc, NULL, &tvolp, areq);
@@ -1413,17 +1396,34 @@ afs_lookup(adp, aname, avcp, acred)
     } /* sub-block just to reduce stack usage */
 
     if (tvc) {
-       if (adp->states & CForeign)
+       int force_eval = afs_fakestat_enable ? 0 : 1;
+
+       if (adp->states & CForeign)
           tvc->states |= CForeign;
        tvc->parentVnode = adp->fid.Fid.Vnode;
        tvc->parentUnique = adp->fid.Fid.Unique;
        tvc->states &= ~CBulkStat;
 
+       if (afs_fakestat_enable == 2 && tvc->mvstat == 1) {
+           ObtainSharedLock(&tvc->lock, 680);
+           if (!tvc->linkData) {
+               UpgradeSToWLock(&tvc->lock, 681);
+               code = afs_HandleLink(tvc, &treq);
+               ConvertWToRLock(&tvc->lock);
+           } else {
+               ConvertSToRLock(&tvc->lock);
+               code = 0;
+           }
+           if (!code && !strchr(tvc->linkData, ':'))
+               force_eval = 1;
+           ReleaseReadLock(&tvc->lock);
+       }
+
 #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
         if (!(flags & AFS_LOOKUP_NOEVAL))
           /* don't eval mount points */
 #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
-       if (!afs_fakestat_enable && tvc->mvstat == 1) {
+       if (tvc->mvstat == 1 && force_eval) {
            /* a mt point, possibly unevaluated */
            struct volume *tvolp;