afs: Clarify vcache->mvid accesses
[openafs.git] / src / afs / afs_callback.c
index 69a010b..c90f82f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
 #include <afsconfig.h>
-#include "../afs/param.h"
-
-RCSID("$Header$");
-
-#include "../afs/sysincludes.h" /*Standard vendor system headers*/
-#include "../afs/afsincludes.h" /*AFS-based standard headers*/
-#include "../afs/afs_stats.h"  /*Cache Manager stats*/
-#include "../afs/afs_args.h"
-
-extern struct volume *afs_volumes[NVOLS];   /* volume hash table */
-extern void afs_DequeueCallback();
-extern void afs_ComputePAGStats();
-afs_int32 afs_allCBs   = 0;            /*Break callbacks on all objects */
-afs_int32 afs_oddCBs   = 0;            /*Break callbacks on dirs*/
-afs_int32 afs_evenCBs = 0;             /*Break callbacks received on files*/
-afs_int32 afs_allZaps = 0;             /*Objects entries deleted */
-afs_int32 afs_oddZaps = 0;             /*Dir cache entries deleted*/
-afs_int32 afs_evenZaps = 0;            /*File cache entries deleted*/
+#include "afs/param.h"
+
+
+#include "afs/sysincludes.h"   /*Standard vendor system headers */
+#include "afsincludes.h"       /*AFS-based standard headers */
+#include "afs/afs_stats.h"     /*Cache Manager stats */
+#include "afs/afs_args.h"
+
+afs_int32 afs_allCBs = 0;      /*Break callbacks on all objects */
+afs_int32 afs_oddCBs = 0;      /*Break callbacks on dirs */
+afs_int32 afs_evenCBs = 0;     /*Break callbacks received on files */
+afs_int32 afs_allZaps = 0;     /*Objects entries deleted */
+afs_int32 afs_oddZaps = 0;     /*Dir cache entries deleted */
+afs_int32 afs_evenZaps = 0;    /*File cache entries deleted */
 afs_int32 afs_connectBacks = 0;
-extern struct rx_service *afs_server;
-
-extern afs_lock_t afs_xvcb, afs_xbrs, afs_xdcache;
-extern afs_rwlock_t afs_xvcache, afs_xserver,  afs_xcell,  afs_xuser;
-extern afs_rwlock_t afs_xvolume, afs_puttofileLock, afs_ftf, afs_xinterface;
-extern afs_rwlock_t afs_xconn;
-extern struct afs_lock afs_xaxs;
-extern afs_lock_t afs_xcbhash;
-extern struct srvAddr *afs_srvAddrs[NSERVERS];
-extern struct afs_q CellLRU;
-extern struct cm_initparams cm_initParams;
 
 /*
  * Some debugging aids.
@@ -51,25 +36,41 @@ extern struct cm_initparams cm_initParams;
 static struct ltable {
     char *name;
     char *addr;
-} ltable []= {
-    "afs_xvcache", (char *)&afs_xvcache,
-    "afs_xdcache", (char *)&afs_xdcache,
-    "afs_xserver", (char *)&afs_xserver,
-    "afs_xvcb",    (char *)&afs_xvcb,
-    "afs_xbrs",    (char *)&afs_xbrs,
-    "afs_xcell",   (char *)&afs_xcell,
-    "afs_xconn",   (char *)&afs_xconn,
-    "afs_xuser",   (char *)&afs_xuser,
-    "afs_xvolume", (char *)&afs_xvolume,
-    "puttofile",   (char *)&afs_puttofileLock,
-    "afs_ftf",     (char *)&afs_ftf,
-    "afs_xcbhash", (char *)&afs_xcbhash,
-    "afs_xaxs",    (char *)&afs_xaxs,
-    "afs_xinterface", (char *)&afs_xinterface,
+} ltable[] = {
+    {
+    "afs_xvcache", (char *)&afs_xvcache}, {
+    "afs_xdcache", (char *)&afs_xdcache}, {
+    "afs_xserver", (char *)&afs_xserver}, {
+    "afs_xvcb", (char *)&afs_xvcb}, {
+    "afs_xbrs", (char *)&afs_xbrs}, {
+    "afs_xcell", (char *)&afs_xcell}, {
+    "afs_xconn", (char *)&afs_xconn}, {
+    "afs_xuser", (char *)&afs_xuser}, {
+    "afs_xvolume", (char *)&afs_xvolume}, {
+    "puttofile", (char *)&afs_puttofileLock}, {
+    "afs_ftf", (char *)&afs_ftf}, {
+    "afs_xcbhash", (char *)&afs_xcbhash}, {
+    "afs_xaxs", (char *)&afs_xaxs}, {
+    "afs_xinterface", (char *)&afs_xinterface},
+#ifndef UKERNEL
+    {
+    "afs_xosi", (char *)&afs_xosi},
+#endif
+    {
+      "afs_xsrvAddr", (char *)&afs_xsrvAddr},
+    {
+      "afs_xvreclaim", (char *)&afs_xvreclaim},
+    { "afsdb_client_lock", (char *)&afsdb_client_lock},
+    { "afsdb_req_lock", (char *)&afsdb_req_lock},
+    { "afs_discon_lock", (char *)&afs_discon_lock},
+    { "afs_disconDirtyLock", (char *)&afs_disconDirtyLock},
+    { "afs_discon_vc_dirty", (char *)&afs_xvcdirty},
+    { "afs_dynrootDirLock", (char *)&afs_dynrootDirLock},
+    { "afs_dynSymlinkLock", (char *)&afs_dynSymlinkLock},
 };
-unsigned long  lastCallBack_vnode;
-unsigned int   lastCallBack_dv;
-osi_timeval_t  lastCallBack_time;
+unsigned long lastCallBack_vnode;
+unsigned int lastCallBack_dv;
+osi_timeval_t lastCallBack_time;
 
 /* these are for storing alternate interface addresses */
 struct interfaceAddr afs_cb_interface;
@@ -97,16 +98,14 @@ struct interfaceAddr afs_cb_interface;
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetCE(a_call, a_index, a_result)
-    struct rx_call *a_call;
-    afs_int32 a_index;
-    struct AFSDBCacheEntry *a_result;
-
-{ /*SRXAFSCB_GetCE*/
+int
+SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
+              struct AFSDBCacheEntry *a_result)
+{
 
-    register int i;                    /*Loop variable*/
-    register struct vcache *tvc;       /*Ptr to current cache entry*/
-    int code;                          /*Return code*/
+    int i;             /*Loop variable */
+    struct vcache *tvc;        /*Ptr to current cache entry */
+    int code;                  /*Return code */
     XSTATS_DECLS;
 
     RX_AFS_GLOCK();
@@ -119,12 +118,12 @@ int SRXAFSCB_GetCE(a_call, a_index, a_result)
            if (a_index == 0)
                goto searchDone;
            a_index--;
-       } /*Zip through current hash chain*/
-    } /*Zip through hash chains*/
+       }                       /*Zip through current hash chain */
+    }                          /*Zip through hash chains */
 
   searchDone:
