From: Derrick Brashear Date: Fri, 20 May 2011 18:13:01 +0000 (-0400) Subject: macos: bulkstat redux X-Git-Tag: upstream/1.6.0.pre6^2~13 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=45f444376cf446a0e21795ea627413666f634011;p=packages%2Fo%2Fopenafs.git 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. Reviewed-on: http://gerrit.openafs.org/4677 Tested-by: Derrick Brashear Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 04087af8494b90f664ac5f274d5db4c12063f238) Change-Id: I7a9c3e4f94496aa1a553ad54f6d43a0d0e6ccd5a Reviewed-on: http://gerrit.openafs.org/4699 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/afs/DARWIN/osi_inode.c b/src/afs/DARWIN/osi_inode.c index 81f9dbfe5..e854a418a 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 a69a819cc..0380461d7 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 15c2b7bc8..ee4b28e8f 100644 --- a/src/afs/DARWIN/osi_vcache.c +++ b/src/afs/DARWIN/osi_vcache.c @@ -99,7 +99,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 @@ -113,6 +113,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 84dd3cad8..28e7ac96b 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 e33514c16..8dc8b85ef 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 ee8f2fc3b..7fb569d1b 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 */ @@ -816,7 +817,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); @@ -826,12 +827,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); @@ -1079,7 +1092,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); @@ -1095,9 +1108,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); @@ -1223,10 +1239,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); @@ -1258,7 +1273,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 c44c2bb6f..fcc4c707a 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1292,8 +1292,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 flag param of afs_CheckVolumeNames */ #define AFS_VOLCHECK_EXPIRED 0x1 /* volumes whose callbacks have expired */ diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c index 9cc559785..d24e070f0 100644 --- a/src/afs/afs_callback.c +++ b/src/afs/afs_callback.c @@ -458,11 +458,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)) @@ -473,11 +471,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 @@ -553,11 +546,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)) @@ -568,11 +559,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 2b9286dad..f2825102c 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -3415,11 +3415,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)) @@ -3430,11 +3428,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 3d79d23d2..f03dfd207 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -1379,6 +1379,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 @@ -1413,16 +1416,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; } @@ -1430,6 +1449,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)) @@ -2018,11 +2045,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 */ @@ -2034,11 +2059,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; } @@ -2517,7 +2537,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 { @@ -2527,16 +2546,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 { @@ -2617,19 +2627,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; @@ -2639,30 +2636,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) { @@ -2679,11 +2656,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; @@ -2796,11 +2768,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)) { @@ -2815,11 +2785,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) {