cm: address race condition in afs_QueueVCB
[openafs.git] / src / afs / afs_vcache.c
index 284e214..a68af8e 100644 (file)
@@ -40,8 +40,6 @@
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include "afs/sysincludes.h"   /*Standard vendor system headers */
 #include "afsincludes.h"       /*AFS-based standard headers */
@@ -49,10 +47,10 @@ RCSID
 #include "afs/afs_cbqueue.h"
 #include "afs/afs_osidnlc.h"
 
-#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_LINUX22_ENV)
 afs_int32 afs_maxvcount = 0;   /* max number of vcache entries */
 afs_int32 afs_vcount = 0;      /* number of vcache in use now */
-#endif /* AFS_OSF_ENV */
+#endif /* AFS_LINUX22_ENV */
 
 #ifdef AFS_SGI_ENV
 int afsvnumbers = 0;
@@ -86,8 +84,10 @@ int afs_norefpanic = 0;
 
 /* Disk backed vcache definitions 
  * Both protected by xvcache */
+#ifdef AFS_DISCON_ENV
 static int afs_nextVcacheSlot = 0;
 static struct afs_slotlist *afs_freeSlotList = NULL;
+#endif
 
 /* Forward declarations */
 static afs_int32 afs_QueueVCB(struct vcache *avc);
@@ -149,11 +149,6 @@ afs_FlushVCache(struct vcache *avc, int *slept)
     AFS_STATCNT(afs_FlushVCache);
     afs_Trace2(afs_iclSetp, CM_TRACE_FLUSHV, ICL_TYPE_POINTER, avc,
               ICL_TYPE_INT32, avc->f.states);
-#ifdef  AFS_OSF_ENV
-    AFS_GUNLOCK();
-    VN_LOCK(AFSTOV(avc));
-    AFS_GLOCK();
-#endif
 
     code = osi_VM_FlushVCache(avc, slept);
     if (code)
@@ -217,14 +212,7 @@ afs_FlushVCache(struct vcache *avc, int *slept)
     vn_reinit(AFSTOV(avc));
 #endif
     afs_FreeAllAxs(&(avc->Access));
-
-    /* we can't really give back callbacks on RO files, since the
-     * server only tracks them on a per-volume basis, and we don't
-     * know whether we still have some other files from the same
-     * volume. */
-    if ((avc->f.states & CRO) == 0 && avc->callback) {
-       afs_QueueVCB(avc);
-    }
+    afs_QueueVCB(avc);
     ObtainWriteLock(&afs_xcbhash, 460);
     afs_DequeueCallback(avc);  /* remove it from queued callbacks list */
     avc->f.states &= ~(CStatd | CUnique);
@@ -244,7 +232,7 @@ afs_FlushVCache(struct vcache *avc, int *slept)
     else
        afs_evenZaps++;
 
-#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV)
+#if !defined(AFS_LINUX22_ENV)
     /* put the entry in the free list */
     avc->nextfree = freeVCList;
     freeVCList = avc;
@@ -257,31 +245,20 @@ afs_FlushVCache(struct vcache *avc, int *slept)
     afs_vcount--;
     vSetType(avc, VREG);
     if (VREFCOUNT_GT(avc,0)) {
-#if defined(AFS_OSF_ENV)
-       VN_UNLOCK(AFSTOV(avc));
-#endif
        AFS_RELE(AFSTOV(avc));
+       afs_stats_cmperf.vcacheXAllocs--;
     } else {
        if (afs_norefpanic) {
            printf("flush vc refcnt < 1");
            afs_norefpanic++;
-#if defined(AFS_OSF_ENV)
-           (void)vgone(avc, VX_NOSLEEP, NULL);
-           AFS_GLOCK();
-           VN_UNLOCK(AFSTOV(avc));
-#endif
        } else
            osi_Panic("flush vc refcnt < 1");
     }
-#endif /* AFS_OSF_ENV */
+#endif /* AFS_LINUX22_ENV */
     return 0;
 
   bad:
-#ifdef AFS_OSF_ENV
-    VN_UNLOCK(AFSTOV(avc));
-#endif
     return code;
-
 }                              /*afs_FlushVCache */
 
 #ifndef AFS_SGI_ENV
@@ -292,7 +269,7 @@ afs_FlushVCache(struct vcache *avc, int *slept)
  * \param acred
  */
 void
-afs_InactiveVCache(struct vcache *avc, struct AFS_UCRED *acred)
+afs_InactiveVCache(struct vcache *avc, afs_ucred_t *acred)
 {
     AFS_STATCNT(afs_inactive);
     if (avc->f.states & CDirty) {
@@ -322,6 +299,8 @@ afs_InactiveVCache(struct vcache *avc, struct AFS_UCRED *acred)
  * \return The allocated afs_cbr.
  */
 static struct afs_cbr *afs_cbrSpace = 0;
+/* if alloc limit below changes, fix me! */
+static struct afs_cbr *afs_cbrHeads[2];
 struct afs_cbr *
 afs_AllocCBR(void)
 {
@@ -343,6 +322,7 @@ afs_AllocCBR(void)
            }
            tsp[AFS_NCBRS - 1].next = 0;
            afs_cbrSpace = tsp;
+           afs_cbrHeads[afs_stats_cmperf.CallBackAlloced] = tsp;
            afs_stats_cmperf.CallBackAlloced++;
        }
     }