-    if (tvc == (struct vcache *) 0) {
-       /*Past EOF*/
+    if (tvc == NULL) {
+       /*Past EOF */
        code = 1;
        goto fcnDone;
     }
@@ -133,61 +132,66 @@ int SRXAFSCB_GetCE(a_call, a_index, a_result)
      * Copy out the located entry.
      */
     a_result->addr = afs_data_pointer_to_int32(tvc);
-    a_result->cell = tvc->fid.Cell;
-    a_result->netFid.Volume = tvc->fid.Fid.Volume;
-    a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
-    a_result->netFid.Unique = tvc->fid.Fid.Unique;
+    a_result->cell = tvc->f.fid.Cell;
+    a_result->netFid.Volume = tvc->f.fid.Fid.Volume;
+    a_result->netFid.Vnode = tvc->f.fid.Fid.Vnode;
+    a_result->netFid.Unique = tvc->f.fid.Fid.Unique;
     a_result->lock.waitStates = tvc->lock.wait_states;
     a_result->lock.exclLocked = tvc->lock.excl_locked;
     a_result->lock.readersReading = tvc->lock.readers_reading;
     a_result->lock.numWaiting = tvc->lock.num_waiting;
 #if defined(INSTRUMENT_LOCKS)
-    a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
-    a_result->lock.pid_writer = tvc->lock.pid_writer;
+    a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
+    a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
     a_result->lock.src_indicator = tvc->lock.src_indicator;
 #else
     /* On osf20 , the vcache does not maintain these three fields */
     a_result->lock.pid_last_reader = 0;
     a_result->lock.pid_writer = 0;
     a_result->lock.src_indicator = 0;
-#endif /* AFS_OSF20_ENV */
+#endif /* INSTRUMENT_LOCKS */
 #ifdef AFS_64BIT_CLIENT
-    a_result->Length = (afs_int32) tvc->m.Length & 0xffffffff;
+    a_result->Length = (afs_int32) tvc->f.m.Length & 0xffffffff;
 #else /* AFS_64BIT_CLIENT */
-    a_result->Length = tvc->m.Length;
+    a_result->Length = tvc->f.m.Length;
 #endif /* AFS_64BIT_CLIENT */
-    a_result->DataVersion = hgetlo(tvc->m.DataVersion);
-    a_result->callback = afs_data_pointer_to_int32(tvc->callback);             /* XXXX Now a pointer; change it XXXX */
+    a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
+    a_result->callback = afs_data_pointer_to_int32(tvc->callback);     /* XXXX Now a pointer; change it XXXX */
     a_result->cbExpires = tvc->cbExpires;
+    if (tvc->f.states & CVInit) {
+        a_result->refCount = 1;
+    } else {
+#ifdef AFS_DARWIN80_ENV
+    a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
+#else
     a_result->refCount = VREFCOUNT(tvc);
+#endif
+    }
     a_result->opens = tvc->opens;
     a_result->writers = tvc->execsOrWriters;
     a_result->mvstat = tvc->mvstat;
-    a_result->states = tvc->states;
+    a_result->states = tvc->f.states;
     code = 0;
 
     /*
      * Return our results.
      */
-fcnDone:
+  fcnDone:
     XSTATS_END_TIME;
 
     RX_AFS_GUNLOCK();
 
-    return(code);
-
-} /*SRXAFSCB_GetCE*/
-
-int SRXAFSCB_GetCE64(a_call, a_index, a_result)
-    struct rx_call *a_call;
-    afs_int32 a_index;
-    struct AFSDBCacheEntry64 *a_result;
+    return (code);
 
-{ /*SRXAFSCB_GetCE64*/
+}                              /*SRXAFSCB_GetCE */
 
-    register int i;                    /*Loop variable*/
-    register struct vcache *tvc;       /*Ptr to current cache entry*/
-    int code;                          /*Return code*/
+int
+SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
+                struct AFSDBCacheEntry64 *a_result)
+{
+    int i;             /*Loop variable */
+    struct vcache *tvc;        /*Ptr to current cache entry */
+    int code;                  /*Return code */
     XSTATS_DECLS;
 
     RX_AFS_GLOCK();
@@ -200,12 +204,12 @@ int SRXAFSCB_GetCE64(a_call, a_index, a_result)
            if (a_index == 0)
                goto searchDone;
            a_index--;
-       } /*Zip through current hash chain*/
-    } /*Zip through hash chains*/
+       }                       /*Zip through current hash chain */
+    }                          /*Zip through hash chains */
 
   searchDone:
