macos: bulkstat redux
authorDerrick Brashear <shadow@dementia.org>
Fri, 20 May 2011 18:13:01 +0000 (14:13 -0400)
committerDerrick Brashear <shadow@dementia.org>
Sat, 21 May 2011 13:50:20 +0000 (06:50 -0700)
simplify the logic which can require sleeps in various vcache
resolution paths. instead of the two-pass system we had before,
just guess using the even/odd hack what type a vnode will be.
if a vnode turns out to be a link and thus we are wrong, we
do a fixup later. other callers who "race" with bulkstat
(which is a supported feature, otherwise you'd have to block
callbacks) will also call through a fixup to get the correct
backing vnode type. this is necessary as the KPI doesn't
let us change the type of a vnode after it's been created.

side effect: eliminate many of the ugly cases where we had been
sleeping waiting for a vnode to be finalized even before bulkstat.

Change-Id: Ib888fa5577d48354725ea72305765e4341bc2366
Reviewed-on: http://gerrit.openafs.org/4677
Tested-by: Derrick Brashear <shadow@dementia.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/afs/DARWIN/osi_inode.c
src/afs/DARWIN/osi_prototypes.h
src/afs/DARWIN/osi_vcache.c
src/afs/DARWIN/osi_vfsops.c
src/afs/DARWIN/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs.h
src/afs/afs_callback.c
src/afs/afs_pioctl.c
src/afs/afs_vcache.c