@@ -504,23 +484,34 @@ afs_FlushVCBs(afs_int32 lockit)
  *     Called when the xvcache lock is already held.
  *
  * \param avc vcache entry
- * \return 0 for success < 0 otherwise.
+ * \return 1 if queued, 0 otherwise
  */
 
 static afs_int32
 afs_QueueVCB(struct vcache *avc)
 {
+    int queued = 0;
     struct server *tsp;
     struct afs_cbr *tcbp;
 
     AFS_STATCNT(afs_QueueVCB);
+
+    MObtainWriteLock(&afs_xvcb, 274);
+
+    /* we can't really give back callbacks on RO files, since the
+     * server only tracks them on a per-volume basis, and we don't
+     * know whether we still have some other files from the same
+     * volume. */
+    if (!((avc->f.states & CRO) == 0 && avc->callback)) {
+        goto done;
+    }
+
     /* The callback is really just a struct server ptr. */
     tsp = (struct server *)(avc->callback);
 
     /* we now have a pointer to the server, so we just allocate
      * a queue entry and queue it.
      */
-    MObtainWriteLock(&afs_xvcb, 274);
     tcbp = afs_AllocCBR();
     tcbp->fid = avc->f.fid.Fid;
 
@@ -532,10 +523,12 @@ afs_QueueVCB(struct vcache *avc)
     tcbp->pprev = &tsp->cbrs;
 
     afs_InsertHashCBR(tcbp);
+    queued = 1;
 
+ done:
     /* now release locks and return */
     MReleaseWriteLock(&afs_xvcb);
-    return 0;
+    return queued;
 }
 
 
@@ -621,62 +614,24 @@ afs_FlushReclaimedVcaches(void)
 #endif
 }
 