-    if (tvc == (struct vcache *) 0) {
-       /*Past EOF*/
+    if (tvc == NULL) {
+       /*Past EOF */
        code = 1;
        goto fcnDone;
     }
@@ -214,55 +218,54 @@ int SRXAFSCB_GetCE64(a_call, a_index, a_result)
      * Copy out the located entry.
      */
     a_result->addr = afs_data_pointer_to_int32(tvc);
-    a_result->cell = tvc->fid.Cell;
-    a_result->netFid.Volume = tvc->fid.Fid.Volume;
-    a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
-    a_result->netFid.Unique = tvc->fid.Fid.Unique;
+    a_result->cell = tvc->f.fid.Cell;
+    a_result->netFid.Volume = tvc->f.fid.Fid.Volume;
+    a_result->netFid.Vnode = tvc->f.fid.Fid.Vnode;
+    a_result->netFid.Unique = tvc->f.fid.Fid.Unique;
     a_result->lock.waitStates = tvc->lock.wait_states;
     a_result->lock.exclLocked = tvc->lock.excl_locked;
     a_result->lock.readersReading = tvc->lock.readers_reading;
     a_result->lock.numWaiting = tvc->lock.num_waiting;
 #if defined(INSTRUMENT_LOCKS)
-    a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
-    a_result->lock.pid_writer = tvc->lock.pid_writer;
+    a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
+    a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
     a_result->lock.src_indicator = tvc->lock.src_indicator;
 #else
     /* On osf20 , the vcache does not maintain these three fields */
     a_result->lock.pid_last_reader = 0;
     a_result->lock.pid_writer = 0;
     a_result->lock.src_indicator = 0;
-#endif /* AFS_OSF20_ENV */
-#ifdef AFS_64BIT_ENV
-    a_result->Length = tvc->m.Length;
-#else /* AFS_64BIT_ENV */
-#ifdef AFS_64BIT_CLIENT
-    a_result->Length = tvc->m.Length;
-#else /* AFS_64BIT_CLIENT */
-    a_result->Length.high = 0;
-    a_result->Length.low = tvc->m.Length;
-#endif /* AFS_64BIT_CLIENT */
-#endif /* AFS_64BIT_ENV */
-    a_result->DataVersion = hgetlo(tvc->m.DataVersion);
-    a_result->callback = afs_data_pointer_to_int32(tvc->callback);             /* XXXX Now a pointer; change it XXXX */
+#endif /* INSTRUMENT_LOCKS */
+    a_result->Length = tvc->f.m.Length;
+    a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
+    a_result->callback = afs_data_pointer_to_int32(tvc->callback);     /* XXXX Now a pointer; change it XXXX */
     a_result->cbExpires = tvc->cbExpires;
+    if (tvc->f.states & CVInit) {
+        a_result->refCount = 1;
+    } else {
+#ifdef AFS_DARWIN80_ENV
+    a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
+#else
     a_result->refCount = VREFCOUNT(tvc);
+#endif
+    }
     a_result->opens = tvc->opens;
     a_result->writers = tvc->execsOrWriters;
     a_result->mvstat = tvc->mvstat;
-    a_result->states = tvc->states;
+    a_result->states = tvc->f.states;
     code = 0;
 
     /*
      * Return our results.
      */
-fcnDone:
+  fcnDone:
     XSTATS_END_TIME;
 
     RX_AFS_GUNLOCK();
 
-    return(code);
+    return (code);
 
-} /*SRXAFSCB_GetCE64*/
+}                              /*SRXAFSCB_GetCE64 */
 
 
 /*------------------------------------------------------------------------
@@ -289,44 +292,71 @@ fcnDone:
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetLock (a_call, a_index, a_result)
-    struct rx_call *a_call;
-    afs_int32 a_index;
-    struct AFSDBLock *a_result;
-
-{ /*SRXAFSCB_GetLock*/
-
-    struct ltable *tl;         /*Ptr to lock table entry*/
-    int nentries;              /*Num entries in table*/
-    int code;                  /*Return code*/
+int
+SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
+                struct AFSDBLock *a_result)
+{
+    struct ltable *tl;         /*Ptr to lock table entry */
+    int nentries;              /*Num entries in table */
+    int code;                  /*Return code */
     XSTATS_DECLS;
 
     RX_AFS_GLOCK();
 
     XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
-    
+
     AFS_STATCNT(SRXAFSCB_GetLock);
-    nentries = sizeof(ltable)/sizeof(struct ltable);
-    if (a_index < 0 || a_index >= nentries) {
+    nentries = sizeof(ltable) / sizeof(struct ltable);
+    if (a_index < 0 || a_index >= nentries+afs_cellindex) {
        /*
-         * Past EOF
-         */
+        * Past EOF
+        */
        code = 1;
-    }
-    else {
+    } else if (a_index >= nentries) {
+       struct cell *tc = afs_GetCellByIndex(a_index-nentries, 0);
+       strcpy(a_result->name, tc->cellName);
+       a_result->lock.waitStates =
+           ((struct afs_lock *)&(tc->lock))->wait_states;
+       a_result->lock.exclLocked =
+           ((struct afs_lock *)&(tc->lock))->excl_locked;
+       a_result->lock.readersReading =
+           ((struct afs_lock *)&(tc->lock))->readers_reading;
+       a_result->lock.numWaiting =
+           ((struct afs_lock *)&(tc->lock))->num_waiting;
+#ifdef INSTRUMENT_LOCKS
+       a_result->lock.pid_last_reader =
+           MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_last_reader);
+       a_result->lock.pid_writer =
+           MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_writer);
+       a_result->lock.src_indicator =
+           ((struct afs_lock *)&(tc->lock))->src_indicator;
+#else
+       a_result->lock.pid_last_reader = 0;
+       a_result->lock.pid_writer = 0;
+       a_result->lock.src_indicator = 0;
+#endif
+       code = 0;
+    } else {
        /*
         * Found it - copy out its contents.
         */
        tl = &ltable[a_index];
        strcpy(a_result->name, tl->name);
-       a_result->lock.waitStates = ((struct afs_lock *)(tl->addr))->wait_states;
-       a_result->lock.exclLocked = ((struct afs_lock *)(tl->addr))->excl_locked;
-       a_result->lock.readersReading = ((struct afs_lock *)(tl->addr))->readers_reading;
-       a_result->lock.numWaiting = ((struct afs_lock *)(tl->addr))->num_waiting;
+       a_result->lock.waitStates =
+           ((struct afs_lock *)(tl->addr))->wait_states;
+       a_result->lock.exclLocked =
+           ((struct afs_lock *)(tl->addr))->excl_locked;
+       a_result->lock.readersReading =
+           ((struct afs_lock *)(tl->addr))->readers_reading;
+       a_result->lock.numWaiting =
+           ((struct afs_lock *)(tl->addr))->num_waiting;
 #ifdef INSTRUMENT_LOCKS
-       a_result->lock.pid_last_reader = ((struct afs_lock *)(tl->addr))->pid_last_reader;
-       a_result->lock.pid_writer = ((struct afs_lock *)(tl->addr))->pid_writer;
-       a_result->lock.src_indicator = ((struct afs_lock *)(tl->addr))->src_indicator;
+       a_result->lock.pid_last_reader =
+           MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_last_reader);
+       a_result->lock.pid_writer =
+           MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_writer);
+       a_result->lock.src_indicator =
+           ((struct afs_lock *)(tl->addr))->src_indicator;
 #else
        a_result->lock.pid_last_reader = 0;
        a_result->lock.pid_writer = 0;
@@ -339,9 +369,9 @@ int SRXAFSCB_GetLock (a_call, a_index, a_result)
 
     RX_AFS_GUNLOCK();
 
-    return(code);
+    return (code);
 
-}  /*SRXAFSCB_GetLock*/
+}                              /*SRXAFSCB_GetLock */
 
 
 /*------------------------------------------------------------------------
@@ -349,7 +379,7 @@ int SRXAFSCB_GetLock (a_call, a_index, a_result)
  *
  * Description:
  *     Clear out callback information for the specified file, or
- *     even a whole volume.  Used to worry about callback was from 
+ *     even a whole volume.  Used to worry about callback was from
  *      within the particular cell or not.  Now we don't bother with
  *      that anymore; it's not worth the time.
  *
@@ -365,21 +395,27 @@ int SRXAFSCB_GetLock (a_call, a_index, a_result)
  *
  * Side Effects:
  *     As advertised.
- *------------------------------------------------------------------------*/
 
-static ClearCallBack(a_conn, a_fid)
-    register struct rx_connection *a_conn;
-    register struct AFSFid *a_fid;
+Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
 
