]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
macos bulkstat support
authorDerrick Brashear <shadow@dementia.org>
Fri, 12 Feb 2010 21:46:33 +0000 (16:46 -0500)
committerDerrick Brashear <shadow@dementia.org>
Wed, 17 Feb 2010 05:32:46 +0000 (21:32 -0800)
add KPI-based bulkstat support for macos

Change-Id: I6d9afa968db5930d392a6298dc5094f3cb500a1b
Reviewed-on: http://gerrit.openafs.org/1303
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
src/afs/DARWIN/osi_prototypes.h
src/afs/DARWIN/osi_vfsops.c
src/afs/DARWIN/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs_callback.c
src/afs/afs_pioctl.c
src/afs/afs_vcache.c

index 4a9b6b251837cb49c0e20ac6953317eac95bb813..5cd4663b1c1bf20e60c1f81994c1a0c74e245b0c 100644 (file)
@@ -35,7 +35,8 @@ extern void osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size);
 extern int osi_VM_Setup(struct vcache *avc, int force);
 
 /* osi_vnodeops.c */
-extern int afs_darwin_getnewvnode(struct vcache *avc);
+extern int afs_darwin_getnewvnode(struct vcache *avc, int recycle);
 extern int afs_darwin_finalizevnode(struct vcache *avc, struct vnode *parent, 
-                                     struct componentname *cnp, int isroot);
+                                   struct componentname *cnp, int isroot,
+                                   int locked);
 #endif /* _OSI_PROTO_H_ */
index 48df74c284d7228bd27802aaade612cfddce3f95..4076b7144e26c12320d7a7e661e37decfd2eaecf 100644 (file)
@@ -276,7 +276,7 @@ afs_root(struct mount *mp, struct vnode **vpp)
 #ifdef AFS_DARWIN80_ENV
             if (tvp) {
                AFS_GUNLOCK();
-                error = afs_darwin_finalizevnode(tvp, NULL, NULL, 1);
+                error = afs_darwin_finalizevnode(tvp, NULL, NULL, 1, 0);
                AFS_GLOCK();
                 if (error)
                    tvp = NULL;
index 911ac2900f6d77581c3bfa1494a5cb219b0f9d61..77c2e4cc016ce2b23d7149bff1cf6a13c2dc72cd 100644 (file)
@@ -343,7 +343,7 @@ afs_vop_lookup(ap)
        return (error);
     }
 #ifdef AFS_DARWIN80_ENV
-    if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0))) {
+    if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0, 0))) {
        DROPNAME();
        *ap->a_vpp = 0;
        return error;
@@ -428,7 +428,7 @@ afs_vop_create(ap)
 
     if (vcp) {
 #ifdef AFS_DARWIN80_ENV
-        if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0))) {
+      if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0, 0))) {
            DROPNAME();
            *ap->a_vpp=0;
            return error;
@@ -1482,7 +1482,7 @@ afs_vop_mkdir(ap)
     }
     if (vcp) {
 #ifdef AFS_DARWIN80_ENV
-        afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0);
+       afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0, 0);
 #endif
        *ap->a_vpp = AFSTOV(vcp);
 #ifndef AFS_DARWIN80_ENV /* XXX needed for multi-mount thing, but can't have it yet */
@@ -2010,7 +2010,7 @@ afs_vop_cmap(ap)
 #endif
 
 int
-afs_darwin_getnewvnode(struct vcache *avc)
+afs_darwin_getnewvnode(struct vcache *avc, int recycle)
 {
 #ifdef AFS_DARWIN80_ENV
     vnode_t vp;
@@ -2029,7 +2029,8 @@ afs_darwin_getnewvnode(struct vcache *avc)
       vnode_addfsref(vp);
       vnode_ref(vp);
       avc->v = vp;
-      vnode_recycle(vp); /* terminate as soon as iocount drops */
+      if (recycle)
+         vnode_recycle(vp); /* terminate as soon as iocount drops */
       avc->f.states |= CDeadVnode;
     }
     return error;
@@ -2046,14 +2047,16 @@ afs_darwin_getnewvnode(struct vcache *avc)
 /* if this fails, then tvc has been unrefed and may have been freed. 
    Don't touch! */
 int 
-afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot)
+afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot, int locked)
 {
     vnode_t ovp;
     vnode_t nvp;
     int error;
     struct vnode_fsparam par;
-    AFS_GLOCK();
-    ObtainWriteLock(&avc->lock,325);
+    if (!locked) {
+       AFS_GLOCK();
+       ObtainWriteLock(&avc->lock,325);
+    }
     ovp = AFSTOV(avc);
     if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) {
         AFS_GUNLOCK();
@@ -2066,8 +2069,10 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
        /* Can end up in reclaim... drop GLOCK */
         vnode_rele(ovp);
        AFS_GLOCK();
-        ReleaseWriteLock(&avc->lock);
-       AFS_GUNLOCK();
+       if (!locked) {
+           ReleaseWriteLock(&avc->lock);
+           AFS_GUNLOCK();
+       }
         return 0;
     }
     if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