-/*!
- *   This routine is responsible for allocating a new cache entry
- * from the free list.  It formats the cache entry and inserts it
- * into the appropriate hash tables.  It must be called with
- * afs_xvcache write-locked so as to prevent several processes from
- * trying to create a new cache entry simultaneously.
- *
- * LOCK: afs_NewVCache  afs_xvcache W
- *
- * \param afid The file id of the file whose cache entry is being created.
- *
- * \return The new vcache struct.
- */
-struct vcache *
-afs_NewVCache(struct VenusFid *afid, struct server *serverp)
+int
+afs_ShakeLooseVCaches(afs_int32 anumber)
 {
+#if defined(AFS_LINUX22_ENV)
+    afs_int32 i;
     struct vcache *tvc;
-    afs_int32 i, j;
-    afs_int32 anumber = VCACHE_FREE;
-#ifdef AFS_AIX_ENV
-    struct gnode *gnodepnt;
-#endif
-#ifdef AFS_OSF_ENV
-    struct vcache *nvc;
-#endif /* AFS_OSF_ENV */
     struct afs_q *tq, *uq;
     int code, fv_slept;
+    afs_int32 target = anumber;
 
-    AFS_STATCNT(afs_NewVCache);
-
-    afs_FlushReclaimedVcaches();
-
-#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV)
-# if defined(AFS_OSF30_ENV) || defined(AFS_LINUX22_ENV)
-    if (afs_vcount >= afs_maxvcount)
-# else
-    /*
-     * If we are using > 33 % of the total system vnodes for AFS vcache
-     * entries or we are using the maximum number of vcache entries,
-     * then free some.  (if our usage is > 33% we should free some, if
-     * our usage is > afs_maxvcount, set elsewhere to 0.5*nvnode,
-     * we _must_ free some -- no choice).
-     */
-    if (((3 * afs_vcount) > nvnode) || (afs_vcount >= afs_maxvcount))
-# endif
-    {
-       int i;
-       char *panicstr;
-
+    if (afsd_dynamic_vcaches || afs_vcount >= afs_maxvcount) {
        i = 0;
        for (tq = VLRU.prev; tq != &VLRU && anumber > 0; tq = uq) {
            tvc = QTOV(tq);
            uq = QPrev(tq);
            if (tvc->f.states & CVFlushed) {
                refpanic("CVFlushed on VLRU");
-           } else if (i++ > afs_maxvcount) {
+           } else if (!afsd_dynamic_vcaches && i++ > afs_maxvcount) {
                refpanic("Exceeded pool of AFS vnodes(VLRU cycle?)");
            } else if (QNext(uq) != tq) {
                refpanic("VLRU inconsistent");
@@ -684,14 +639,14 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
                refpanic("refcnt 0 on VLRU");
            }
 
-# if defined(AFS_LINUX22_ENV)
+#if defined(AFS_LINUX22_ENV)
            if (tvc != afs_globalVp && VREFCOUNT(tvc) > 1 && tvc->opens == 0) {
                 struct dentry *dentry;
                 struct list_head *cur, *head;
                 AFS_GUNLOCK();
-#  if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX24_ENV)
                 spin_lock(&dcache_lock);
-#  endif /* AFS_LINUX24_ENV */
+#endif /* AFS_LINUX24_ENV */
                head = &(AFSTOV(tvc))->i_dentry;
 
 restart:
@@ -704,27 +659,27 @@ restart:
 
                    dget_locked(dentry);
 
-#  if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX24_ENV)
                    spin_unlock(&dcache_lock);
-#  endif /* AFS_LINUX24_ENV */
+#endif /* AFS_LINUX24_ENV */
                    if (d_invalidate(dentry) == -EBUSY) {
                        dput(dentry);
                        /* perhaps lock and try to continue? (use cur as head?) */
                        goto inuse;
                    }
                    dput(dentry);
-#  if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX24_ENV)
                    spin_lock(&dcache_lock);
-#  endif /* AFS_LINUX24_ENV */
+#endif /* AFS_LINUX24_ENV */
                    goto restart;
                }                   
-#  if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX24_ENV)
                spin_unlock(&dcache_lock);
-#  endif /* AFS_LINUX24_ENV */
+#endif /* AFS_LINUX24_ENV */
            inuse:
                AFS_GLOCK();
            }
-# endif /* AFS_LINUX22_ENV */
+#endif /* AFS_LINUX22_ENV */
 
            if (VREFCOUNT_GT(tvc,0) && !VREFCOUNT_GT(tvc,1) &&
                tvc->opens == 0
@@ -742,47 +697,78 @@ restart:
            if (tq == uq)
                break;
        }
-       if (anumber == VCACHE_FREE) {
-           printf("afs_NewVCache: warning none freed, using %d of %d\n",
+       if (!afsd_dynamic_vcaches && anumber == target) {
+           printf("afs_ShakeLooseVCaches: warning none freed, using %d of %d\n",
                   afs_vcount, afs_maxvcount);
-           if (afs_vcount >= afs_maxvcount) {
-               printf("afs_NewVCache - none freed\n");
-               return NULL;
-           }
        }
     } /* finished freeing up space */
+/*
+    printf("recycled %d entries\n", target-anumber);
+*/
+#endif
+    return 0;
+}
 
 /* Alloc new vnode. */
-#if defined(AFS_LINUX22_ENV)
+
+static struct vcache *
+afs_AllocVCache(void) 
 {
+    struct vcache *tvc;
+#if defined(AFS_LINUX22_ENV)
     struct inode *ip;
 
     AFS_GUNLOCK();
     ip = new_inode(afs_globalVFS);
     if (!ip)
-       osi_Panic("afs_NewVCache: no more inodes");
+       osi_Panic("afs_AllocVCache: no more inodes");
     AFS_GLOCK();
-#  if defined(STRUCT_SUPER_HAS_ALLOC_INODE)
+#if defined(STRUCT_SUPER_HAS_ALLOC_INODE)
     tvc = VTOAFS(ip);
-#  else
+#else
     tvc = afs_osi_Alloc(sizeof(struct vcache));
     ip->u.generic_ip = tvc;
     tvc->v = ip;
-#  endif
-}
-# else
-    AFS_GUNLOCK();
-    if (getnewvnode(MOUNT_AFS, &Afs_vnodeops, &nvc)) {
-       /* What should we do ???? */
-       osi_Panic("afs_NewVCache: no more vnodes");
-    }
-    AFS_GLOCK();
+#endif
 
-    tvc = nvc;
-    tvc->nextfree = NULL;
-# endif
     afs_vcount++;
 
+    /* track the peak */
+    if (afsd_dynamic_vcaches && afs_maxvcount < afs_vcount) {
+       afs_maxvcount = afs_vcount;
+       /*printf("peak vnodes: %d\n", afs_maxvcount);*/
+    }
+
+    afs_stats_cmperf.vcacheXAllocs++;  /* count in case we have a leak */
+#else
+    /* none free, making one is better than a panic */
+    afs_stats_cmperf.vcacheXAllocs++;  /* count in case we have a leak */
+    tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache));
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
+    tvc->v = NULL; /* important to clean this, or use memset 0 */
+#endif
+#ifdef KERNEL_HAVE_PIN
+    pin((char *)tvc, sizeof(struct vcache));   /* XXX */
+#endif
+#if defined(AFS_SGI_ENV)
+    {
+       char name[METER_NAMSZ];
+       memset(tvc, 0, sizeof(struct vcache));
+       tvc->v.v_number = ++afsvnumbers;
+       tvc->vc_rwlockid = OSI_NO_LOCKID;
+       initnsema(&tvc->vc_rwlock, 1,
+                 makesname(name, "vrw", tvc->v.v_number));
+#ifndef        AFS_SGI53_ENV
+       initnsema(&tvc->v.v_sync, 0,
+                 makesname(name, "vsy", tvc->v.v_number));
+#endif
+#ifndef AFS_SGI62_ENV
+       initnlock(&tvc->v.v_lock,
+                 makesname(name, "vlk", tvc->v.v_number));
+#endif
+    }
+#endif /* AFS_SGI_ENV */
+#endif
 #ifdef AFS_DISCON_ENV
     /* If we create a new inode, we either give it a new slot number,
      * or if one's available, use a slot number from the slot free list
@@ -799,7 +785,50 @@ restart:
     }
 #endif
 
-#else /* AFS_OSF_ENV || AFS_LINUX22_ENV */
+    return tvc;
+}
+
+/*!
+ *   This routine is responsible for allocating a new cache entry
+ * from the free list.  It formats the cache entry and inserts it
+ * into the appropriate hash tables.  It must be called with
+ * afs_xvcache write-locked so as to prevent several processes from
+ * trying to create a new cache entry simultaneously.
+ *
+ * LOCK: afs_NewVCache  afs_xvcache W
+ *
+ * \param afid The file id of the file whose cache entry is being created.
+ *
+ * \return The new vcache struct.
+ */
+struct vcache *
+afs_NewVCache(struct VenusFid *afid, struct server *serverp)
+{
+    struct vcache *tvc;
+    afs_int32 i, j;
+    afs_int32 anumber = VCACHE_FREE;
+#ifdef AFS_AIX_ENV
+    struct gnode *gnodepnt;
+#endif
+#if !defined(AFS_LINUX22_ENV)
+    struct afs_q *tq, *uq;
+    int code, fv_slept;
+#endif
+
+    AFS_STATCNT(afs_NewVCache);
+
+    afs_FlushReclaimedVcaches();
+
+#if defined(AFS_LINUX22_ENV)
+    if(!afsd_dynamic_vcaches) {
+       afs_ShakeLooseVCaches(anumber);
+       if (afs_vcount >= afs_maxvcount) {
+           printf("afs_NewVCache - none freed\n");
+           return NULL;
+       }
+    }
+    tvc = afs_AllocVCache();
+#else /* AFS_LINUX22_ENV */
     /* pull out a free cache entry */
     if (!freeVCList) {
         int loop = 0;
@@ -819,13 +848,13 @@ restart:
             }
 
            if (!VREFCOUNT_GT(tvc,0)
-# if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) && !defined(AFS_DARWIN80_ENV)
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) && !defined(AFS_DARWIN80_ENV)
                || ((VREFCOUNT(tvc) == 1) && 
                    (UBCINFOEXISTS(AFSTOV(tvc))))
-# endif
+#endif
                && tvc->opens == 0 && (tvc->f.states & CUnlinkedDel) == 0) {
-# if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
-#  ifdef AFS_DARWIN80_ENV
+#if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#ifdef AFS_DARWIN80_ENV
                vnode_t tvp = AFSTOV(tvc);
                /* VREFCOUNT_GT only sees usecounts, not iocounts */
                /* so this may fail to actually recycle the vnode now */
@@ -853,7 +882,7 @@ restart:
                    code = EBUSY;
                } else
                    code = 0;