-{ /*ClearCallBack*/
+ *------------------------------------------------------------------------*/
 
-    register struct vcache *tvc;
-    register int i;
+static int
+ClearCallBack(struct rx_connection *a_conn,
+             struct AFSFid *a_fid)
+{
+    struct vcache *tvc;
+    int i;
     struct VenusFid localFid;
-    struct volume * tv;
+    struct volume *tv;
+#ifdef AFS_DARWIN80_ENV
+    vnode_t vp;
+#endif
 
     AFS_STATCNT(ClearCallBack);
 
+    AFS_ASSERT_GLOCK();
+
     /*
      * XXXX Don't hold any server locks here because of callback protocol XXX
      */
@@ -389,96 +425,175 @@ static ClearCallBack(a_conn, a_fid)
     localFid.Fid.Unique = a_fid->Unique;
 
     /*
-      * Volume ID of zero means don't do anything.
-      */
+     * Volume ID of zero means don't do anything.
+     */
     if (a_fid->Volume != 0) {
        if (a_fid->Vnode == 0) {
+               struct afs_q *tq, *uq;
            /*
             * Clear callback for the whole volume.  Zip through the
             * hash chain, nullifying entries whose volume ID matches.
             */
-           for (i = 0; i < VCSIZE; i++)
-               for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
-                   if (tvc->fid.Fid.Volume == a_fid->Volume) {
-                       tvc->callback = (struct server *)0;
-                       tvc->quick.stamp = 0; 
+loop1:
+               ObtainReadLock(&afs_xvcache);
+               i = VCHashV(&localFid);
+               for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) {
+                   uq = QPrev(tq);
+                   tvc = QTOVH(tq);
+                   if (tvc->f.fid.Fid.Volume == a_fid->Volume) {
+                       tvc->callback = NULL;
                        if (!localFid.Cell)
-                           localFid.Cell = tvc->fid.Cell;
-                       tvc->h1.dchint = NULL; /* invalidate hints */
+                           localFid.Cell = tvc->f.fid.Cell;
+                       tvc->dchint = NULL;     /* invalidate hints */
+                       if (tvc->f.states & CVInit) {
+                           ReleaseReadLock(&afs_xvcache);
+                           afs_osi_Sleep(&tvc->f.states);
+                           goto loop1;
+                       }
+#if     defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
+                       AFS_FAST_HOLD(tvc);
+#else
+#ifdef AFS_DARWIN80_ENV
+                       if (tvc->f.states & CDeadVnode) {
+                           ReleaseReadLock(&afs_xvcache);
+                           afs_osi_Sleep(&tvc->f.states);
+                           goto loop1;
+                       }
+                       vp = AFSTOV(tvc);
+                       if (vnode_get(vp))
+                           continue;
+                       if (vnode_ref(vp)) {
+                           AFS_GUNLOCK();
+                           vnode_put(vp);
+                           AFS_GLOCK();
+                           continue;
+                       }
+#else
+                       AFS_FAST_HOLD(tvc);
+#endif
+#endif
+                       ReleaseReadLock(&afs_xvcache);
                        ObtainWriteLock(&afs_xcbhash, 449);
                        afs_DequeueCallback(tvc);
-                       tvc->states &= ~(CStatd | CUnique | CBulkFetching);
+                       tvc->f.states &= ~(CStatd | CUnique | CBulkFetching);
                        afs_allCBs++;
-                       if (tvc->fid.Fid.Vnode & 1)
-                         afs_oddCBs++; 
+                       if (tvc->f.fid.Fid.Vnode & 1)
+                           afs_oddCBs++;
                        else
-                         afs_evenCBs++; 
+                           afs_evenCBs++;
                        ReleaseWriteLock(&afs_xcbhash);
-                       if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
+                       if ((tvc->f.fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)))
                            osi_dnlc_purgedp(tvc);
                        afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
-                                  ICL_TYPE_POINTER, tvc, 
-                                  ICL_TYPE_INT32, tvc->states,
-                                  ICL_TYPE_INT32, a_fid->Volume);
-                   } else if ((tvc->states & CMValid) && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
-                       tvc->states &= ~CMValid;
+                                  ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
+                                  tvc->f.states, ICL_TYPE_INT32,
+                                  a_fid->Volume);
+#ifdef AFS_DARWIN80_ENV
+                       vnode_put(AFSTOV(tvc));
+#endif
+                       ObtainReadLock(&afs_xvcache);
+                       uq = QPrev(tq);
+                       AFS_FAST_RELE(tvc);
+                   } else if ((tvc->f.states & CMValid)
+                              && (tvc->mvid.target_root->Fid.Volume == a_fid->Volume)) {
+                       tvc->f.states &= ~CMValid;
                        if (!localFid.Cell)
-                           localFid.Cell = tvc->mvid->Cell;
+                           localFid.Cell = tvc->mvid.target_root->Cell;
                    }
                }
+               ReleaseReadLock(&afs_xvcache);
 
            /*
             * XXXX Don't hold any locks here XXXX
             */
            tv = afs_FindVolume(&localFid, 0);
            if (tv) {
-             afs_ResetVolumeInfo(tv);
-             afs_PutVolume(tv, 0);
-             /* invalidate mtpoint? */
+               afs_ResetVolumeInfo(tv);
+               afs_PutVolume(tv, 0);
+               /* invalidate mtpoint? */
            }
-       } /*Clear callbacks for whole volume*/
+       } /*Clear callbacks for whole volume */
        else {
            /*
             * Clear callbacks just for the one file.
             */
+           struct vcache *uvc;
            afs_allCBs++;
            if (a_fid->Vnode & 1)
-               afs_oddCBs++;   /*Could do this on volume basis, too*/
+               afs_oddCBs++;   /*Could do this on volume basis, too */
            else
-               afs_evenCBs++; /*A particular fid was specified*/
+               afs_evenCBs++;  /*A particular fid was specified */
+loop2:
+           ObtainReadLock(&afs_xvcache);
            i = VCHash(&localFid);
-           for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
-               if (tvc->fid.Fid.Vnode == a_fid->Vnode
-                   && tvc->fid.Fid.Volume == a_fid->Volume
-                   && tvc->fid.Fid.Unique == a_fid->Unique ) {
-                   tvc->callback = (struct server *)0;
-                   tvc->quick.stamp = 0; 
-                   tvc->h1.dchint = NULL; /* invalidate hints */
+           for (tvc = afs_vhashT[i]; tvc; tvc = uvc) {
+               uvc = tvc->hnext;
+               if (tvc->f.fid.Fid.Vnode == a_fid->Vnode
+                   && tvc->f.fid.Fid.Volume == a_fid->Volume
+                   && tvc->f.fid.Fid.Unique == a_fid->Unique) {
+                   tvc->callback = NULL;
+                   tvc->dchint = NULL; /* invalidate hints */
+                   if (tvc->f.states & CVInit) {
+                       ReleaseReadLock(&afs_xvcache);
+                       afs_osi_Sleep(&tvc->f.states);
+                       goto loop2;
+                   }
+#if     defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
+                   AFS_FAST_HOLD(tvc);
+#else
+#ifdef AFS_DARWIN80_ENV
+                   if (tvc->f.states & CDeadVnode) {
+                       ReleaseReadLock(&afs_xvcache);
+                       afs_osi_Sleep(&tvc->f.states);
+                       goto loop2;
+                   }
+                   vp = AFSTOV(tvc);
+                   if (vnode_get(vp))
+                       continue;
+                   if (vnode_ref(vp)) {
+                       AFS_GUNLOCK();
+                       vnode_put(vp);
+                       AFS_GLOCK();
+                       continue;
+                   }
+#else
+                   AFS_FAST_HOLD(tvc);
+#endif
+#endif
+                   ReleaseReadLock(&afs_xvcache);
                    ObtainWriteLock(&afs_xcbhash, 450);
                    afs_DequeueCallback(tvc);
-                   tvc->states &= ~(CStatd | CUnique | CBulkFetching);
+                   tvc->f.states &= ~(CStatd | CUnique | CBulkFetching);
                    ReleaseWriteLock(&afs_xcbhash);
-                   if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
+                   if ((tvc->f.fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)))
                        osi_dnlc_purgedp(tvc);
                    afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
-                              ICL_TYPE_POINTER, tvc, 
-                              ICL_TYPE_INT32, tvc->states, ICL_TYPE_LONG, 0);
+                              ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
+                              tvc->f.states, ICL_TYPE_LONG, 0);
 #ifdef CBDEBUG
                    lastCallBack_vnode = afid->Vnode;
                    lastCallBack_dv = tvc->mstat.DataVersion.low;
                    osi_GetuTime(&lastCallBack_time);
 #endif /* CBDEBUG */
+#ifdef AFS_DARWIN80_ENV
+                   vnode_put(AFSTOV(tvc));
+#endif
+                   ObtainReadLock(&afs_xvcache);
+                   uvc = tvc->hnext;
+                   AFS_FAST_RELE(tvc);
                }
-           } /*Walk through hash table*/
-       } /*Clear callbacks for one file*/
-    } /*Fid has non-zero volume ID*/
+           }                   /*Walk through hash table */
+           ReleaseReadLock(&afs_xvcache);
+       }                       /*Clear callbacks for one file */
+    }
 
+    /*Fid has non-zero volume ID */
     /*
      * Always return a predictable value.
      */
-    return(0);
+    return (0);
 