@@ -2092,6 +2097,9 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
        if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
            printf("vcache %p should not be CDeadVnode", avc);
        if (avc->v == ovp) {
+           if (avc->f.states & CBulkFetching) {
+               vnode_recycle(ovp);
+           }
            if (!(avc->f.states & CVInit)) {
                vnode_clearfsnode(ovp);
                vnode_removefsref(ovp);
@@ -2103,10 +2111,12 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
     vnode_put(ovp);
     vnode_rele(ovp);
     AFS_GLOCK();
-    ReleaseWriteLock(&avc->lock);
+    if (!locked)
+       ReleaseWriteLock(&avc->lock);
     if (!error)
        afs_osi_Wakeup(&avc->f.states);
-    AFS_GUNLOCK();
+    if (!locked)
+       AFS_GUNLOCK();
     return error;
 }
 #endif
index 31a6cc1852d92ee7eaebff79c5af43be9aa53621..be81ff32a3de70c5837da0a49c1a07488ccc814e 100644 (file)
@@ -399,7 +399,7 @@ afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state,
 #ifdef AFS_DARWIN80_ENV
         root_vp->f.m.Type = VDIR;
         AFS_GUNLOCK();
-        code = afs_darwin_finalizevnode(root_vp, NULL, NULL, 0);
+        code = afs_darwin_finalizevnode(root_vp, NULL, NULL, 0, 0);
         AFS_GLOCK();
         if (code) goto done;
         vnode_ref(AFSTOV(root_vp));
@@ -628,6 +628,9 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
 {
     int nentries;              /* # of entries to prefetch */
     int nskip;                 /* # of slots in the LRU queue to skip */
+#ifdef AFS_DARWIN80_ENV
+    struct vnode *lruvp;
+#endif
     struct vcache *lruvcp;     /* vcache ptr of our goal pos in LRU queue */
     struct dcache *dcp;                /* chunk containing the dir block */
     afs_size_t temp;           /* temp for holding chunk length, &c. */
@@ -664,9 +667,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
     dotdot.Cell = 0;
     dotdot.Fid.Unique = 0;
     dotdot.Fid.Vnode = 0;
-#ifdef AFS_DARWIN80_ENV
-    panic("bulkstatus doesn't work on AFS_DARWIN80_ENV. don't call it");
-#endif
+
     /* first compute some basic parameters.  We dont want to prefetch more
      * than a fraction of the cache in any given call, and we want to preserve
      * a portion of the LRU queue in any event, so as to avoid thrashing
@@ -824,15 +825,6 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                goto done;      /* can happen if afs_NewVCache fails */
            }
 
-#ifdef AFS_DARWIN80_ENV
-            if (tvcp->f.states & CVInit) {
-                 /* XXX don't have status yet, so creating the vnode is
-                    not yet useful. we would get CDeadVnode set, and the
-                    upcoming PutVCache will cause the vcache to be flushed &
-                    freed, which in turn means the bulkstatus results won't 
-                    be used */
-            }
-#endif
            /* WARNING: afs_DoBulkStat uses the Length field to store a
             * sequence number for each bulk status request. Under no
             * circumstances should afs_DoBulkStat store a sequence number
@@ -974,9 +966,13 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
        refpanic("Bulkstat VLRU inconsistent");
     }
     for (tq = VLRU.next; tq != &VLRU; tq = QNext(tq)) {
-       if (--nskip <= 0)
-           break;
-       else if (QNext(QPrev(tq)) != tq) {
+       if (--nskip <= 0) {
+#ifdef AFS_DARWIN80_ENV
+           if (!(QTOV(tq)->f.states & CDeadVnode))
+#endif
+               break;
+       }
+       if (QNext(QPrev(tq)) != tq) {
            BStvc = QTOV(tq);
            refpanic("BulkStat VLRU inconsistent");
        }
@@ -992,7 +988,20 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
      * doesn't hurt nearly as much.
      */
     retry = 0;
+#ifdef AFS_DARWIN80_ENV
+    lruvp = AFSTOV(lruvcp);
+    if (vnode_get(lruvp))       /* this bumps ref count */
+       retry = 1;
+    else if (vnode_ref(lruvp)) {
+       AFS_GUNLOCK();
+       /* AFSTOV(lruvcp) may be NULL */
+       vnode_put(lruvp);
+       AFS_GLOCK();
+       retry = 1;
+    }
+#else
     osi_vnhold(lruvcp, &retry);
+#endif
     ReleaseReadLock(&afs_xvcache);     /* could be read lock */
     if (retry)
        goto reskip;
@@ -1143,6 +1152,23 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
                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) {
+           /* passing in a parent hangs getting the vnode lock */
+           code = afs_darwin_finalizevnode(tvcp, NULL, NULL, 0, 1);
+           if (code) {
+               /* It's gonna get recycled - shouldn't happen */
+               tvcp->callback = 0;
+               tvcp->f.states &= ~(CStatd | CUnique);
+               afs_DequeueCallback(tvcp);
+               if ((tvcp->f.states & CForeign) || (vType(tvcp) == VDIR))
+                   osi_dnlc_purgedp(tvcp); /* if it (could be) a directory */
+           } else
+               /* re-acquire the usecount that finalizevnode disposed of */
+               vnode_ref(AFSTOV(tvcp));
+       }
+#endif
 
        ReleaseWriteLock(&tvcp->lock);
        /* finally, we're done with the entry */
