MacOS: allow cdead vcaches to be found in FindVCache if requested
authorDerrick Brashear <shadow@dementia.org>
Thu, 20 Jan 2011 04:11:11 +0000 (23:11 -0500)
committerDerrick Brashear <shadow@dementia.org>
Fri, 18 Mar 2011 04:32:38 +0000 (21:32 -0700)
if we are trying to find a dead vcache, let it be found, don't immediately
attempt to recycle

FIXES 128511

Change-Id: I7f86f7d4a88e1b89887b64617246e750654b0334
Reviewed-on: http://gerrit.openafs.org/3691
Tested-by: BuildBot <buildbot@rampaginggeek.com>
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 0bc1c06..127d002 100644 (file)
@@ -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);
index 9dd97fc..496b8ea 100644 (file)
@@ -1329,6 +1329,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 adown value of afs_LoopServers */
 #define AFS_LS_UP 0
index d96bfc0..dc6a799 100644 (file)
@@ -2647,6 +2647,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
 
@@ -2656,47 +2657,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)) ||
@@ -2705,6 +2737,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)