index 81f9dbf..e854a41 100644 (file)
@@ -235,17 +235,17 @@ int
 afs_syscall_icreate(long dev, long near_inode, long param1, long param2, 
                    long param3, long param4, long *retval)
 {
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
 afs_syscall_iopen(int dev, int inode, int usrmod, long *retval)
 {
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
 afs_syscall_iincdec(int dev, int inode, int inode_p1, int amount)
 {
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
index a69a819..0380461 100644 (file)
@@ -36,7 +36,7 @@ extern void osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size);
 extern int osi_VM_Setup(struct vcache *avc, int force);
 
 /* osi_vnodeops.c */
-extern int afs_darwin_getnewvnode(struct vcache *avc, int recycle);
+extern int afs_darwin_getnewvnode(struct vcache *avc);
 extern int afs_darwin_finalizevnode(struct vcache *avc, struct vnode *parent,
                                    struct componentname *cnp, int isroot,
                                    int locked);
index ce3bb5f..18d8d9a 100644 (file)
@@ -100,7 +100,7 @@ void
 osi_AttachVnode(struct vcache *avc, int seq) {
     ReleaseWriteLock(&afs_xvcache);
     AFS_GUNLOCK();
-    afs_darwin_getnewvnode(avc, seq ? 0 : 1);  /* includes one refcount */
+    afs_darwin_getnewvnode(avc);  /* includes one refcount */
     AFS_GLOCK();
     ObtainWriteLock(&afs_xvcache,338);
 #ifdef AFS_DARWIN80_ENV
@@ -114,6 +114,8 @@ void
 osi_PostPopulateVCache(struct vcache *avc) {
 #if !defined(AFS_DARWIN80_ENV)
    avc->v->v_mount = afs_globalVFS;
-#endif
    vSetType(avc, VREG);
+#else
+   vSetType(avc, VNON);
+#endif
 }
index 84dd3ca..28e7ac9 100644 (file)
@@ -28,7 +28,7 @@ int afs_vfs_typenum;
 int
 afs_quotactl()
 {
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
@@ -258,7 +258,7 @@ afs_root(struct mount *mp, struct vnode **vpp)
                AFS_GLOCK();
                 if (error)
                    tvp = NULL;
-                else 
+                else
                    /* re-acquire the usecount that finalizevnode disposed of */
                    vnode_ref(AFSTOV(tvp));
             }
@@ -510,7 +510,7 @@ afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
        }
        break;
     }
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 typedef (*PFI) ();
index 2a0cdfc..3380e8e 100644 (file)
@@ -1210,6 +1210,10 @@ afs_vop_fsync(ap)
     struct vnode *vp = ap->a_vp;
     int haveGlock = ISAFS_GLOCK();
 
+    /* in order to recycle faked vnodes for bulkstat */
+    if (VTOAFS(vp) == NULL)
+       return ENOTSUP;
+
     /* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */
     if (!haveGlock) AFS_GLOCK();
     if (vop_cred)
@@ -1994,7 +1998,7 @@ afs_vop_truncate(ap)
                                 * } */ *ap;
 {
     /* printf("stray afs_vop_truncate\n"); */
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
@@ -2007,7 +2011,7 @@ afs_vop_update(ap)
                                 * } */ *ap;
 {
     /* printf("stray afs_vop_update\n"); */
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
@@ -2109,7 +2113,7 @@ afs_vop_cmap(ap)
 #endif
 
 int
-afs_darwin_getnewvnode(struct vcache *avc, int recycle)
+afs_darwin_getnewvnode(struct vcache *avc)
 {
 #ifdef AFS_DARWIN80_ENV
     vnode_t vp;
@@ -2128,8 +2132,7 @@ afs_darwin_getnewvnode(struct vcache *avc, int recycle)
       vnode_addfsref(vp);
       vnode_ref(vp);
       avc->v = vp;
-      if (recycle)
-         vnode_recycle(vp); /* terminate as soon as iocount drops */
+      vnode_recycle(vp); /* terminate as soon as iocount drops */
       avc->f.states |= CDeadVnode;
     }
     return error;
@@ -2145,20 +2148,26 @@ afs_darwin_getnewvnode(struct vcache *avc, int recycle)
 #ifdef AFS_DARWIN80_ENV
 /* if this fails, then tvc has been unrefed and may have been freed. 
    Don't touch! */
-int 
-afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot, int locked)
+int
+afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp,
+                        struct componentname *cnp, int isroot, int locked)
 {
     vnode_t ovp;
     vnode_t nvp;
     int error;
     struct vnode_fsparam par;
+
     if (!locked) {
        AFS_GLOCK();
        ObtainWriteLock(&avc->lock,325);
     }
     ovp = AFSTOV(avc);
-    if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) {
-        AFS_GUNLOCK();
+
+    /* if the type changed, we still need to do a fixup, for bulkstat */
+    if (vnode_vtype(ovp) == avc->f.m.Type && !(avc->f.states & CDeadVnode)
+       && vnode_vtype(ovp) != VNON)
+    {
+       AFS_GUNLOCK();
 #if 0 /* unsupported */
         if (dvp && cnp)
            vnode_update_identity(ovp, dvp, cnp->cn_nameptr, cnp->cn_namelen,
@@ -2166,14 +2175,15 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
                                  VNODE_UPDATE_PARENT|VNODE_UPDATE_NAME);
 #endif
        /* Can end up in reclaim... drop GLOCK */
-        vnode_rele(ovp);
+       vnode_rele(ovp);
        AFS_GLOCK();
        if (!locked) {
            ReleaseWriteLock(&avc->lock);
            AFS_GUNLOCK();
        }
-        return 0;
+       return 0;
     }
+
     if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
        panic("vcache %p should not be CDeadVnode", avc);
     AFS_GUNLOCK();
@@ -2196,13 +2206,13 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
        if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
            printf("vcache %p should not be CDeadVnode", avc);
        if (avc->v == ovp) {
-           if (avc->f.states & CBulkFetching) {
-               vnode_recycle(ovp);
-           }
            if (!(avc->f.states & CVInit)) {
                vnode_clearfsnode(ovp);
                vnode_removefsref(ovp);
            }
+           /* we're discarding on a fixup. mark for recycle */
+           if (!(avc->f.states & CDeadVnode))
+               vnode_recycle(ovp);
        }
        avc->v = nvp;
        avc->f.states &=~ CDeadVnode;
index 1edeb2c..3a8ea1b 100644 (file)
@@ -670,6 +670,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
     long startTime;            /* time we started the call,
                                 * for callback expiration base
                                 */
+    int ftype[4] = {VNON, VREG, VDIR, VLNK}; /* verify type is as expected */
     afs_size_t statSeqNo = 0;  /* Valued of file size to detect races */
     int code;                  /* error code */
     long newIndex;             /* new index in the dir */
@@ -817,7 +818,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
            do {
                retry = 0;
                ObtainWriteLock(&afs_xvcache, 130);
-               tvcp = afs_FindVCache(&tfid, &retry, IS_WLOCK|FIND_BULKDEAD /* no stats | LRU */ );
+               tvcp = afs_FindVCache(&tfid, &retry, IS_WLOCK /* no stats | LRU */ );
                if (tvcp && retry) {
                    ReleaseWriteLock(&afs_xvcache);
                    afs_PutVCache(tvcp);
@@ -827,12 +828,24 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                tvcp = afs_NewBulkVCache(&tfid, hostp, statSeqNo);
                if (tvcp)
                {
-                       ObtainWriteLock(&tvcp->lock, 505);
-                       ReleaseWriteLock(&afs_xvcache);
-                       afs_RemoveVCB(&tfid);
-                       ReleaseWriteLock(&tvcp->lock);
+                   ObtainWriteLock(&tvcp->lock, 505);
+#ifdef AFS_DARWIN80_ENV
+                   /* use even/odd hack to guess file versus dir.
+                      let links be reaped. oh well. */
+                   if (dirEntryp->fid.vnode & 1)
+                       tvcp->f.m.Type = VDIR;
+                   else
+                       tvcp->f.m.Type = VREG;
+                   /* finalize to a best guess */
+                   afs_darwin_finalizevnode(tvcp, VTOAFS(adp), NULL, 0, 1);
+                   /* re-acquire usecount that finalizevnode disposed of */
+                   vnode_ref(AFSTOV(tvcp));
+#endif
+                   ReleaseWriteLock(&afs_xvcache);
+                   afs_RemoveVCB(&tfid);
+                   ReleaseWriteLock(&tvcp->lock);
                } else {
-                       ReleaseWriteLock(&afs_xvcache);
+                   ReleaseWriteLock(&afs_xvcache);
                }
            } else {
                ReleaseWriteLock(&afs_xvcache);
@@ -1110,7 +1123,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
        do {
            retry = 0;
            ObtainReadLock(&afs_xvcache);
-           tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
+           tvcp = afs_FindVCache(&afid, &retry, 0/* !stats&!lru */);
            ReleaseReadLock(&afs_xvcache);
        } while (tvcp && retry);
 
@@ -1126,9 +1139,12 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
         * matches the value we placed there when we set the CBulkFetching
         * flag, then someone else has done something with this node,
         * and we may not have the latest status information for this
-        * file.  Leave the entry alone.
+        * file.  Leave the entry alone. There's also a file type
+        * change here, for OSX bulkstat support.
         */
-       if (!(tvcp->f.states & CBulkFetching) || (tvcp->f.m.Length != statSeqNo)) {
+       if (!(tvcp->f.states & CBulkFetching)
+           || (tvcp->f.m.Length != statSeqNo)
+           || (ftype[(&statsp[i])->FileType] != vType(tvcp))) {
            flagIndex++;
            ReleaseWriteLock(&tvcp->lock);
            afs_PutVCache(tvcp);
@@ -1254,10 +1270,9 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                afs_DequeueCallback(tvcp);
                if ((tvcp->f.states & CForeign) || (vType(tvcp) == VDIR))
                    osi_dnlc_purgedp(tvcp); /* if it (could be) a directory */
-           } else {
+           } else
                /* re-acquire the usecount that finalizevnode disposed of */
                vnode_ref(AFSTOV(tvcp));
-           }
        } else
 #endif
        ReleaseWriteLock(&afs_xcbhash);
@@ -1289,7 +1304,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
        do {
            retry = 0;
            ObtainReadLock(&afs_xvcache);
-           tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
+           tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */);
            ReleaseReadLock(&afs_xvcache);
        } while (tvcp && retry);
        if (tvcp != NULL) {
index f1dabf0..7787e17 100644 (file)
@@ -1340,8 +1340,6 @@ extern struct brequest afs_brs[NBRS];     /* request structures */
 #define DO_VLRU 2
 #define IS_SLOCK 4
 #define IS_WLOCK 8
-#define FIND_CDEAD 16
-#define FIND_BULKDEAD 32
 
 /* values for adown value of afs_LoopServers */
 #define AFS_LS_UP 0
index d9d24f8..b880979 100644 (file)
@@ -453,11 +453,9 @@ loop1:
 #else
 #ifdef AFS_DARWIN80_ENV
                        if (tvc->f.states & CDeadVnode) {
-                           if (!(tvc->f.states & CBulkFetching)) {
-                               ReleaseReadLock(&afs_xvcache);
-                               afs_osi_Sleep(&tvc->f.states);
-                               goto loop1;
-                           }
+                           ReleaseReadLock(&afs_xvcache);
+                           afs_osi_Sleep(&tvc->f.states);
+                           goto loop1;
                        }
                        vp = AFSTOV(tvc);
                        if (vnode_get(vp))
@@ -468,11 +466,6 @@ loop1:
                            AFS_GLOCK();
                            continue;
                        }
-                       if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
-                           AFS_GUNLOCK();
-                           vnode_recycle(AFSTOV(tvc));
-                           AFS_GLOCK();
-                       }
 #else
                        AFS_FAST_HOLD(tvc);
 #endif