@@ -1150,7 +1176,14 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp)
     }                          /* for all files we got back */
 
     /* finally return the pointer into the LRU queue */
+#ifdef AFS_DARWIN80_ENV
+    AFS_GUNLOCK();
+    vnode_put(lruvp);
+    vnode_rele(lruvp);
+    AFS_GLOCK();
+#else
     afs_PutVCache(lruvcp);
+#endif
 
   done:
     /* Be sure to turn off the CBulkFetching flags */
@@ -1194,11 +1227,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_DARWIN80_ENV
-#define AFSDOBULK 0
-#else
 static int AFSDOBULK = 1;
-#endif
 
 int
 #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
index a4ea288ab0b692e4a6b104f9e9589f11e1a0eb8b..ed6754298d2b466588cbb7c0287a8e10ad96133f 100644 (file)
@@ -455,17 +455,17 @@ loop1:
                            afs_osi_Sleep(&tvc->f.states);
                            goto loop1;
                        }
-#ifdef AFS_DARWIN80_ENV
-                       if (tvc->f.states & CDeadVnode) {
-                           ReleaseReadLock(&afs_xvcache);
-                           afs_osi_Sleep(&tvc->f.states);
-                           goto loop1;
-                       }
-#endif
 #if     defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
                        VN_HOLD(AFSTOV(tvc));
 #else
 #ifdef AFS_DARWIN80_ENV
+                       if (tvc->f.states & CDeadVnode) {
+                           if (!(tvc->f.states & CBulkFetching)) {
+                               ReleaseReadLock(&afs_xvcache);
+                               afs_osi_Sleep(&tvc->f.states);
+                               goto loop1;
+                           }
+                       }
                        vp = AFSTOV(tvc);
                        if (vnode_get(vp))
                            continue;
@@ -475,6 +475,11 @@ loop1:
                            AFS_GLOCK();
                            continue;
                        }
+                       if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
+                           AFS_GUNLOCK();
+                           vnode_recycle(AFSTOV(tvc));
+                           AFS_GLOCK();
+                       }
 #else
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
                        osi_vnhold(tvc, 0);
@@ -549,17 +554,17 @@ loop2:
                        afs_osi_Sleep(&tvc->f.states);
                        goto loop2;
                    }
-#ifdef AFS_DARWIN80_ENV
-                   if (tvc->f.states & CDeadVnode) {
-                       ReleaseReadLock(&afs_xvcache);
-                       afs_osi_Sleep(&tvc->f.states);
-                       goto loop2;
-                   }
-#endif
 #if     defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
                    VN_HOLD(AFSTOV(tvc));
 #else
 #ifdef AFS_DARWIN80_ENV
+                   if (tvc->f.states & CDeadVnode) {
+                       if (!(tvc->f.states & CBulkFetching)) {
+                           ReleaseReadLock(&afs_xvcache);
+                           afs_osi_Sleep(&tvc->f.states);
+                           goto loop2;
+                       }
+                   }
                    vp = AFSTOV(tvc);
                    if (vnode_get(vp))
                        continue;
@@ -569,6 +574,11 @@ loop2:
                        AFS_GLOCK();
                        continue;
                    }
+                   if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
+                       AFS_GUNLOCK();
+                       vnode_recycle(AFSTOV(tvc));
+                       AFS_GLOCK();
+                   }
 #else
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
                    osi_vnhold(tvc, 0);