-} /*ClearCallBack*/
+}                              /*ClearCallBack */
 
 
 /*------------------------------------------------------------------------
@@ -504,17 +619,14 @@ static ClearCallBack(a_conn, a_fid)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_CallBack(a_call, a_fids, a_callbacks)
-    struct rx_call *a_call;
-    register struct AFSCBFids *a_fids;
-    struct AFSCBs *a_callbacks;
-    
-{ /*SRXAFSCB_CallBack*/
-
-    register int i;                        /*Loop variable*/
-    struct AFSFid *tfid;                   /*Ptr to current fid*/
-    register struct rx_connection *tconn;   /*Call's connection*/
-    int code=0;
+int
+SRXAFSCB_CallBack(struct rx_call *a_call, struct AFSCBFids *a_fids,
+                 struct AFSCBs *a_callbacks)
+{
+    int i;             /*Loop variable */
+    struct AFSFid *tfid;       /*Ptr to current fid */
+    struct rx_connection *tconn;       /*Call's connection */
+    int code = 0;
     XSTATS_DECLS;
 
     RX_AFS_GLOCK();
@@ -522,23 +634,24 @@ int SRXAFSCB_CallBack(a_call, a_fids, a_callbacks)
     XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
 
     AFS_STATCNT(SRXAFSCB_CallBack);
-    if (!(tconn = rx_ConnectionOf(a_call))) return;
-    tfid = (struct AFSFid *) a_fids->AFSCBFids_val;
-    
+    if (!(tconn = rx_ConnectionOf(a_call)))
+       return (0);
+    tfid = (struct AFSFid *)a_fids->AFSCBFids_val;
+
     /*
      * For now, we ignore callbacks, since the File Server only *breaks*
      * callbacks at present.
      */
-    for (i = 0; i < a_fids->AFSCBFids_len; i++) 
+    for (i = 0; i < a_fids->AFSCBFids_len; i++)
        ClearCallBack(tconn, &tfid[i]);
 
     XSTATS_END_TIME;
 
     RX_AFS_GUNLOCK();
-    
-    return(0);
 
-} /*SRXAFSCB_CallBack*/
+    return (0);
+
+}                              /*SRXAFSCB_CallBack */
 
 
 /*------------------------------------------------------------------------
@@ -562,10 +675,9 @@ int SRXAFSCB_CallBack(a_call, a_fids, a_callbacks)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_Probe(a_call)
-    struct rx_call *a_call;
-
-{ /*SRXAFSCB_Probe*/
+int
+SRXAFSCB_Probe(struct rx_call *a_call)
+{
     int code = 0;
     XSTATS_DECLS;
 
@@ -577,9 +689,9 @@ int SRXAFSCB_Probe(a_call)
 
     RX_AFS_GUNLOCK();
 
-    return(0);
+    return (0);
 
-} /*SRXAFSCB_Probe*/
+}                              /*SRXAFSCB_Probe */
 
 
 /*------------------------------------------------------------------------
@@ -602,18 +714,15 @@ int SRXAFSCB_Probe(a_call)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_InitCallBackState(a_call)
-    struct rx_call *a_call;
-
-{ /*SRXAFSCB_InitCallBackState*/
-
-    register int i;
-    register struct vcache *tvc;
-    register struct rx_connection *tconn;
-    register struct rx_peer *peer;
+int
+SRXAFSCB_InitCallBackState(struct rx_call *a_call)
+{
+    int i;
+    struct vcache *tvc;
+    struct rx_connection *tconn;
+    struct rx_peer *peer;
     struct server *ts;
     int code = 0;
-    extern int osi_dnlc_purge();
     XSTATS_DECLS;
 
     RX_AFS_GLOCK();
@@ -627,47 +736,51 @@ int SRXAFSCB_InitCallBackState(a_call)
     if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
 
        afs_allCBs++;
-       afs_oddCBs++;   /*Including any missed via create race*/
-       afs_evenCBs++;  /*Including any missed via create race*/
+       afs_oddCBs++;           /*Including any missed via create race */
+       afs_evenCBs++;          /*Including any missed via create race */
 
-       ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *)0, 0);
+       ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0,
+                           0);
        if (ts) {
            for (i = 0; i < VCSIZE; i++)
                for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
                    if (tvc->callback == ts) {
                        ObtainWriteLock(&afs_xcbhash, 451);
                        afs_DequeueCallback(tvc);
-                       tvc->callback = (struct server *)0;
-                       tvc->states &= ~(CStatd | CUnique | CBulkFetching);
+                       tvc->callback = NULL;
+                       tvc->f.states &= ~(CStatd | CUnique | CBulkFetching);
                        ReleaseWriteLock(&afs_xcbhash);
                    }
                }
+
+           /* capabilities need be requested again */
+           ts->flags &= ~SCAPS_KNOWN;
        }
 
-      
+
+
        /* find any volumes residing on this server and flush their state */
        {
-           register struct volume *tv;
-           register int j;
-        
-           for (i=0;i<NVOLS;i++) 
-               for (tv = afs_volumes[i]; tv; tv=tv->next) {
-                   for (j=0; j<MAXHOSTS; j++)
+           struct volume *tv;
+           int j;
+
+           for (i = 0; i < NVOLS; i++)
+               for (tv = afs_volumes[i]; tv; tv = tv->next) {
+                   for (j = 0; j < AFS_MAXHOSTS; j++)
                        if (tv->serverHost[j] == ts)
                            afs_ResetVolumeInfo(tv);
                }
        }
-       osi_dnlc_purge(); /* may be a little bit extreme */
+       osi_dnlc_purge();       /* may be a little bit extreme */
     }
 
     XSTATS_END_TIME;
 
     RX_AFS_GUNLOCK();
 
-    return(0);
+    return (0);
 
