From: Derrick Brashear Date: Thu, 20 Jan 2011 04:11:11 +0000 (-0500) Subject: MacOS: allow cdead vcaches to be found in FindVCache if requested X-Git-Tag: upstream/1.6.0.pre4^2~30 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=74f56c447de1878427655c1394e1805081b65333;p=packages%2Fo%2Fopenafs.git MacOS: allow cdead vcaches to be found in FindVCache if requested if we are trying to find a dead vcache, let it be found, don't immediately attempt to recycle FIXES 128511 (cherry picked from commit d73d9a1011cc3e1e5acfbc970434373f732c066e) Change-Id: I4dde25e54e3d76faff58c8e42d0949493aa986f3 Reviewed-on: http://gerrit.openafs.org/4243 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 359b148bf..ee8f2fc3b 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -816,7 +816,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 /* no stats | LRU */ ); + tvcp = afs_FindVCache(&tfid, &retry, IS_WLOCK|FIND_BULKDEAD /* no stats | LRU */ ); if (tvcp && retry) { ReleaseWriteLock(&afs_xvcache); afs_PutVCache(tvcp); diff --git a/src/afs/afs.h b/src/afs/afs.h index b7372296f..f83c8d2d3 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1282,6 +1282,7 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ #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_vcache.c b/src/afs/afs_vcache.c index 40fd704c8..58c56cd4a 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -2600,6 +2600,7 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) struct vcache *tvc; afs_int32 i; #ifdef AFS_DARWIN80_ENV + struct vcache *deadvc = NULL, *livevc = NULL; vnode_t tvp; #endif @@ -2609,47 +2610,78 @@ 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; - } -#ifdef AFS_DARWIN80_ENV - if (tvc->f.states & CDeadVnode) { - if (!(flag & FIND_CDEAD)) { - findvc_sleep(tvc, flag); - goto findloop; - } } - tvp = AFSTOV(tvc); - if (vnode_get(tvp)) - continue; - if (vnode_ref(tvp)) { - AFS_GUNLOCK(); - /* AFSTOV(tvc) may be NULL */ - vnode_put(tvp); - AFS_GLOCK(); +#ifdef AFS_DARWIN80_ENV + if (tvc->f.states & CDeadVnode) { + findvc_sleep(tvc, flag); + goto findloop; + } + if (flag & FIND_CDEAD) { + livevc = tvc; continue; } - if (tvc->f.states & (CBulkFetching|CDeadVnode)) { - AFS_GUNLOCK(); - vnode_recycle(AFSTOV(tvc)); - AFS_GLOCK(); - } #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) { if (retry) *retry = 0; -#if !defined(AFS_DARWIN80_ENV) - osi_vnhold(tvc, retry); /* already held, above */ - if (retry && *retry) - return 0; -#endif -#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV) +#if defined(AFS_DARWIN80_ENV) + tvp = AFSTOV(tvc); + if (vnode_get(tvp)) + tvp = NULL; + if (tvp && vnode_ref(tvp)) { + AFS_GUNLOCK(); + /* AFSTOV(tvc) may be NULL */ + vnode_put(tvp); + 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; + } +#elif defined(AFS_DARWIN_ENV) tvc->f.states |= CUBCinit; AFS_GUNLOCK(); if (UBCINFOMISSING(AFSTOV(tvc)) || @@ -2658,6 +2690,10 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) } AFS_GLOCK(); tvc->f.states &= ~CUBCinit; +#else + osi_vnhold(tvc, retry); /* already held, above */ + if (retry && *retry) + return 0; #endif /* * only move to front of vlru if we have proper vcache locking)