index 79baf27d814ded4122288e7afa6dc87d0bb99b5d..1a387936d1a19edbc382c1bcd254bb48b8fc0381 100644 (file)
@@ -3401,11 +3401,13 @@ DECL_PIOCTL(PFlushVolumeData)
                    goto loop;
                }
 #ifdef AFS_DARWIN80_ENV
-               if (tvc->f.states & CDeadVnode) {
+           if (tvc->f.states & CDeadVnode) {
+               if (!(tvc->f.states & CBulkFetching)) {
                    ReleaseReadLock(&afs_xvcache);
                    afs_osi_Sleep(&tvc->f.states);
                    goto loop;
                }
+           }
 #endif
 #if    defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
                VN_HOLD(AFSTOV(tvc));
@@ -3419,6 +3421,11 @@ DECL_PIOCTL(PFlushVolumeData)
                    AFS_GLOCK();
                    continue;
                }
+               if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
+                   AFS_GUNLOCK();
+                   vnode_recycle(AFSTOV(tvc));
+                   AFS_GLOCK();
+               }
 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
                osi_vnhold(tvc, 0);
 #else
index ade8bc6632acf43b2da62fe2231a5cff1e51999b..81819e1beda157e0f588e7df13a0fa8b8faed25d 100644 (file)
@@ -1026,7 +1026,7 @@ afs_NewVCache_int(struct VenusFid *afid, struct server *serverp, int seq)
 #ifdef AFS_DARWIN_ENV
     ReleaseWriteLock(&afs_xvcache);
     AFS_GUNLOCK();
-    afs_darwin_getnewvnode(tvc);       /* includes one refcount */
+    afs_darwin_getnewvnode(tvc, seq ? 0 : 1);  /* includes one refcount */
     AFS_GLOCK();
     ObtainWriteLock(&afs_xvcache,338);
 #ifdef AFS_DARWIN80_ENV
@@ -2337,11 +2337,13 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
                goto rootvc_loop;
             }
 #ifdef AFS_DARWIN80_ENV
-            if (tvc->f.states & CDeadVnode) {
-               ReleaseSharedLock(&afs_xvcache);
-               afs_osi_Sleep(&tvc->f.states);
-               goto rootvc_loop;
-            }
+           if (tvc->f.states & CDeadVnode) {
+               if (!(tvc->f.states & CBulkFetching)) {
+                   ReleaseSharedLock(&afs_xvcache);
+                   afs_osi_Sleep(&tvc->f.states);
+                   goto rootvc_loop;
+               }
+           }
            tvp = AFSTOV(tvc);
            if (vnode_get(tvp))       /* this bumps ref count */
                continue;
@@ -2352,6 +2354,11 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
                AFS_GLOCK();
                continue;
            }
+           if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
+               AFS_GUNLOCK();
+               vnode_recycle(AFSTOV(tvc));
+               AFS_GLOCK();
+           }
 #endif
            break;
        }
@@ -2885,10 +2892,12 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
                goto findloop;
             }
 #ifdef  AFS_DARWIN80_ENV
-            if (tvc->f.states & CDeadVnode) {
-                findvc_sleep(tvc, flag);
-               goto findloop;
-            }
+           if (tvc->f.states & CDeadVnode) {
+               if (!(tvc->f.states & CBulkFetching)) {
+                   findvc_sleep(tvc, flag);
+                   goto findloop;
+               }
+           }
            tvp = AFSTOV(tvc);
            if (vnode_get(tvp))
                continue;
@@ -2899,6 +2908,11 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
                AFS_GLOCK();
                continue;
            }
+           if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
+               AFS_GUNLOCK();
+               vnode_recycle(AFSTOV(tvc));
+               AFS_GLOCK();
+           }
 #endif
            break;
        }
@@ -3016,11 +3030,13 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
                goto loop;
             }
 #ifdef  AFS_DARWIN80_ENV
-            if (tvc->f.states & CDeadVnode) {
-               ReleaseSharedLock(&afs_xvcache);
-               afs_osi_Sleep(&tvc->f.states);
-               goto loop;
-            }
+           if (tvc->f.states & CDeadVnode) {
+               if (!(tvc->f.states & CBulkFetching)) {
+                   ReleaseSharedLock(&afs_xvcache);
+                   afs_osi_Sleep(&tvc->f.states);
+                   goto loop;
+               }
+           }
            tvp = AFSTOV(tvc);
            if (vnode_get(tvp)) {
                /* This vnode no longer exists. */
@@ -3034,6 +3050,11 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
                AFS_GLOCK();
                continue;
            }
+           if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
+               AFS_GUNLOCK();
+               vnode_recycle(AFSTOV(tvc));
+               AFS_GLOCK();
+           }
 #endif /* AFS_DARWIN80_ENV */
            count++;
            if (found_tvc) {