@@ -548,11 +541,9 @@ loop2:
 #else
 #ifdef AFS_DARWIN80_ENV
                    if (tvc->f.states & CDeadVnode) {
-                       if (!(tvc->f.states & CBulkFetching)) {
-                           ReleaseReadLock(&afs_xvcache);
-                           afs_osi_Sleep(&tvc->f.states);
-                           goto loop2;
-                       }
+                       ReleaseReadLock(&afs_xvcache);
+                       afs_osi_Sleep(&tvc->f.states);
+                       goto loop2;
                    }
                    vp = AFSTOV(tvc);
                    if (vnode_get(vp))
@@ -563,11 +554,6 @@ loop2:
                        AFS_GLOCK();
                        continue;
                    }
-                   if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
-                       AFS_GUNLOCK();
-                       vnode_recycle(AFSTOV(tvc));
-                       AFS_GLOCK();
-                   }
 #else
                    AFS_FAST_HOLD(tvc);
 #endif
index c4f3a7b..6540d26 100644 (file)
@@ -3489,11 +3489,9 @@ DECL_PIOCTL(PFlushVolumeData)
                }
 #ifdef AFS_DARWIN80_ENV
                if (tvc->f.states & CDeadVnode) {
-                   if (!(tvc->f.states & CBulkFetching)) {
-                       ReleaseReadLock(&afs_xvcache);
-                       afs_osi_Sleep(&tvc->f.states);
-                       goto loop;
-                   }
+                   ReleaseReadLock(&afs_xvcache);
+                   afs_osi_Sleep(&tvc->f.states);
+                   goto loop;
                }
                vp = AFSTOV(tvc);
                if (vnode_get(vp))
