macos bulkstat again
authorDerrick Brashear <shadow@dementia.org>
Wed, 21 Apr 2010 22:45:33 +0000 (18:45 -0400)
committerDerrick Brashear <shadow@dementia.org>
Wed, 21 Apr 2010 23:15:09 +0000 (16:15 -0700)
revamp this to avoid various issues with vnode references,
and to avoid potentially finding CVInit vcaches but not reclaiming

Change-Id: I6cb8d73b66c449a104799082259c97ede7e32e9b
Reviewed-on: http://gerrit.openafs.org/1802
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs.h
src/afs/afs_vcache.c

index f40f46c..9e90a91 100644 (file)
@@ -1061,7 +1061,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
        do {
            retry = 0;
            ObtainReadLock(&afs_xvcache);
-           tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */ );
+           tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
            ReleaseReadLock(&afs_xvcache);
        } while (tvcp && retry);
 
@@ -1080,19 +1080,8 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
         * file.  Leave the entry alone.
         */
        if (!(tvcp->f.states & CBulkFetching) || (tvcp->f.m.Length != statSeqNo)) {
-#ifdef AFS_DARWIN80_ENV            
-           int isdead = ((tvcp->f.states & CDeadVnode) ||
-                         (tvcp->f.states & CVInit));
-#endif
            flagIndex++;
            ReleaseWriteLock(&tvcp->lock);
-#ifdef AFS_DARWIN80_ENV            
-           if (!isdead) {
-               /* re-acquire the io&usecount that the other finalizevnode disposed of */
-               vnode_get(AFSTOV(tvcp));
-               vnode_ref(AFSTOV(tvcp));
-           }
-#endif
            afs_PutVCache(tvcp);
            continue;
        }
@@ -1148,13 +1137,6 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
         */
        if (!(tvcp->f.states & CBulkFetching) || (tvcp->f.m.Length != statSeqNo)) {
            flagIndex++;
-#ifdef AFS_DARWIN80_ENV            
-           if ((!(tvcp->f.states & CDeadVnode)&&!(tvcp->f.states & CVInit))) {
-               /* re-acquire the io&usecount that the other finalizevnode disposed of */
-               vnode_get(AFSTOV(tvcp));
-               vnode_ref(AFSTOV(tvcp));
-           }
-#endif
            ReleaseWriteLock(&tvcp->lock);
            ReleaseWriteLock(&afs_xcbhash);
            afs_PutVCache(tvcp);
@@ -1210,10 +1192,10 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
            if ((tvcp->f.states & CForeign) || (vType(tvcp) == VDIR))
                osi_dnlc_purgedp(tvcp); /* if it (could be) a directory */
        }
-       ReleaseWriteLock(&afs_xcbhash);
 #ifdef AFS_DARWIN80_ENV
        /* reclaim->FlushVCache will need xcbhash */
        if (((tvcp->f.states & CDeadVnode)||(tvcp->f.states & CVInit))) {
+           ReleaseWriteLock(&afs_xcbhash);
            /* passing in a parent hangs getting the vnode lock */
            code = afs_darwin_finalizevnode(tvcp, NULL, NULL, 0, 1);
            if (code) {
@@ -1224,12 +1206,12 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                if ((tvcp->f.states & CForeign) || (vType(tvcp) == VDIR))
                    osi_dnlc_purgedp(tvcp); /* if it (could be) a directory */
            } else {
-               /* re-acquire the io&usecount that finalizevnode disposed of */
-               vnode_get(AFSTOV(tvcp));
+               /* re-acquire the usecount that finalizevnode disposed of */
                vnode_ref(AFSTOV(tvcp));
            }
-       }
+       } else
 #endif
+       ReleaseWriteLock(&afs_xcbhash);
 
        ReleaseWriteLock(&tvcp->lock);
        /* finally, we're done with the entry */
@@ -1258,30 +1240,16 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
        do {
            retry = 0;
            ObtainReadLock(&afs_xvcache);
-           tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */ );
+           tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
            ReleaseReadLock(&afs_xvcache);
        } while (tvcp && retry);
        if (tvcp != NULL) {
            if ((tvcp->f.states & CBulkFetching)
                && (tvcp->f.m.Length == statSeqNo)) {
                tvcp->f.states &= ~CBulkFetching;
-#ifdef AFS_DARWIN80_ENV
-               if ((!(tvcp->f.states & CDeadVnode)&&!(tvcp->f.states & CVInit))) {
-                   /* re-acquire the io&usecount that finalizevnode dropped */
-                   vnode_get(AFSTOV(tvcp));
-                   vnode_ref(AFSTOV(tvcp));
-               }
-#endif
            }
            afs_PutVCache(tvcp);
        }
-#ifdef AFS_DARWIN80_ENV            
-       else {
-           if ((!(tvcp->f.states & CDeadVnode)&&!(tvcp->f.states & CVInit)))
-               osi_Panic("vnode finalized without clearing BulkFetching!");
-       }
-#endif
-
     }
     if (volp)
        afs_PutVolume(volp, READ_LOCK);
@@ -1304,11 +1272,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
 }
 
 /* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */
-#ifdef AFS_DARWIN_ENV
-static int AFSDOBULK = 0;
-#else
 static int AFSDOBULK = 1;
-#endif
 
 int
 #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
index 44f6679..2a43b9e 100644 (file)
@@ -1287,6 +1287,7 @@ extern struct brequest afs_brs[NBRS];     /* request structures */
 #define DO_VLRU 2
 #define IS_SLOCK 4
 #define IS_WLOCK 8
+#define FIND_CDEAD 16
 
 /* values for flag param of afs_CheckVolumeNames */
 #define AFS_VOLCHECK_EXPIRED   0x1     /* volumes whose callbacks have expired */
index d3b4dc5..7f83bbc 100644 (file)
@@ -2838,6 +2838,7 @@ 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 {
@@ -2847,7 +2848,16 @@ findvc_sleep(struct vcache *avc, int flag)
            ReleaseReadLock(&afs_xvcache);
        }
     }
-    afs_osi_Sleep(&avc->f.states);
+    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);
     if (flag & IS_SLOCK) {
            ObtainSharedLock(&afs_xvcache, 341);
     } else {
@@ -2894,7 +2904,7 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
             }
 #ifdef  AFS_DARWIN80_ENV
            if (tvc->f.states & CDeadVnode) {
-               if (!(tvc->f.states & CBulkFetching)) {
+               if (!(flag & FIND_CDEAD)) {
                    findvc_sleep(tvc, flag);
                    goto findloop;
                }