-#  else /* AFS_DARWIN80_ENV */
+#else /* AFS_DARWIN80_ENV */
                 /*
                  * vgone() reclaims the vnode, which calls afs_FlushVCache(),
                  * then it puts the vnode on the free list.
@@ -866,10 +895,10 @@ restart:
                 fv_slept = 0;
                 code = 0;
                 AFS_GLOCK();
-#  endif
-# else /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */
+#endif
+#else /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */
                 code = afs_FlushVCache(tvc, &fv_slept);
-# endif /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */
+#endif /* AFS_DARWIN80_ENV || AFS_XBSD_ENV */
                if (code == 0) {
                    anumber--;
                }
@@ -887,76 +916,34 @@ restart:
     } /* end of if (!freeVCList) */
 
     if (!freeVCList) {
-       /* none free, making one is better than a panic */
-       afs_stats_cmperf.vcacheXAllocs++;       /* count in case we have a leak */
-       tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache));
-# if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
-       tvc->v = NULL; /* important to clean this, or use memset 0 */
-# endif
-# ifdef        KERNEL_HAVE_PIN
-       pin((char *)tvc, sizeof(struct vcache));        /* XXX */
-# endif
-
-#ifdef AFS_DISCON_ENV
-       /* If we create a new inode, we either give it a new slot number,
-         * or if one's available, use a slot number from the slot free list
-         */
-        if (afs_freeSlotList != NULL) {
-           struct afs_slotlist *tmp;
-       
-            tvc->diskSlot = afs_freeSlotList->slot;
-            tmp = afs_freeSlotList;
-           afs_freeSlotList = tmp->next;
-           afs_osi_Free(tmp, sizeof(struct afs_slotlist));
-        } else {
-           tvc->diskSlot = afs_nextVcacheSlot++;
-        }
-#endif
-# if defined(AFS_SGI_ENV)
-       {
-           char name[METER_NAMSZ];
-           memset(tvc, 0, sizeof(struct vcache));
-           tvc->v.v_number = ++afsvnumbers;
-           tvc->vc_rwlockid = OSI_NO_LOCKID;
-           initnsema(&tvc->vc_rwlock, 1,
-                     makesname(name, "vrw", tvc->v.v_number));
-#ifndef        AFS_SGI53_ENV
-           initnsema(&tvc->v.v_sync, 0,
-                     makesname(name, "vsy", tvc->v.v_number));
-#endif
-#ifndef AFS_SGI62_ENV
-           initnlock(&tvc->v.v_lock,
-                     makesname(name, "vlk", tvc->v.v_number));
-#endif
-       }
-#endif /* AFS_SGI_ENV */
+       tvc = afs_AllocVCache();
     } else {
        tvc = freeVCList;       /* take from free list */
        freeVCList = tvc->nextfree;
        tvc->nextfree = NULL;
     } /* end of if (!freeVCList) */
 
