fs-getcache-show-more-20060615
[openafs.git] / src / afs / afs_pioctl.c
index 18e02d5..2c4599b 100644 (file)
@@ -430,7 +430,7 @@ afs_ioctl(OSI_VN_DECL(tvc), int cmd, void *arg, int flag, cred_t * cr,
    interface call.
    */
 /* AFS_HPUX102 and up uses VNODE ioctl instead */
-#ifndef AFS_HPUX102_ENV
+#if !defined(AFS_HPUX102_ENV) && !defined(AFS_DARWIN80_ENV)
 #if !defined(AFS_SGI_ENV)
 #ifdef AFS_AIX32_ENV
 #ifdef AFS_AIX51_ENV
@@ -817,9 +817,15 @@ afs_pioctl(p, args, retval)
     } *uap = (struct a *)args;
 
     AFS_STATCNT(afs_pioctl);
+#ifdef AFS_DARWIN80_ENV
+    return (afs_syscall_pioctl
+           (uap->path, uap->cmd, uap->cmarg, uap->follow,
+            kauth_cred_get()));
+#else
     return (afs_syscall_pioctl
            (uap->path, uap->cmd, uap->cmarg, uap->follow,
             p->p_cred->pc_ucred));
+#endif
 }
 
 #endif
@@ -967,6 +973,19 @@ afs_syscall_pioctl(path, com, cmarg, follow)
     } else
        vp = NULL;
 
+#if defined(AFS_SUN510_ENV)
+    if (vp && !IsAfsVnode(vp)) {
+       struct vnode *realvp;
+       
+       if (VOP_REALVP(vp, &realvp) == 0) {
+           struct vnode *oldvp = vp;
+           
+           VN_HOLD(realvp);
+           vp = realvp;
+           AFS_RELE(oldvp);
+       }
+    }
+#endif
     /* now make the call if we were passed no file, or were passed an AFS file */
     if (!vp || IsAfsVnode(vp)) {
 #if defined(AFS_SUN5_ENV)
@@ -1186,7 +1205,7 @@ DECL_PIOCTL(PSetAcl)
     AFS_STATCNT(PSetAcl);
     if (!avc)
        return EINVAL;
-    if ((acl.AFSOpaque_len = strlen(ain) + 1) > 1000)
+    if ((acl.AFSOpaque_len = strlen(ain) + 1) > 1024 /* AFSOPAQUEMAX */)
        return EINVAL;
 
     acl.AFSOpaque_val = ain;
@@ -1453,8 +1472,10 @@ DECL_PIOCTL(PSetTokens)
 #else
        struct proc *p = curproc;       /* XXX */
 #endif
+#ifndef AFS_DARWIN80_ENV
        uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
                p->p_pid, p->p_comm);
