From 04087af8494b90f664ac5f274d5db4c12063f238 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Fri, 20 May 2011 14:13:01 -0400 Subject: [PATCH] macos: bulkstat redux 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 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/afs/DARWIN/osi_inode.c | 6 +-- src/afs/DARWIN/osi_prototypes.h | 2 +- src/afs/DARWIN/osi_vcache.c | 6 ++- src/afs/DARWIN/osi_vfsops.c | 6 +-- src/afs/DARWIN/osi_vnodeops.c | 38 +++++++++------ src/afs/VNOPS/afs_vnop_lookup.c | 39 ++++++++++----- src/afs/afs.h | 2 - src/afs/afs_callback.c | 26 +++------- src/afs/afs_pioctl.c | 13 ++--- src/afs/afs_vcache.c | 103 +++++++++++++--------------------------- 10 files changed, 105 insertions(+), 136 deletions(-) diff --git a/src/afs/DARWIN/osi_inode.c b/src/afs/DARWIN/osi_inode.c index 81f9dbf..e854a41 100644 --- a/src/afs/DARWIN/osi_inode.c +++ b/src/afs/DARWIN/osi_inode.c @@ -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; } diff --git a/src/afs/DARWIN/osi_prototypes.h b/src/afs/DARWIN/osi_prototypes.h index a69a819..0380461 100644 --- a/src/afs/DARWIN/osi_prototypes.h +++ b/src/afs/DARWIN/osi_prototypes.h @@ -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); diff --git a/src/afs/DARWIN/osi_vcache.c b/src/afs/DARWIN/osi_vcache.c index ce3bb5f..18d8d9a 100644 --- a/src/afs/DARWIN/osi_vcache.c +++ b/src/afs/DARWIN/osi_vcache.c @@ -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 } diff --git a/src/afs/DARWIN/osi_vfsops.c b/src/afs/DARWIN/osi_vfsops.c index 84dd3ca..28e7ac9 100644 --- a/src/afs/DARWIN/osi_vfsops.c +++ b/src/afs/DARWIN/osi_vfsops.c @@ -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) (); diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index 2a0cdfc..3380e8e 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -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; diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 1edeb2c..3a8ea1b 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -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) { diff --git a/src/afs/afs.h b/src/afs/afs.h index f1dabf0..7787e17 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -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 diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c index d9d24f8..b880979 100644 --- a/src/afs/afs_callback.c +++ b/src/afs/afs_callback.c @@ -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 diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index c4f3a7b..6540d26 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -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 diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index e577230..b6d2915 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -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) { -- 1.9.4