-#endif /* AFS_OSF_ENV */
+#endif /* AFS_LINUX22_ENV */
 
 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
     if (tvc->v)
        panic("afs_NewVCache(): free vcache with vnode attached");
 #endif
 
-#if !defined(AFS_SGI_ENV) && !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV)
+#if !defined(AFS_SGI_ENV) && !defined(AFS_LINUX22_ENV)
 
-# if AFS_DISCON_ENV
+#if defined(AFS_DISCON_ENV)
     /* We need to preserve the slot that we're being stored into on
      * disk */
     { 
        afs_uint32 slot;
         slot = tvc->diskSlot;
-       memset((char *)tvc, 0, sizeof(struct vcache));
+       memset(tvc, 0, sizeof(struct vcache));
        tvc->diskSlot = slot;
     }
-# else
-    memset((char *)tvc, 0, sizeof(struct vcache));
-# endif
+#else
+    memset(tvc, 0, sizeof(struct vcache));
+#endif
 
 #else
     tvc->uncred = 0;
@@ -979,6 +966,9 @@ restart:
     tvc->f.fid = *afid;
     tvc->asynchrony = -1;
     tvc->vc_error = 0;
+#if defined(AFS_LINUX26_ENV)
+    tvc->cred = NULL;
+#endif
 #ifdef AFS_TEXT_ENV
     tvc->flushDV.low = tvc->flushDV.high = AFS_MAXDV;
 #endif
@@ -1069,14 +1059,13 @@ restart:
     }
 #endif
 
-#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_LINUX22_ENV)
     /* Hold it for the LRU (should make count 2) */
     VN_HOLD(AFSTOV(tvc));
-#else /* AFS_OSF_ENV */
-#if !(defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV))
+#elif !(defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV))
     VREFCOUNT_SET(tvc, 1);     /* us */
-#endif /* AFS_XBSD_ENV */
-#endif /* AFS_OSF_ENV */
+#endif
+
 #ifdef AFS_AIX32_ENV
     LOCK_INIT(&tvc->pvmlock, "vcache pvmlock");
     tvc->vmh = tvc->segid = NULL;
@@ -1115,7 +1104,7 @@ restart:
     /* Don't forget to free the gnode space */
     tvc->v.v_gnode = gnodepnt =
        (struct gnode *)osi_AllocSmallSpace(sizeof(struct gnode));
-    memset((char *)gnodepnt, 0, sizeof(struct gnode));
+    memset(gnodepnt, 0, sizeof(struct gnode));
 #endif
 #ifdef AFS_SGI64_ENV
     memset((void *)&(tvc->vc_bhv_desc), 0, sizeof(tvc->vc_bhv_desc));
@@ -1169,14 +1158,6 @@ restart:
     tvc->v.v_next = gnodepnt->gn_vnode;        /*Single vnode per gnode for us! */
     gnodepnt->gn_vnode = &tvc->v;
 #endif
-#if    defined(AFS_DUX40_ENV)
-    insmntque(tvc, afs_globalVFS, &afs_ubcops);
-#else
-#ifdef  AFS_OSF_ENV
-    /* Is this needed??? */
-    insmntque(tvc, afs_globalVFS);
-#endif /* AFS_OSF_ENV */
-#endif /* AFS_DUX40_ENV */
 #ifdef AFS_FBSD70_ENV
 #ifndef AFS_FBSD80_ENV /* yup.  they put it back. */
     insmntque(AFSTOV(tvc), afs_globalVFS);
@@ -1203,7 +1184,7 @@ restart:
 #endif /* AFS_SGI_ENV */
     tvc->dchint = NULL;
     osi_dnlc_purgedp(tvc);     /* this may be overkill */