+#endif
        if (!setpag(p, acred, -1, &pag, 1)) {
 #else
 #ifdef AFS_OSF_ENV
@@ -1669,7 +1690,6 @@ DECL_PIOCTL(PFlush)
     /* now find the disk cache entries */
     afs_TryToSmush(avc, *acred, 1);
     osi_dnlc_purgedp(avc);
-    afs_symhint_inval(avc);
     if (avc->linkData && !(avc->states & CCore)) {
        afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
        avc->linkData = NULL;
@@ -1925,12 +1945,12 @@ DECL_PIOCTL(PCheckServers)
        pcheck = (struct chservinfo *)ain;
        if (pcheck->tinterval >= 0) {
            cp = aout;
-           memcpy(cp, (char *)&PROBE_INTERVAL, sizeof(afs_int32));
+           memcpy(cp, (char *)&afs_probe_interval, sizeof(afs_int32));
            *aoutSize = sizeof(afs_int32);
            if (pcheck->tinterval > 0) {
                if (!afs_osi_suser(*acred))
                    return EACCES;
-               PROBE_INTERVAL = pcheck->tinterval;
+               afs_probe_interval = pcheck->tinterval;
            }
            return 0;
        }
@@ -2155,11 +2175,51 @@ DECL_PIOCTL(PSetCacheSize)
 DECL_PIOCTL(PGetCacheSize)
 {
     afs_int32 results[MAXGCSTATS];
-
+    afs_int32 flags;
+    register struct dcache * tdc;
+    int i, size;
+    
     AFS_STATCNT(PGetCacheSize);
+
+    if (sizeof(afs_int32) == ainSize){
+       memcpy((char *)&flags, ain, sizeof(afs_int32));
+    } else if (0 == ainSize){ 
+       flags = 0;
+    } else {
+       return EINVAL;
+    }
+    
     memset((char *)results, 0, sizeof(results));
     results[0] = afs_cacheBlocks;
     results[1] = afs_blocksUsed;
+    results[2] = afs_cacheFiles;
+    
+    if (1 == flags){
+        for (i = 0; i < afs_cacheFiles; i++) {
+           if (afs_indexFlags[i] & IFFree) results[3]++;
+       }
+    } else if (2 == flags){
+        for (i = 0; i < afs_cacheFiles; i++) {
+           if (afs_indexFlags[i] & IFFree) results[3]++;
+           if (afs_indexFlags[i] & IFEverUsed) results[4]++;
+           if (afs_indexFlags[i] & IFDataMod) results[5]++;
+           if (afs_indexFlags[i] & IFDirtyPages) results[6]++;
+           if (afs_indexFlags[i] & IFAnyPages) results[7]++;
+           if (afs_indexFlags[i] & IFDiscarded) results[8]++;
+
+           tdc = afs_indexTable[i];
+           if (tdc){
+               results[9]++;
+               size = tdc->validPos;
+               if ( 0 < size && size < (1<<12) ) results[10]++;
+               else if (size < (1<<14) ) results[11]++;
+               else if (size < (1<<16) ) results[12]++;
+               else if (size < (1<<18) ) results[13]++;
+               else if (size < (1<<20) ) results[14]++;
+               else if (size >= (1<<20) ) results[15]++;
+           }
+        }
+    }
     memcpy(aout, (char *)results, sizeof(results));
     *aoutSize = sizeof(results);
     return 0;
@@ -2528,6 +2588,10 @@ DECL_PIOCTL(PFlushVolumeData)
     register struct vcache *tvc;
     register struct volume *tv;
     afs_int32 cell, volume;
+    struct afs_q *tq, *uq;
+#ifdef AFS_DARWIN80_ENV
+    vnode_t vp;
+#endif
 
     AFS_STATCNT(PFlushVolumeData);
     if (!avc)
@@ -2542,19 +2606,46 @@ DECL_PIOCTL(PFlushVolumeData)
      * Clear stat'd flag from all vnodes from this volume; this will invalidate all
      * the vcaches associated with the volume.
      */
+ loop:
     ObtainReadLock(&afs_xvcache);
-    for (i = 0; i < VCSIZE; i++) {
-       for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
+    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) {
+                   ReleaseReadLock(&afs_xvcache);
+                   afs_osi_Sleep(&tvc->states);
+                   goto loop;
+               }
+#ifdef AFS_DARWIN80_ENV
+               if (tvc->states & CDeadVnode) {
+                   ReleaseReadLock(&afs_xvcache);
+                   afs_osi_Sleep(&tvc->states);
+                   goto loop;
+               }
+#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);
 #ifdef AFS_BOZONLOCK_ENV
                afs_BozonLock(&tvc->pvnLock, tvc);      /* Since afs_TryToSmush will do a pvn_vptrunc */
@@ -2572,12 +2663,15 @@ DECL_PIOCTL(PFlushVolumeData)
 #ifdef AFS_BOZONLOCK_ENV
                afs_BozonUnlock(&tvc->pvnLock, tvc);
 #endif
+#ifdef AFS_DARWIN80_ENV
+               vnode_put(AFSTOV(tvc));
+#endif
                ObtainReadLock(&afs_xvcache);
+               uq = QPrev(tq);
                /* our tvc ptr is still good until now */
                AFS_FAST_RELE(tvc);
            }
        }
-    }
     ReleaseReadLock(&afs_xvcache);
 
 
@@ -2718,7 +2812,7 @@ DECL_PIOCTL(PSetSysName)
     register struct unixuser *au;
     register afs_int32 pag, error;
     int t, count, num = 0;
-    char **sysnamelist[MAXSYSNAME];
+    char **sysnamelist[MAXNUMSYSNAMES];
 
     AFS_STATCNT(PSetSysName);
     if (!afs_globalVFS) {
@@ -3562,7 +3656,6 @@ DECL_PIOCTL(PFlushMount)
     /* now find the disk cache entries */
     afs_TryToSmush(tvc, *acred, 1);
     osi_dnlc_purgedp(tvc);
-    afs_symhint_inval(tvc);
     if (tvc->linkData && !(tvc->states & CCore)) {
        afs_osi_Free(tvc->linkData, strlen(tvc->linkData) + 1);
        tvc->linkData = NULL;