@@ -3504,11 +3502,6 @@ DECL_PIOCTL(PFlushVolumeData)
                    AFS_GLOCK();
                    continue;
                }
-               if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
-                   AFS_GUNLOCK();
-                   vnode_recycle(AFSTOV(tvc));
-                   AFS_GLOCK();
-               }
 #else
                AFS_FAST_HOLD(tvc);
 #endif
index e577230..b6d2915 100644 (file)
@@ -1455,6 +1455,9 @@ afs_ProcessFS(struct vcache *avc,
              struct AFSFetchStatus *astat, struct vrequest *areq)
 {
     afs_size_t length;
+#ifdef AFS_DARWIN80_ENV
+    int fixup = 0;
+#endif
     AFS_STATCNT(afs_ProcessFS);
 
 #ifdef AFS_64BIT_CLIENT
@@ -1489,16 +1492,32 @@ afs_ProcessFS(struct vcache *avc,
     avc->f.m.Group = astat->Group;
     avc->f.m.LinkCount = astat->LinkCount;
     if (astat->FileType == File) {
+#ifdef AFS_DARWIN80_ENV
+       if (avc->f.m.Type != VREG)
+           fixup = 1;
+#endif
        vSetType(avc, VREG);
        avc->f.m.Mode |= S_IFREG;
     } else if (astat->FileType == Directory) {
+#ifdef AFS_DARWIN80_ENV
+       if (avc->f.m.Type != VDIR)
+           fixup = 1;
+#endif
        vSetType(avc, VDIR);
        avc->f.m.Mode |= S_IFDIR;
     } else if (astat->FileType == SymbolicLink) {
        if (afs_fakestat_enable && (avc->f.m.Mode & 0111) == 0) {
+#ifdef AFS_DARWIN80_ENV
+           if (avc->f.m.Type != VDIR)
+               fixup = 1;
+#endif
            vSetType(avc, VDIR);
            avc->f.m.Mode |= S_IFDIR;
        } else {
+#ifdef AFS_DARWIN80_ENV
+           if (avc->f.m.Type != VLNK)
+               fixup = 1;
+#endif
            vSetType(avc, VLNK);
            avc->f.m.Mode |= S_IFLNK;
        }
@@ -1506,6 +1525,14 @@ afs_ProcessFS(struct vcache *avc,
            avc->mvstat = 1;
        }
     }
+#ifdef AFS_DARWIN80_ENV
+    if (fixup) {
+       /* perform type correction on underlying vnode */
+       afs_darwin_finalizevnode(avc, NULL, NULL, 0, 1);
+       /* re-acquire the usecount that finalizevnode disposed of */
+       vnode_ref(AFSTOV(avc));
+    }
+#endif
     avc->f.anyAccess = astat->AnonymousAccess;
 #ifdef badidea
     if ((astat->CallerAccess & ~astat->AnonymousAccess))
@@ -2093,11 +2120,9 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
             }
 #ifdef AFS_DARWIN80_ENV
            if (tvc->f.states & CDeadVnode) {
-               if (!(tvc->f.states & CBulkFetching)) {
-                   ReleaseSharedLock(&afs_xvcache);
-                   afs_osi_Sleep(&tvc->f.states);
-                   goto rootvc_loop;
-               }
+               ReleaseSharedLock(&afs_xvcache);
+               afs_osi_Sleep(&tvc->f.states);
+               goto rootvc_loop;
            }
            tvp = AFSTOV(tvc);
            if (vnode_get(tvp))       /* this bumps ref count */
@@ -2109,11 +2134,6 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
                AFS_GLOCK();
                continue;
            }
