]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-callback-get-refs-20060302
authorChaskiel M Grundman <cg2v@andrew.cmu.edu>
Thu, 2 Mar 2006 06:44:05 +0000 (06:44 +0000)
committerDerrick Brashear <shadow@dementia.org>
Thu, 2 Mar 2006 06:44:05 +0000 (06:44 +0000)
more updates, focused on issues found working at darwin, but actually generic issues

(cherry picked from commit c9a4d3363bc11722e017cac4ee83cbeb5d9583f7)

src/afs/afs_callback.c
src/afs/afs_cbqueue.c
src/afs/afs_pioctl.c

index 3ab7a434d95f846e8c0d7d90c8a664f6f0006967..f6868c2f0fd1288ac729414d094d1afb48e3b7e7 100644 (file)
@@ -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 */
     }
 
index 451a01f1ffb7a2620b26344f59437f81a413962e..87cb5bc553c09fd2a3e1afdd319a240f964601e1 100644 (file)
@@ -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);
                }
index 78081a4ed82b8347840843f818e66b288ad6d818..848f4c136d611d1056a07d8b4a5956ced087977c 100644 (file)
@@ -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);