-    memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q));
+    memset(&(tvc->callsort), 0, sizeof(struct afs_q));
     tvc->slocks = NULL;
     tvc->f.states &=~ CVInit;
     afs_osi_Wakeup(&tvc->f.states);
@@ -1227,7 +1208,7 @@ afs_FlushActiveVcaches(register afs_int32 doflocks)
     register int i;
     register struct afs_conn *tc;
     register afs_int32 code;
-    register struct AFS_UCRED *cred = NULL;
+    afs_ucred_t *cred = NULL;
     struct vrequest treq, ureq;
     struct AFSVolSync tsync;
     int didCore;
@@ -1299,7 +1280,7 @@ afs_FlushActiveVcaches(register afs_int32 doflocks)
                if (tvc->f.states & CCore) {
                    tvc->f.states &= ~CCore;
                    /* XXXX Find better place-holder for cred XXXX */
-                   cred = (struct AFS_UCRED *)tvc->linkData;
+                   cred = (afs_ucred_t *)tvc->linkData;
                    tvc->linkData = NULL;       /* XXX */
                    afs_InitReq(&ureq, cred);
                    afs_Trace2(afs_iclSetp, CM_TRACE_ACTCCORE,
@@ -1404,14 +1385,6 @@ afs_VerifyVCache2(struct vcache *avc, struct vrequest *areq)
 
     AFS_STATCNT(afs_VerifyVCache);
 
-#if defined(AFS_OSF_ENV)
-    ObtainReadLock(&avc->lock);
-    if (afs_IsWired(avc)) {
-       ReleaseReadLock(&avc->lock);
-       return 0;
-    }
-    ReleaseReadLock(&avc->lock);
-#endif /* AFS_OSF_ENV */
     /* otherwise we must fetch the status info */
 
     ObtainWriteLock(&avc->lock, 53);
@@ -1635,12 +1608,12 @@ int afs_WriteVCacheDiscon(register struct vcache *avc,
 
        if (astatus->Mask & AFS_SETOWNER) {
                printf("Not allowed yet. \n");
-               //avc->f.m.Owner = astatus->Owner;
+               /*avc->f.m.Owner = astatus->Owner;*/
        }
 
        if (astatus->Mask & AFS_SETGROUP) {
                printf("Not allowed yet. \n");
-               //avc->f.m.Group =  astatus->Group;
+               /*avc->f.m.Group =  astatus->Group;*/
        }
 
        if (astatus->Mask & AFS_SETMODE) {
@@ -1910,7 +1883,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        newvcache = 1;
 
        ConvertWToSLock(&afs_xvcache);
-       if (!tvc)
+       if (tvc == NULL)
        {
                ReleaseSharedLock(&afs_xvcache);
                return NULL;
@@ -1927,12 +1900,6 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        ReleaseWriteLock(&tvc->lock);
        return tvc;
     }
-#if defined(AFS_OSF_ENV)
-    if (afs_IsWired(tvc)) {
-       ReleaseWriteLock(&tvc->lock);
-       return tvc;
-    }
-#endif /* AFS_OSF_ENV */
 #ifdef AFS_DARWIN80_ENV
 /* Darwin 8.0 only has bufs in nfs, so we shouldn't have to worry about them.
    What about ubc? */
@@ -2299,9 +2266,6 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
     struct AFSCallBack CallBack;
     struct AFSVolSync tsync;
     int origCBs = 0;
-#ifdef AFS_OSF_ENV
-    int vg;
-#endif
 #ifdef AFS_DARWIN80_ENV
     vnode_t tvp;
 #endif
@@ -2343,17 +2307,6 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
                afs_osi_Sleep(&tvc->f.states);
                goto rootvc_loop;
             }
-#ifdef AFS_OSF_ENV
-           /* Grab this vnode, possibly reactivating from the free list */
-           /* for the present (95.05.25) everything on the hash table is
-            * definitively NOT in the free list -- at least until afs_reclaim
-            * can be safely implemented */
-           AFS_GUNLOCK();
-           vg = vget(AFSTOV(tvc));     /* this bumps ref count */
-           AFS_GLOCK();
-           if (vg)
-               continue;
-#endif /* AFS_OSF_ENV */
 #ifdef AFS_DARWIN80_ENV
             if (tvc->f.states & CDeadVnode) {
                ReleaseSharedLock(&afs_xvcache);
@@ -2377,10 +2330,6 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
 
     if (!haveStatus && (!tvc || !(tvc->f.states & CStatd))) {
        /* Mount point no longer stat'd or unknown. FID may have changed. */
-#ifdef AFS_OSF_ENV
-       if (tvc)
-           AFS_RELE(AFSTOV(tvc));
-#endif
        getNewFid = 1;
        ReleaseSharedLock(&afs_xvcache);
 #ifdef AFS_DARWIN80_ENV
@@ -2410,9 +2359,9 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq,
        if (cached)
            *cached = 1;
        afs_stats_cmperf.vcacheHits++;
-#if    defined(AFS_OSF_ENV) || defined(AFS_DARWIN80_ENV)
+#if    defined(AFS_DARWIN80_ENV)
        /* we already bumped the ref count in the for loop above */
-#else /* AFS_OSF_ENV */
+#else /* AFS_DARWIN80_ENV */
        osi_vnhold(tvc, 0);
 #endif
        UpgradeSToWLock(&afs_xvcache, 24);
@@ -2828,7 +2777,7 @@ afs_PutVCache(register struct vcache *avc)
  * \note avc must be write locked on entry
  */
 void
-afs_ResetVCache(struct vcache *avc, struct AFS_UCRED *acred) {
+afs_ResetVCache(struct vcache *avc, afs_ucred_t *acred) {
     ObtainWriteLock(&afs_xcbhash, 456);
     afs_DequeueCallback(avc);
     avc->f.states &= ~(CStatd | CDirty);    /* next reference will re-stat */
@@ -2892,9 +2841,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
 
     register struct vcache *tvc;
     afs_int32 i;
-#if defined( AFS_OSF_ENV)
-    int vg;
-#endif
 #ifdef AFS_DARWIN80_ENV
     vnode_t tvp;
 #endif
@@ -2909,14 +2855,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
                findvc_sleep(tvc, flag);
                goto findloop;
             }
-#ifdef  AFS_OSF_ENV
-           /* Grab this vnode, possibly reactivating from the free list */
-           AFS_GUNLOCK();
-           vg = vget(AFSTOV(tvc));
-           AFS_GLOCK();
-           if (vg)
-               continue;
-#endif /* AFS_OSF_ENV */
 #ifdef  AFS_DARWIN80_ENV
             if (tvc->f.states & CDeadVnode) {
                 findvc_sleep(tvc, flag);
@@ -2941,7 +2879,7 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
     if (tvc) {
        if (retry)
            *retry = 0;
-#if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN80_ENV)
+#if !defined(AFS_DARWIN80_ENV)
        osi_vnhold(tvc, retry); /* already held, above */
        if (retry && *retry)
            return 0;
@@ -3026,9 +2964,6 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
     afs_int32 i;
     afs_int32 count = 0;
     struct vcache *found_tvc = NULL;
-#ifdef  AFS_OSF_ENV
-    int vg;
-#endif
 #ifdef AFS_DARWIN80_ENV
     vnode_t tvp;
 #endif
@@ -3051,16 +2986,6 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
                afs_osi_Sleep(&tvc->f.states);
                goto loop;
             }
-#ifdef  AFS_OSF_ENV
-           /* Grab this vnode, possibly reactivating from the free list */
-           AFS_GUNLOCK();
-           vg = vget(AFSTOV(tvc));
-           AFS_GLOCK();
-           if (vg) {
-               /* This vnode no longer exists. */
-               continue;
-           }
-#endif /* AFS_OSF_ENV */
 #ifdef  AFS_DARWIN80_ENV
             if (tvc->f.states & CDeadVnode) {
                ReleaseSharedLock(&afs_xvcache);
@@ -3084,11 +3009,6 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
            count++;
            if (found_tvc) {
                /* Duplicates */
-#ifdef AFS_OSF_ENV
-               /* Drop our reference counts. */
-               vrele(AFSTOV(tvc));
-               vrele(AFSTOV(found_tvc));
-#endif
                afs_duplicate_nfs_fids++;
                ReleaseSharedLock(&afs_xvcache);
 #ifdef AFS_DARWIN80_ENV
@@ -3116,10 +3036,8 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
            goto loop;
        }
 #else
-#if !defined(AFS_OSF_ENV)
        osi_vnhold(tvc, (int *)0);      /* already held, above */
 #endif
-#endif
        /*
         * We obtained the xvcache lock above.
         */
@@ -3175,32 +3093,28 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid)
 void
 afs_vcacheInit(int astatSize)
 {
+#if !defined(AFS_LINUX22_ENV)
     register struct vcache *tvp;
+#endif
     int i;
-#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV)
-    if (!afs_maxvcount) {
 #if defined(AFS_LINUX22_ENV)
+    if (!afs_maxvcount) {
        afs_maxvcount = astatSize;      /* no particular limit on linux? */
-#elif defined(AFS_OSF30_ENV)
-       afs_maxvcount = max_vnodes / 2; /* limit ourselves to half the total */
-#else
-       afs_maxvcount = nvnode / 2;     /* limit ourselves to half the total */
-#endif
        if (astatSize < afs_maxvcount) {
            afs_maxvcount = astatSize;
        }
     }
-#else /* AFS_OSF_ENV */
+#else /* AFS_LINUX22_ENV */
     freeVCList = NULL;
 #endif
 
     AFS_RWLOCK_INIT(&afs_xvcache, "afs_xvcache");
     LOCK_INIT(&afs_xvcb, "afs_xvcb");
 
-#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV)
+#if !defined(AFS_LINUX22_ENV)
     /* Allocate and thread the struct vcache entries */
     tvp = (struct vcache *)afs_osi_Alloc(astatSize * sizeof(struct vcache));
-    memset((char *)tvp, 0, sizeof(struct vcache) * astatSize);
+    memset(tvp, 0, sizeof(struct vcache) * astatSize);
 
     Initial_freeVCList = tvp;
     freeVCList = &(tvp[0]);
@@ -3208,9 +3122,9 @@ afs_vcacheInit(int astatSize)
        tvp[i].nextfree = &(tvp[i + 1]);
     }
     tvp[astatSize - 1].nextfree = NULL;
-#ifdef  KERNEL_HAVE_PIN
+# ifdef  KERNEL_HAVE_PIN
     pin((char *)tvp, astatSize * sizeof(struct vcache));       /* XXX */
-#endif
+# endif
 #endif
 
 #if defined(AFS_SGI_ENV)
@@ -3242,15 +3156,16 @@ void
 shutdown_vcache(void)
 {
     int i;
-    struct afs_cbr *tsp, *nsp;
+    struct afs_cbr *tsp;
     /*
-     * XXX We may potentially miss some of the vcaches because if when there're no
-     * free vcache entries and all the vcache entries are active ones then we allocate
-     * an additional one - admittedly we almost never had that occur.
+     * XXX We may potentially miss some of the vcaches because if when
+     * there are no free vcache entries and all the vcache entries are active
+     * ones then we allocate an additional one - admittedly we almost never
+     * had that occur.
      */
 
     {
-       register struct afs_q *tq, *uq;
+       register struct afs_q *tq, *uq = NULL;
        register struct vcache *tvc;
        for (tq = VLRU.prev; tq != &VLRU; tq = uq) {
            tvc = QTOV(tq);
@@ -3305,7 +3220,8 @@ shutdown_vcache(void)
                    tvc->linkData = 0;
                }
 
-               afs_FreeAllAxs(&(tvc->Access));
+               if (tvc->Access)
+                   afs_FreeAllAxs(&(tvc->Access));
            }
            afs_vhashT[i] = 0;
        }
@@ -3313,22 +3229,23 @@ shutdown_vcache(void)
     /*
      * Free any leftover callback queue
      */
-    for (tsp = afs_cbrSpace; tsp; tsp = nsp) {
-       nsp = tsp->next;
+    for (i = 0; i < afs_stats_cmperf.CallBackAlloced; i++) {
+       tsp = afs_cbrHeads[i];
+       afs_cbrHeads[i] = 0;
        afs_osi_Free((char *)tsp, AFS_NCBRS * sizeof(struct afs_cbr));
     }
     afs_cbrSpace = 0;
 
-#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV)
+#if !defined(AFS_LINUX22_ENV)
     afs_osi_Free(Initial_freeVCList, afs_cacheStats * sizeof(struct vcache));
-#endif
-#ifdef  KERNEL_HAVE_PIN
+
+# ifdef  KERNEL_HAVE_PIN
     unpin(Initial_freeVCList, afs_cacheStats * sizeof(struct vcache));
-#endif
+# endif
 
-#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV)
     freeVCList = Initial_freeVCList = 0;
 #endif
+
     AFS_RWLOCK_INIT(&afs_xvcache, "afs_xvcache");
     LOCK_INIT(&afs_xvcb, "afs_xvcb");
     QInit(&VLRU);
@@ -3336,7 +3253,8 @@ shutdown_vcache(void)
        QInit(&afs_vhashTV[i]);
 }
 
-void afs_DisconGiveUpCallbacks() {
+void
+afs_DisconGiveUpCallbacks(void) {
     int i;
     struct vcache *tvc;
     int nq=0;
@@ -3346,18 +3264,16 @@ void afs_DisconGiveUpCallbacks() {
     /* Somehow, walk the set of vcaches, with each one coming out as tvc */
     for (i = 0; i < VCSIZE; i++) {
         for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
-            if ((tvc->f.states & CRO) == 0 && tvc->callback) {
-                afs_QueueVCB(tvc);
+            if (afs_QueueVCB(tvc)) {
                 tvc->callback = NULL;
                 nq++;
             }
         }
     }
-    /*printf("%d callbacks to be discarded. queued ... ", nq);*/
-    afs_FlushVCBs(0);
-    
+
     ReleaseWriteLock(&afs_xvcache);
-    /*printf("gone\n");*/
+
+    afs_FlushVCBs(1);
 }
 
 /*!
@@ -3368,7 +3284,8 @@ void afs_DisconGiveUpCallbacks() {
  * disconnected mode to tidy up during reconnection
  *
  */
-void afs_ClearAllStatdFlag() {
+void
+afs_ClearAllStatdFlag(void) {
     int i;
     struct vcache *tvc;