-           if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
-               AFS_GUNLOCK();
-               vnode_recycle(AFSTOV(tvc));
-               AFS_GLOCK();
-           }
 #endif
            break;
        }
@@ -2593,7 +2613,6 @@ afs_ResetVCache(struct vcache *avc, afs_ucred_t *acred)
 static void
 findvc_sleep(struct vcache *avc, int flag)
 {
-    int fstates = avc->f.states;
     if (flag & IS_SLOCK) {
            ReleaseSharedLock(&afs_xvcache);
     } else {
@@ -2603,16 +2622,7 @@ findvc_sleep(struct vcache *avc, int flag)
            ReleaseReadLock(&afs_xvcache);
        }
     }
-    if (flag & FIND_CDEAD) {
-       ObtainWriteLock(&afs_xvcache, 342);
-       afs_FlushReclaimedVcaches();
-       if (fstates == avc->f.states) {
-           ReleaseWriteLock(&afs_xvcache);
-           afs_osi_Sleep(&avc->f.states);
-       } else
-           ReleaseWriteLock(&afs_xvcache);
-    } else
-       afs_osi_Sleep(&avc->f.states);
+    afs_osi_Sleep(&avc->f.states);
     if (flag & IS_SLOCK) {
            ObtainSharedLock(&afs_xvcache, 341);
     } else {
@@ -2693,19 +2703,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
     i = VCHash(afid);
     for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
        if (FidMatches(afid, tvc)) {
-#ifdef  AFS_DARWIN80_ENV
-           if (flag & FIND_CDEAD) {
-               if (tvc->f.states & (CDeadVnode|CBulkFetching)) {
-                   deadvc = tvc;
-                   continue;
-               }
-           } else {
-               if (tvc->f.states & CDeadVnode)
-                   if ((tvc->f.states & CBulkFetching) &&
-                       !(flag & FIND_BULKDEAD))
-                       continue;
-           }
-#endif
             if (tvc->f.states & CVInit) {
                findvc_sleep(tvc, flag);
                goto findloop;
@@ -2715,30 +2712,10 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
                findvc_sleep(tvc, flag);
                goto findloop;
             }
-           if (flag & FIND_CDEAD) {
-               livevc = tvc;
-               continue;
-           }
 #endif
            break;
        }
     }
-#ifdef  AFS_DARWIN80_ENV
-       if (flag & FIND_CDEAD) {
-           if (livevc && deadvc) {
-               /* discard deadvc */
-               AFS_GUNLOCK();
-               vnode_recycle(AFSTOV(deadvc));
-               vnode_put(AFSTOV(deadvc));
-               vnode_rele(AFSTOV(deadvc));
-               AFS_GLOCK();
-               deadvc = NULL;
-           }
-
-           /* return what's left */
-           tvc = livevc ? livevc : deadvc;
-       }
-#endif
 
     /* should I have a read lock on the vnode here? */
     if (tvc) {
@@ -2755,11 +2732,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
            AFS_GLOCK();
            tvp = NULL;
        }
-       if (tvp && (tvc->f.states & (CBulkFetching|CDeadVnode))) {
-           AFS_GUNLOCK();
-           vnode_recycle(AFSTOV(tvc));
-           AFS_GLOCK();
-       }
        if (!tvp) {
            tvc = NULL;
            return tvc;
@@ -2872,11 +2844,9 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
             }
 #ifdef  AFS_DARWIN80_ENV
            if (tvc->f.states & CDeadVnode) {
-               if (!(tvc->f.states & CBulkFetching)) {
-                   ReleaseSharedLock(&afs_xvcache);
-                   afs_osi_Sleep(&tvc->f.states);
-                   goto loop;
-               }
+               ReleaseSharedLock(&afs_xvcache);
+               afs_osi_Sleep(&tvc->f.states);
+               goto loop;
            }
            tvp = AFSTOV(tvc);
            if (vnode_get(tvp)) {
@@ -2891,11 +2861,6 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
                AFS_GLOCK();
                continue;
            }
-           if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
-               AFS_GUNLOCK();
-               vnode_recycle(AFSTOV(tvc));
-               AFS_GLOCK();
-           }
 #endif /* AFS_DARWIN80_ENV */
            count++;
            if (found_tvc) {