From: Chaskiel M Grundman Date: Thu, 2 Mar 2006 06:44:05 +0000 (+0000) Subject: STABLE14-callback-get-refs-20060302 X-Git-Tag: openafs-stable-1_4_1-rc9~1 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=fb1b2e03b20ef64bb52c24c840d06137efc29640;p=packages%2Fo%2Fopenafs.git STABLE14-callback-get-refs-20060302 more updates, focused on issues found working at darwin, but actually generic issues (cherry picked from commit c9a4d3363bc11722e017cac4ee83cbeb5d9583f7) --- diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c index 3ab7a434d..f6868c2f0 100644 --- a/src/afs/afs_callback.c +++ b/src/afs/afs_callback.c @@ -384,6 +384,9 @@ ClearCallBack(register struct rx_connection *a_conn, register int i; struct VenusFid localFid; struct volume *tv; +#ifdef AFS_DARWIN80_ENV + vnode_t vp; +#endif AFS_STATCNT(ClearCallBack); @@ -407,6 +410,8 @@ ClearCallBack(register struct rx_connection *a_conn, * Clear callback for the whole volume. Zip through the * hash chain, nullifying entries whose volume ID matches. */ +loop1: + ObtainReadLock(&afs_xvcache); i = VCHashV(&localFid); for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) { uq = QPrev(tq); @@ -416,6 +421,40 @@ ClearCallBack(register struct rx_connection *a_conn, if (!localFid.Cell) localFid.Cell = tvc->fid.Cell; tvc->dchint = NULL; /* invalidate hints */ + if (tvc->states & CVInit) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop1; + } +#ifdef AFS_DARWIN80_ENV + if (tvc->states & CDeadVnode) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop1; + } +#endif +#if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) + VN_HOLD(AFSTOV(tvc)); +#else +#ifdef AFS_DARWIN80_ENV + vp = AFSTOV(tvc); + if (vnode_get(vp)) + continue; + if (vnode_ref(vp)) { + AFS_GUNLOCK(); + vnode_put(vp); + AFS_GLOCK(); + continue; + } +#else +#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) + osi_vnhold(tvc, 0); +#else + VREFCOUNT_INC(tvc); /* AIX, apparently */ +#endif +#endif +#endif + ReleaseReadLock(&afs_xvcache); ObtainWriteLock(&afs_xcbhash, 449); afs_DequeueCallback(tvc); tvc->states &= ~(CStatd | CUnique | CBulkFetching); @@ -425,13 +464,18 @@ ClearCallBack(register struct rx_connection *a_conn, else afs_evenCBs++; ReleaseWriteLock(&afs_xcbhash); - if (!(tvc->states & CVInit) && - (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) + if ((tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK, ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32, tvc->states, ICL_TYPE_INT32, a_fid->Volume); +#ifdef AFS_DARWIN80_ENV + vnode_put(AFSTOV(tvc)); +#endif + ObtainReadLock(&afs_xvcache); + uq = QPrev(tq); + AFS_FAST_RELE(tvc); } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) { tvc->states &= ~CMValid; @@ -439,6 +483,7 @@ ClearCallBack(register struct rx_connection *a_conn, localFid.Cell = tvc->mvid->Cell; } } + ReleaseReadLock(&afs_xvcache); /* * XXXX Don't hold any locks here XXXX @@ -454,24 +499,61 @@ ClearCallBack(register struct rx_connection *a_conn, /* * Clear callbacks just for the one file. */ + struct vcache *uvc; afs_allCBs++; if (a_fid->Vnode & 1) afs_oddCBs++; /*Could do this on volume basis, too */ else afs_evenCBs++; /*A particular fid was specified */ +loop2: + ObtainReadLock(&afs_xvcache); i = VCHash(&localFid); - for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { + for (tvc = afs_vhashT[i]; tvc; tvc = uvc) { + uvc = tvc->hnext; if (tvc->fid.Fid.Vnode == a_fid->Vnode && tvc->fid.Fid.Volume == a_fid->Volume && tvc->fid.Fid.Unique == a_fid->Unique) { tvc->callback = NULL; tvc->dchint = NULL; /* invalidate hints */ + if (tvc->states & CVInit) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop2; + } +#ifdef AFS_DARWIN80_ENV + if (tvc->states & CDeadVnode) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop2; + } +#endif +#if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) + VN_HOLD(AFSTOV(tvc)); +#else +#ifdef AFS_DARWIN80_ENV + vp = AFSTOV(tvc); + if (vnode_get(vp)) + continue; + if (vnode_ref(vp)) { + AFS_GUNLOCK(); + vnode_put(vp); + AFS_GLOCK(); + continue; + } +#else +#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) + osi_vnhold(tvc, 0); +#else + VREFCOUNT_INC(tvc); /* AIX, apparently */ +#endif +#endif +#endif + ReleaseReadLock(&afs_xvcache); ObtainWriteLock(&afs_xcbhash, 450); afs_DequeueCallback(tvc); tvc->states &= ~(CStatd | CUnique | CBulkFetching); ReleaseWriteLock(&afs_xcbhash); - if (!(tvc->states & CVInit) && - (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) + if ((tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK, ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32, @@ -481,8 +563,15 @@ ClearCallBack(register struct rx_connection *a_conn, lastCallBack_dv = tvc->mstat.DataVersion.low; osi_GetuTime(&lastCallBack_time); #endif /* CBDEBUG */ +#ifdef AFS_DARWIN80_ENV + vnode_put(AFSTOV(tvc)); +#endif + ObtainReadLock(&afs_xvcache); + uvc = tvc->hnext; + AFS_FAST_RELE(tvc); } } /*Walk through hash table */ + ReleaseReadLock(&afs_xvcache); } /*Clear callbacks for one file */ } diff --git a/src/afs/afs_cbqueue.c b/src/afs/afs_cbqueue.c index 451a01f1f..87cb5bc55 100644 --- a/src/afs/afs_cbqueue.c +++ b/src/afs/afs_cbqueue.c @@ -220,7 +220,7 @@ afs_CheckCallbacks(unsigned int secs) * write locking tvc? */ QRemove(tq); tvc->states &= ~(CStatd | CMValid | CUnique); - if (!(tvc->states & CVInit) && + if (!(tvc->states & (CVInit|CVFlushed)) && (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); @@ -237,7 +237,7 @@ afs_CheckCallbacks(unsigned int secs) */ QRemove(tq); tvc->states &= ~(CStatd | CMValid | CUnique); - if (!(tvc->states & CVInit) && + if (!(tvc->states & (CVInit|CVFlushed)) && (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); } @@ -310,7 +310,7 @@ afs_FlushCBs(void) tvc->states &= ~(CStatd); if (QPrev(&(tvc->callsort))) QRemove(&(tvc->callsort)); - if (!(tvc->states & CVInit) && + if (!(tvc->states & (CVInit|CVFlushed)) && ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); } @@ -339,7 +339,7 @@ afs_FlushServerCBs(struct server *srvp) tvc->callback = 0; tvc->dchint = NULL; /* invalidate hints */ tvc->states &= ~(CStatd); - if (!(tvc->states & CVInit) && + if (!(tvc->states & (CVInit|CVFlushed)) && ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR))) { osi_dnlc_purgedp(tvc); } diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 78081a4ed..848f4c136 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -2570,6 +2570,7 @@ DECL_PIOCTL(PFlushVolumeData) ObtainReadLock(&afs_xvcache); i = VCHashV(&avc->fid); for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) { + uq = QPrev(tq); tvc = QTOVH(tq); if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) { if (tvc->states & CVInit) { @@ -2629,8 +2630,6 @@ DECL_PIOCTL(PFlushVolumeData) uq = QPrev(tq); /* our tvc ptr is still good until now */ AFS_FAST_RELE(tvc); - } else { - uq = QPrev(tq); } } ReleaseReadLock(&afs_xvcache);