-} /*SRXAFSCB_InitCallBackState*/
+}                              /*SRXAFSCB_InitCallBackState */
 
 
 /*------------------------------------------------------------------------
@@ -691,12 +804,10 @@ int SRXAFSCB_InitCallBackState(a_call)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_XStatsVersion(a_call, a_versionP)
-    struct rx_call *a_call;
-    afs_int32 *a_versionP;
-
-{ /*SRXAFSCB_XStatsVersion*/
-   int code=0;
+int
+SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 * a_versionP)
+{
+    int code = 0;
 
     XSTATS_DECLS;
 
@@ -709,8 +820,8 @@ int SRXAFSCB_XStatsVersion(a_call, a_versionP)
 
     RX_AFS_GUNLOCK();
 
-    return(0);
-}  /*SRXAFSCB_XStatsVersion*/
+    return (0);
+}                              /*SRXAFSCB_XStatsVersion */
 
 
 /*------------------------------------------------------------------------
@@ -740,19 +851,14 @@ int SRXAFSCB_XStatsVersion(a_call, a_versionP)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVersionNumP, a_timeP, a_dataP)
-    struct rx_call *a_call;
-    afs_int32 a_clientVersionNum;
-    afs_int32 a_collectionNumber;
-    afs_int32 *a_srvVersionNumP;
-    afs_int32 *a_timeP;
-    AFSCB_CollData *a_dataP;
-
-{ /*SRXAFSCB_GetXStats*/
-
-    register int code;         /*Return value*/
-    afs_int32 *dataBuffP;              /*Ptr to data to be returned*/
-    afs_int32 dataBytes;               /*Bytes in data buffer*/
+int
+SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
+                  afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
+                  afs_int32 * a_timeP, AFSCB_CollData * a_dataP)
+{
+    int code;          /*Return value */
+    afs_int32 *dataBuffP;      /*Ptr to data to be returned */
+    afs_int32 dataBytes;       /*Bytes in data buffer */
     XSTATS_DECLS;
 
     RX_AFS_GLOCK();
@@ -776,10 +882,10 @@ int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVers
      * no data.
      */
     a_dataP->AFSCB_CollData_len = 0;
-    a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
+    a_dataP->AFSCB_CollData_val = NULL;
 #else
-    switch(a_collectionNumber) {
-      case AFSCB_XSTATSCOLL_CALL_INFO:
+    switch (a_collectionNumber) {
+    case AFSCB_XSTATSCOLL_CALL_INFO:
        /*
         * Pass back all the call-count-related data.
         *
@@ -788,13 +894,14 @@ int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVers
         * >>> will be freed at the tail end of the server stub code.
         */
        dataBytes = sizeof(struct afs_CMStats);
-       dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
+       dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
+       osi_Assert(dataBuffP != NULL);
        memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
-       a_dataP->AFSCB_CollData_len = dataBytes>>2;
+       a_dataP->AFSCB_CollData_len = dataBytes >> 2;
        a_dataP->AFSCB_CollData_val = dataBuffP;
        break;
 
-      case AFSCB_XSTATSCOLL_PERF_INFO:
+    case AFSCB_XSTATSCOLL_PERF_INFO:
        /*
         * Update and then pass back all the performance-related data.
         * Note: the only performance fields that need to be computed
@@ -808,13 +915,14 @@ int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVers
        afs_stats_cmperf.numPerfCalls++;
        afs_CountServers();
        dataBytes = sizeof(afs_stats_cmperf);
-       dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
+       dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
+       osi_Assert(dataBuffP != NULL);
        memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
-       a_dataP->AFSCB_CollData_len = dataBytes>>2;
+       a_dataP->AFSCB_CollData_len = dataBytes >> 2;
        a_dataP->AFSCB_CollData_val = dataBuffP;
        break;
 
-      case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
+    case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
        /*
         * Pass back the full range of performance and statistical
         * data available.  We have to bring the normal performance
@@ -827,33 +935,35 @@ int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVers
         */
        afs_stats_cmperf.numPerfCalls++;
        afs_CountServers();
-       memcpy((char *)(&(afs_stats_cmfullperf.perf)), (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
+       memcpy((char *)(&(afs_stats_cmfullperf.perf)),
+              (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
        afs_stats_cmfullperf.numFullPerfCalls++;
 
        dataBytes = sizeof(afs_stats_cmfullperf);
-       dataBuffP = (afs_int32 *)afs_osi_Alloc(dataBytes);
+       dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
+       osi_Assert(dataBuffP != NULL);
        memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
-       a_dataP->AFSCB_CollData_len = dataBytes>>2;
+       a_dataP->AFSCB_CollData_len = dataBytes >> 2;
        a_dataP->AFSCB_CollData_val = dataBuffP;
        break;
 
-      default:
+    default:
        /*
         * Illegal collection number.
         */
        a_dataP->AFSCB_CollData_len = 0;
-       a_dataP->AFSCB_CollData_val = (afs_int32 *)0;
+       a_dataP->AFSCB_CollData_val = NULL;
        code = 1;
-    } /*Switch on collection number*/
+    }                          /*Switch on collection number */
 #endif /* AFS_NOSTATS */
 
     XSTATS_END_TIME;
 
     RX_AFS_GUNLOCK();
 
-    return(code);
+    return (code);
 
-} /*SRXAFSCB_GetXStats*/
+}                              /*SRXAFSCB_GetXStats */
 
 
 /*------------------------------------------------------------------------
@@ -875,9 +985,9 @@ int SRXAFSCB_GetXStats(a_call, a_clientVersionNum, a_collectionNumber, a_srvVers
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int afs_RXCallBackServer()
-
-{ /*afs_RXCallBackServer*/
+int
+afs_RXCallBackServer(void)
+{
     AFS_STATCNT(afs_RXCallBackServer);
 
     while (1) {
@@ -889,10 +999,10 @@ int afs_RXCallBackServer()
     /*
      * Donate this process to Rx.
      */
-    rx_ServerProc();
-    return(0);
+    rx_ServerProc(NULL);
+    return (0);
 
-} /*afs_RXCallBackServer*/
+}                              /*afs_RXCallBackServer */
 
 
 /*------------------------------------------------------------------------
@@ -914,22 +1024,19 @@ int afs_RXCallBackServer()
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int shutdown_CB() 
-
-{ /*shutdown_CB*/
-
-  extern int afs_cold_shutdown;
-
-  AFS_STATCNT(shutdown_CB);
+int
+shutdown_CB(void)
+{
+    AFS_STATCNT(shutdown_CB);
 
-  if (afs_cold_shutdown) {
-    afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps = afs_evenZaps =
-       afs_connectBacks = 0;
-  }
+    if (afs_cold_shutdown) {
+       afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps =
+           afs_evenZaps = afs_connectBacks = 0;
+    }
 
-  return(0);
+    return (0);
 
-} /*shutdown_CB*/
+}                              /*shutdown_CB */
 
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_InitCallBackState2
@@ -942,7 +1049,7 @@ int shutdown_CB()
  *      a_call : Ptr to Rx call on which this request came in.
  *
  * Returns:
- *      RXGEN_OPCODE (always). 
+ *      RXGEN_OPCODE (always).
  *
  * Environment:
  *      Nothing interesting.
@@ -951,11 +1058,11 @@ int shutdown_CB()
  *      None
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_InitCallBackState2(a_call, addr)
-struct rx_call *a_call;
-struct interfaceAddr * addr;
+int
+SRXAFSCB_InitCallBackState2(struct rx_call *a_call,
+                           struct interfaceAddr *addr)
 {
-       return RXGEN_OPCODE;
+    return RXGEN_OPCODE;
 }
 
 /*------------------------------------------------------------------------
@@ -982,24 +1089,24 @@ struct interfaceAddr * addr;
  *      As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_WhoAreYou(a_call, addr)
-struct rx_call *a_call;
-struct interfaceAddr *addr;
+int
+SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
 {
     int i;
     int code = 0;
-    XSTATS_DECLS;
 
     RX_AFS_GLOCK();
 
     AFS_STATCNT(SRXAFSCB_WhoAreYou);
 
+    memset(addr, 0, sizeof(*addr));
+
     ObtainReadLock(&afs_xinterface);
 
     /* return all network interface addresses */
     addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
     addr->uuid = afs_cb_interface.uuid;
-    for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
+    for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
        addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
        addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
        addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
@@ -1033,9 +1140,8 @@ struct interfaceAddr *addr;
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_InitCallBackState3(a_call, a_uuid)
-struct rx_call *a_call;
-afsUUID *a_uuid;
+int
+SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID * a_uuid)
 {
     int code;
 
@@ -1046,7 +1152,7 @@ afsUUID *a_uuid;
 
     return code;
 }
+
 
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_ProbeUuid
@@ -1071,9 +1177,8 @@ afsUUID *a_uuid;
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_ProbeUuid(a_call, a_uuid)
-struct rx_call *a_call;
-afsUUID *a_uuid;
+int
+SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID * a_uuid)
 {
     int code = 0;
     XSTATS_DECLS;
@@ -1083,14 +1188,14 @@ afsUUID *a_uuid;
 
     XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
     if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
-       code = 1; /* failure */
+       code = 1;               /* failure */
     XSTATS_END_TIME;
 
     RX_AFS_GUNLOCK();
 
     return code;
 }
