From: Chaskiel M Grundman Date: Thu, 5 Jan 2006 05:57:55 +0000 (+0000) Subject: STABLE14-macos-vnode-get-fixes-20060105 X-Git-Tag: openafs-stable-1_4_1-rc3~1 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=7d81ee9430acb50eefd5035bd4f0d33ff7d5ed88;p=packages%2Fo%2Fopenafs.git STABLE14-macos-vnode-get-fixes-20060105 The afs_pioctl.c change should fix a real crash (panic), but fs flushv isn't that common an operation. Other changes: don't GUNLOCK() around vnode_get(). we weren't consistent about it, and it doesn't appear to be strictly required. handle vnode_get() failures in more cases darwin_vn_hold will panic if vnode is terminating rather than mess up the refcounts. (cherry picked from commit 8b015a5e325b52969203d0647f67945ab7e402cc) --- diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index 06e43147a..97741b093 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -247,7 +247,16 @@ darwin_vn_hold(struct vnode *vp) if (haveGlock) AFS_GUNLOCK(); #ifdef AFS_DARWIN80_ENV - vnode_get(vp); + if (vnode_get(vp)) { + /* being terminated. kernel won't give us a ref. Now what? our + callers don't expect us to fail */ +#if 1 + panic("vn_hold on terminating vnode"); +#else + if (haveGlock) AFS_GLOCK(); + return; +#endif + } vnode_ref(vp); vnode_put(vp); #else diff --git a/src/afs/afs_osidnlc.c b/src/afs/afs_osidnlc.c index 9ece5a1ec..cee981484 100644 --- a/src/afs/afs_osidnlc.c +++ b/src/afs/afs_osidnlc.c @@ -243,7 +243,12 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) VN_HOLD((vnode_t *) tvc); #else #ifdef AFS_DARWIN80_ENV - vnode_get(tvc->v); + if (vnode_get(tvc->v)) { + ReleaseReadLock(&afs_xvcache); + dnlcstats.misses++; + osi_dnlc_remove(adp, aname, tvc); + return 0; + } #endif osi_vnhold(tvc, 0); #endif diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 6ba9cf62e..18ef43f04 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -2586,6 +2586,10 @@ DECL_PIOCTL(PFlushVolumeData) VN_HOLD(AFSTOV(tvc)); #else #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#ifdef AFS_DARWIN80_ENV + if (vnode_get(AFSTOV(tvc))) + continue; +#endif osi_vnhold(tvc, 0); #else VREFCOUNT_INC(tvc); /* AIX, apparently */ @@ -2610,6 +2614,7 @@ DECL_PIOCTL(PFlushVolumeData) #endif #ifdef AFS_DARWIN80_ENV /* our tvc ptr is still good until now */ + vnode_put(AFSTOV(tvc)); AFS_FAST_RELE(tvc); ObtainReadLock(&afs_xvcache); #else diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index b059ef18d..1d2e08db5 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -760,20 +760,20 @@ restart: #if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #ifdef AFS_DARWIN80_ENV vnode_t tvp = AFSTOV(tvc); - fv_slept=1; - /* must release lock, since vnode_recycle will immediately - reclaim if there are no other users */ - ReleaseWriteLock(&afs_xvcache); - AFS_GUNLOCK(); /* VREFCOUNT_GT only sees usecounts, not iocounts */ /* so this may fail to actually recycle the vnode now */ /* must call vnode_get to avoid races. */ if (vnode_get(tvp) == 0) { + fv_slept=1; + /* must release lock, since vnode_put will immediately + reclaim if there are no other users */ + ReleaseWriteLock(&afs_xvcache); + AFS_GUNLOCK(); vnode_recycle(tvp); vnode_put(tvp); + AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache, 336); } - AFS_GLOCK(); - ObtainWriteLock(&afs_xvcache, 336); /* we can't use the vnode_recycle return value to figure * this out, since the iocount we have to hold makes it * always "fail" */ @@ -2037,6 +2037,9 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, struct AFSCallBack CallBack; struct AFSVolSync tsync; int origCBs = 0; +#ifdef AFS_OSF_ENV + int vg; +#endif start = osi_Time(); @@ -2080,7 +2083,6 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, /* for the present (95.05.25) everything on the hash table is * definitively NOT in the free list -- at least until afs_reclaim * can be safely implemented */ - int vg; AFS_GUNLOCK(); vg = vget(AFSTOV(tvc)); /* this bumps ref count */ AFS_GLOCK(); @@ -2088,16 +2090,12 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, continue; #endif /* AFS_OSF_ENV */ #ifdef AFS_DARWIN80_ENV - int vg; if (tvc->states & CDeadVnode) { ReleaseSharedLock(&afs_xvcache); afs_osi_Sleep(&tvc->states); goto rootvc_loop; } - AFS_GUNLOCK(); - vg = vnode_get(AFSTOV(tvc)); /* this bumps ref count */ - AFS_GLOCK(); - if (vg) + if (vnode_get(AFSTOV(tvc))) /* this bumps ref count */ continue; #endif break; @@ -2113,8 +2111,11 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, getNewFid = 1; ReleaseSharedLock(&afs_xvcache); #ifdef AFS_DARWIN80_ENV - if (tvc) + if (tvc) { + AFS_GUNLOCK(); vnode_put(AFSTOV(tvc)); + AFS_GLOCK(); + } #endif tvc = NULL; goto newmtpt; @@ -2566,6 +2567,9 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) register struct vcache *tvc; afs_int32 i; +#if defined( AFS_OSF_ENV) + int vg; +#endif AFS_STATCNT(afs_FindVCache); @@ -2579,7 +2583,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) } #ifdef AFS_OSF_ENV /* Grab this vnode, possibly reactivating from the free list */ - int vg; AFS_GUNLOCK(); vg = vget(AFSTOV(tvc)); AFS_GLOCK(); @@ -2587,15 +2590,11 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) continue; #endif /* AFS_OSF_ENV */ #ifdef AFS_DARWIN80_ENV - int vg; if (tvc->states & CDeadVnode) { findvc_sleep(tvc, flag); goto findloop; } - AFS_GUNLOCK(); - vg = vnode_get(AFSTOV(tvc)); - AFS_GLOCK(); - if (vg) + if (vnode_get(AFSTOV(tvc))) continue; #endif break; @@ -2697,6 +2696,9 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) afs_int32 i; afs_int32 count = 0; struct vcache *found_tvc = NULL; +#ifdef AFS_OSF_ENV + int vg; +#endif AFS_STATCNT(afs_FindVCache); @@ -2719,7 +2721,6 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) } #ifdef AFS_OSF_ENV /* Grab this vnode, possibly reactivating from the free list */ - int vg; AFS_GUNLOCK(); vg = vget(AFSTOV(tvc)); AFS_GLOCK(); @@ -2729,16 +2730,12 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) } #endif /* AFS_OSF_ENV */ #ifdef AFS_DARWIN80_ENV - int vg; if (tvc->states & CDeadVnode) { ReleaseSharedLock(&afs_xvcache); afs_osi_Sleep(&tvc->states); goto loop; } - AFS_GUNLOCK(); - vg = vnode_get(AFSTOV(tvc)); - AFS_GLOCK(); - if (vg) { + if (vnode_get(AFSTOV(tvc))) { /* This vnode no longer exists. */ continue; } diff --git a/src/afs/afs_volume.c b/src/afs/afs_volume.c index 727812994..0c0d08485 100644 --- a/src/afs/afs_volume.c +++ b/src/afs/afs_volume.c @@ -318,6 +318,8 @@ loop: afs_osi_Sleep(&tvc->states); goto loop; } + if (vnode_get(AFSTOV(tvc))) + continue; #endif AFS_FAST_HOLD(tvc); ReleaseReadLock(&afs_xvcache);