+
 
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_GetServerPrefs
@@ -1115,11 +1220,9 @@ afsUUID *a_uuid;
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetServerPrefs(
-    struct rx_call *a_call,
-    afs_int32 a_index,
-    afs_int32 *a_srvr_addr,
-    afs_int32 *a_srvr_rank)
+int
+SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
+                       afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
 {
     int i, j;
     struct srvAddr *sa;
@@ -1132,7 +1235,7 @@ int SRXAFSCB_GetServerPrefs(
     /* Search the hash table for the server with this index */
     *a_srvr_addr = 0xffffffff;
     *a_srvr_rank = 0xffffffff;
-    for (i=0, j=0; j < NSERVERS && i <= a_index; j++) {
+    for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) {
        for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
            if (i == a_index) {
                *a_srvr_addr = ntohl(sa->sa_ip);
@@ -1147,7 +1250,7 @@ int SRXAFSCB_GetServerPrefs(
 
     return 0;
 }
+
 
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_GetCellServDB
@@ -1171,41 +1274,40 @@ int SRXAFSCB_GetServerPrefs(
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetCellServDB(
-    struct rx_call *a_call,
-    afs_int32 a_index,
-    char **a_name,
-    afs_int32 *a_hosts)
+int
+SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
+                      char **a_name, serverList * a_hosts)
 {
-    afs_int32 i, j;
+    afs_int32 i, j = 0;
     struct cell *tcell;
-    struct afs_q *cq, *tq;
     char *t_name, *p_name = NULL;
 
     RX_AFS_GLOCK();
     AFS_STATCNT(SRXAFSCB_GetCellServDB);
 
-    memset(a_hosts, 0, AFSMAXCELLHOSTS * sizeof(afs_int32));
-
-    /* search the list for the cell with this index */
-    ObtainReadLock(&afs_xcell);
-    for (i=0, cq = CellLRU.next; cq != &CellLRU && i<= a_index; cq = tq, i++) {
-        tq = QNext(cq);
-       if (i == a_index) {
-           tcell = QTOC(cq);
-           p_name = tcell->cellName;
-           for (j = 0 ; j < AFSMAXCELLHOSTS && tcell->cellHosts[j] ; j++) {
-               a_hosts[j] = ntohl(tcell->cellHosts[j]->addr->sa_ip);
-           }
-       }
-    }
+    tcell = afs_GetCellByIndex(a_index, READ_LOCK);
 
-    if (p_name)
-       i = strlen(p_name);
-    else
+    if (!tcell) {
        i = 0;
-    t_name = (char *)rxi_Alloc(i+1);
+       a_hosts->serverList_val = 0;
+       a_hosts->serverList_len = 0;
+    } else {
+       p_name = tcell->cellName;
+       for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
+       i = strlen(p_name);
+       a_hosts->serverList_val = afs_osi_Alloc(j * sizeof(afs_int32));
+       osi_Assert(a_hosts->serverList_val != NULL);
+       a_hosts->serverList_len = j;
+       for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
+           a_hosts->serverList_val[j] =
+               ntohl(tcell->cellHosts[j]->addr->sa_ip);
+       afs_PutCell(tcell, READ_LOCK);
+    }
+
+    t_name = afs_osi_Alloc(i + 1);
     if (t_name == NULL) {
+       if (tcell != NULL)
+           afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
        RX_AFS_GUNLOCK();
        return ENOMEM;
     }
@@ -1214,14 +1316,12 @@ int SRXAFSCB_GetCellServDB(
     if (p_name)
        memcpy(t_name, p_name, i);
 
-    ReleaseReadLock(&afs_xcell);
-
     RX_AFS_GUNLOCK();
 
     *a_name = t_name;
     return 0;
 }
+
 
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_GetLocalCell
@@ -1243,13 +1343,11 @@ int SRXAFSCB_GetCellServDB(
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetLocalCell(
-    struct rx_call *a_call,
-    char **a_name)
+int
+SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
 {
     int plen;
     struct cell *tcell;
-    struct afs_q *cq, *tq;
     char *t_name, *p_name = NULL;
 
     RX_AFS_GLOCK();
@@ -1258,25 +1356,17 @@ int SRXAFSCB_GetLocalCell(
     /* Search the list for the primary cell. Cell number 1 is only
      * the primary cell is when no other cell is explicitly marked as
      * the primary cell.  */
-    ObtainReadLock(&afs_xcell);
-    for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
-        tq = QNext(cq);
-       tcell = QTOC(cq);
-       if (tcell->states & CPrimary) {
-           p_name = tcell->cellName;
-           break;
-       }
-        if (tcell->cell == 1) {
-           p_name = tcell->cellName;
-       }
-    }
-
+    tcell = afs_GetPrimaryCell(READ_LOCK);
+    if (tcell)
+       p_name = tcell->cellName;
     if (p_name)
        plen = strlen(p_name);
     else
        plen = 0;
-    t_name = (char *)rxi_Alloc(plen+1);
+    t_name = afs_osi_Alloc(plen + 1);
     if (t_name == NULL) {
+       if (tcell)
+           afs_PutCell(tcell, READ_LOCK);
        RX_AFS_GUNLOCK();
        return ENOMEM;
     }
@@ -1285,11 +1375,11 @@ int SRXAFSCB_GetLocalCell(
     if (p_name)
        memcpy(t_name, p_name, plen);
 
-    ReleaseReadLock(&afs_xcell);
-
     RX_AFS_GUNLOCK();
 
     *a_name = t_name;
+    if (tcell)
+       afs_PutCell(tcell, READ_LOCK);
     return 0;
 }
 
@@ -1309,10 +1399,9 @@ int SRXAFSCB_GetLocalCell(
  *
  * Returns void.
  */
-static void afs_MarshallCacheConfig(
-    afs_uint32 callerVersion,
-    cm_initparams_v1 *config,
-    afs_uint32 *ptr)
+static void
+afs_MarshallCacheConfig(afs_uint32 callerVersion, cm_initparams_v1 * config,
+                       afs_uint32 * ptr)
 {
     AFS_STATCNT(afs_MarshallCacheConfig);
     /*
@@ -1327,9 +1416,8 @@ static void afs_MarshallCacheConfig(
     *(ptr++) = config->cacheSize;
     *(ptr++) = config->setTime;
     *(ptr++) = config->memCache;
-
 }
+
 
 /*------------------------------------------------------------------------
  * EXPORTED SRXAFSCB_GetCacheConfig
@@ -1356,12 +1444,10 @@ static void afs_MarshallCacheConfig(
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int SRXAFSCB_GetCacheConfig(
-    struct rx_call *a_call,
-    afs_uint32 callerVersion,
-    afs_uint32 *serverVersion,
-    afs_uint32 *configCount,
-    cacheConfig *config)
+int
+SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
+                       afs_uint32 * serverVersion, afs_uint32 * configCount,
+                       cacheConfig * config)
 {
     afs_uint32 *t_config;
     size_t allocsize;
@@ -1374,7 +1460,7 @@ int SRXAFSCB_GetCacheConfig(
      * Currently only support version 1
      */
     allocsize = sizeof(cm_initparams_v1);
-    t_config = (afs_uint32 *)rxi_Alloc(allocsize);
+    t_config = afs_osi_Alloc(allocsize);
     if (t_config == NULL) {
        RX_AFS_GUNLOCK();
        return ENOMEM;
@@ -1395,7 +1481,7 @@ int SRXAFSCB_GetCacheConfig(
     *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
     *configCount = allocsize;
     config->cacheConfig_val = t_config;
-    config->cacheConfig_len = allocsize/sizeof(afs_uint32);
+    config->cacheConfig_len = allocsize / sizeof(afs_uint32);
 
     RX_AFS_GUNLOCK();
 
@@ -1426,13 +1512,10 @@ int SRXAFSCB_GetCacheConfig(
  *
  * Side Effects:
  *------------------------------------------------------------------------*/
-SRXAFSCB_FetchData(rxcall, Fid, Fd, Position, Length, TotalLength)
-    struct rx_call *rxcall;
-    struct AFSFid *Fid;
-    afs_int32 Fd;
-    afs_int64 Position;
-    afs_int64 Length;
-    afs_int64 *TotalLength;
+int
+SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
+                  afs_int64 Position, afs_int64 Length,
+                  afs_int64 * TotalLength)
 {
     return ENOSYS;
 }
@@ -1462,13 +1545,243 @@ SRXAFSCB_FetchData(rxcall, Fid, Fd, Position, Length, TotalLength)
  * Side Effects:
  *      As advertised.
  *------------------------------------------------------------------------*/
-SRXAFSCB_StoreData(rxcall, Fid, Fd, Position, Length, TotalLength)
-    struct rx_call *rxcall;
-    struct AFSFid *Fid;
-    afs_int32 Fd;
-    afs_int64 Position;
-    afs_int64 Length;
-    afs_int64 *TotalLength;
+int
+SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
+                  afs_int64 Position, afs_int64 Length,
+                  afs_int64 * TotalLength)
 {
     return ENOSYS;
 }
+
+/*------------------------------------------------------------------------
+ * EXPORTED SRXAFSCB_GetCellByNum
+ *
+ * Description:
+ *     Routine to get information about a cell specified by its
+ *     cell number (returned by GetCE/GetCE64).
+ *
+ * Arguments:
+ *     a_call    : Ptr to Rx call on which this request came in.
+ *     a_cellnum : Input cell number
+ *     a_name    : Output cell name (one zero byte when no such cell).
+ *     a_hosts   : Output cell database servers in host byte order.
+ *
+ * Returns:
+ *     0 on success
+ *
+ * Environment:
+ *     Nothing interesting.
+ *
+ * Side Effects:
+ *     As advertised.
+ *------------------------------------------------------------------------*/
+
+int
+SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
+                     char **a_name, serverList * a_hosts)
+{
+    afs_int32 i, sn;
+    struct cell *tcell;
+
+    RX_AFS_GLOCK();
+    AFS_STATCNT(SRXAFSCB_GetCellByNum);
+
+    a_hosts->serverList_val = 0;
+    a_hosts->serverList_len = 0;
+
+    tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
+    if (!tcell) {
+       *a_name = afs_strdup("");
+       RX_AFS_GUNLOCK();
+       return 0;
+    }
+
+    ObtainReadLock(&tcell->lock);
+    *a_name = afs_strdup(tcell->cellName);
+
+    for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
+    a_hosts->serverList_len = sn;
+    a_hosts->serverList_val = afs_osi_Alloc(sn * sizeof(afs_int32));
+    osi_Assert(a_hosts->serverList_val != NULL);
+
+    for (i = 0; i < sn; i++)
+       a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
+    ReleaseReadLock(&tcell->lock);
+    afs_PutCell(tcell, READ_LOCK);
+
+    RX_AFS_GUNLOCK();
+    return 0;
+}
+
+int
+SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
+                            struct interfaceAddr *addr,
+                            Capabilities * capabilities)
+{
+    int i;
+    int code = 0;
+    afs_uint32 *dataBuffP;
+    afs_int32 dataBytes;
+
+    RX_AFS_GLOCK();
+
+    AFS_STATCNT(SRXAFSCB_WhoAreYou);
+
+    ObtainReadLock(&afs_xinterface);
+
+    /* return all network interface addresses */
+    addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
+    addr->uuid = afs_cb_interface.uuid;
+    for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
+       addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
+       addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
+       addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
+    }
+
+    ReleaseReadLock(&afs_xinterface);
+
+    RX_AFS_GUNLOCK();
+
+    dataBytes = 1 * sizeof(afs_uint32);
+    dataBuffP = afs_osi_Alloc(dataBytes);
+    osi_Assert(dataBuffP != NULL);
+    dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
+    capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
+    capabilities->Capabilities_val = dataBuffP;
+
+    return code;
+}
+
+
+#if 0 && defined(AFS_LINUX24_ENV)
+extern struct vcache *afs_globalVp;
+
+int recurse_dcache_parent(parent, a_index, addr, inode, flags, time, fileName)
+     struct dentry * parent;
+    afs_int32 a_index;
+    afs_int32 *addr;
+    afs_int32 *inode;
+    afs_int32 *flags;
+    afs_int32 *time;
+    char ** fileName;
+{
+       struct dentry *this_parent = parent;
+       struct list_head *next;
+       int found = 0;
+       struct dentry *dentry;
+
+repeat:
+       next = this_parent->d_subdirs.next;
+resume:
+       while (next != &this_parent->d_subdirs) {
+               struct list_head *tmp = next;
+               dentry = list_entry(tmp, struct dentry, d_child);
+               if (a_index == 0)
+                 goto searchdone3;
+               a_index--;
+               next = tmp->next;
+               /*
+                * Descend a level if the d_subdirs list is non-empty.
+                */
+               if (!list_empty(&dentry->d_subdirs)) {
+                       this_parent = dentry;
+                       goto repeat;
+               }
+       }
+       /*
+        * All done at this level ... ascend and resume the search.
+        */
+       if (this_parent != parent) {
+               next = this_parent->d_child.next;
+               this_parent = this_parent->d_parent;
+               goto resume;
+       }
+       goto ret;
+
+ searchdone3:
+    if (d_unhashed(dentry))
+      *flags = 1;
+    else
+      *flags = 0;
+
+    *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
+    *inode = ITOAFS(dentry->d_inode);
+    *addr = atomic_read(&(dentry)->d_count);
+    *time = dentry->d_time;
+
+    return 0;
+ ret:
+    return 1;
+}
+#endif
+
+int
+SRXAFSCB_GetDE(struct rx_call *a_call, afs_int32 a_index, afs_int32 *addr,
+              afs_int32 *inode, afs_int32 *flags, afs_int32 *time,
+              char ** fileName)
+{ /*SRXAFSCB_GetDE*/
+    int code = 0;                              /*Return code*/
+#if 0 && defined(AFS_LINUX24_ENV)
+    int i;                     /*Loop variable*/
+    struct vcache *tvc = afs_globalVp;
+    struct dentry *dentry;
+    struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
+
+#ifdef RX_ENABLE_LOCKS
+    AFS_GLOCK();
+#endif /* RX_ENABLE_LOCKS */
+
+#if defined(AFS_LINUX24_ENV)
+    spin_lock(&dcache_lock);
+#endif
+
+    cur = head;
+    while ((cur = cur->next) != head) {
+      dentry = list_entry(cur, struct dentry, d_alias);
+
+      dget_locked(dentry);
+
+#if defined(AFS_LINUX24_ENV)
+      spin_unlock(&dcache_lock);
+#endif
+      if (a_index == 0)
+       goto searchdone2;
+      a_index--;
+
+      if (recurse_dcache_parent(dentry, a_index, addr, inode, flags, time, fileName) == 0) {
+       dput(dentry);
+       code = 0;
+       goto fcnDone;
+      }
+      dput(dentry);
+    }
+ searchdone2:
+    if (cur == head) {
+       /*Past EOF*/
+       code = 1;
+       *fileName = afs_strdup("");
+       goto fcnDone;
+    }
+
+    if (d_unhashed(dentry))
+      *flags = 1;
+    else
+      *flags = 0;
+
+    *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
+    *inode = ITOAFS(dentry->d_inode);
+    *addr = atomic_read(&(dentry)->d_count);
+    *time = dentry->d_time;
+
+    dput(dentry);
+    code = 0;
+
+fcnDone:
+
+#ifdef RX_ENABLE_LOCKS
+    AFS_GUNLOCK();
+#endif /* RX_ENABLE_LOCKS */
+#endif
+    return(code);
+
+} /*SRXAFSCB_GetDE*/