afs: Remove afs_xosi
[openafs.git] / src / afs / afs_callback.c
index 49c6bb9..f8b7c6a 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
@@ -16,8 +16,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 */
@@ -54,12 +52,17 @@ static struct ltable {
     "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_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;
@@ -96,8 +99,8 @@ 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 i;             /*Loop variable */
+    struct vcache *tvc;        /*Ptr to current cache entry */
     int code;                  /*Return code */
     XSTATS_DECLS;
 
@@ -125,37 +128,45 @@ SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
      * 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->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;
 
     /*
@@ -174,8 +185,8 @@ int
 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
                 struct AFSDBCacheEntry64 *a_result)
 {
-    register int i;            /*Loop variable */
-    register struct vcache *tvc;       /*Ptr to current cache entry */
+    int i;             /*Loop variable */
+    struct vcache *tvc;        /*Ptr to current cache entry */
     int code;                  /*Return code */
     XSTATS_DECLS;
 
@@ -203,38 +214,41 @@ SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
      * 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 */
-#if !defined(AFS_64BIT_ENV) 
-    a_result->Length.high = 0;
-    a_result->Length.low = tvc->m.Length;
-#else
-    a_result->Length = tvc->m.Length;
-#endif
-    a_result->DataVersion = hgetlo(tvc->m.DataVersion);
+#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;
 
     /*
@@ -288,12 +302,37 @@ SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
     XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
 
     AFS_STATCNT(SRXAFSCB_GetLock);
+    memset(a_result, 0, sizeof(*a_result));
     nentries = sizeof(ltable) / sizeof(struct ltable);
-    if (a_index < 0 || a_index >= nentries) {
+    if (a_index < 0 || a_index >= nentries+afs_cellindex) {
        /*
         * Past EOF
         */
        code = 1;
+    } 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.
@@ -310,9 +349,9 @@ SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
            ((struct afs_lock *)(tl->addr))->num_waiting;
 #ifdef INSTRUMENT_LOCKS
        a_result->lock.pid_last_reader =
-           ((struct afs_lock *)(tl->addr))->pid_last_reader;
+           MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_last_reader);
        a_result->lock.pid_writer =
-           ((struct afs_lock *)(tl->addr))->pid_writer;
+           MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_writer);
        a_result->lock.src_indicator =
            ((struct afs_lock *)(tl->addr))->src_indicator;
 #else
@@ -337,7 +376,7 @@ SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
  *
  * 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.
  *
@@ -359,13 +398,16 @@ Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts ot
  *------------------------------------------------------------------------*/
 
 static int
-ClearCallBack(register struct rx_connection *a_conn,
-             register struct AFSFid *a_fid)
+ClearCallBack(struct rx_connection *a_conn,
+             struct AFSFid *a_fid)
 {
-    register struct vcache *tvc;
-    register int i;
+    struct vcache *tvc;
+    int i;
     struct VenusFid localFid;
     struct volume *tv;
+#ifdef AFS_DARWIN80_ENV
+    vnode_t vp;
+#endif
 
     AFS_STATCNT(ClearCallBack);
 
@@ -384,39 +426,74 @@ ClearCallBack(register struct rx_connection *a_conn,
      */
     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.
             */
+loop1:
+               ObtainReadLock(&afs_xvcache);
                i = VCHashV(&localFid);
-               for (tvc = afs_vhashTV[i]; tvc; tvc = tvc->vhnext) {
-                   if (tvc->fid.Fid.Volume == a_fid->Volume) {
+               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;
+                           localFid.Cell = tvc->f.fid.Cell;
                        tvc->dchint = NULL;     /* invalidate hints */
-                       ObtainWriteLock(&afs_xcbhash, 449);
-                       afs_DequeueCallback(tvc);
-                       tvc->states &= ~(CStatd | CUnique | CBulkFetching);
+                       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);
+                       afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
                        afs_allCBs++;
-                       if (tvc->fid.Fid.Vnode & 1)
+                       if (tvc->f.fid.Fid.Vnode & 1)
                            afs_oddCBs++;
                        else
                            afs_evenCBs++;
-                       ReleaseWriteLock(&afs_xcbhash);
-                       if (tvc->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,
+                                  tvc->f.states, ICL_TYPE_INT32,
                                   a_fid->Volume);
-                   } else if ((tvc->states & CMValid)
-                              && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
-                       tvc->states &= ~CMValid;
+#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
@@ -432,34 +509,68 @@ ClearCallBack(register struct rx_connection *a_conn,
            /*
             * 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 */
            else
                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) {
+           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 */
-                   ObtainWriteLock(&afs_xcbhash, 450);
-                   afs_DequeueCallback(tvc);
-                   tvc->states &= ~(CStatd | CUnique | CBulkFetching);
-                   ReleaseWriteLock(&afs_xcbhash);
-                   if (a_fid->Vnode & 1 || (vType(tvc) == VDIR))
-                       osi_dnlc_purgedp(tvc);
+                   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);
+                   afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
                    afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
                               ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
-                              tvc->states, ICL_TYPE_LONG, 0);
+                              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 */
+           ReleaseReadLock(&afs_xvcache);
        }                       /*Clear callbacks for one file */
     }
 
@@ -496,12 +607,12 @@ ClearCallBack(register struct rx_connection *a_conn,
  *------------------------------------------------------------------------*/
 
 int
-SRXAFSCB_CallBack(struct rx_call *a_call, register struct AFSCBFids *a_fids,
+SRXAFSCB_CallBack(struct rx_call *a_call, struct AFSCBFids *a_fids,
                  struct AFSCBs *a_callbacks)
 {
-    register int i;            /*Loop variable */
+    int i;             /*Loop variable */
     struct AFSFid *tfid;       /*Ptr to current fid */
-    register struct rx_connection *tconn;      /*Call's connection */
+    struct rx_connection *tconn;       /*Call's connection */
     int code = 0;
     XSTATS_DECLS;
 
@@ -593,10 +704,10 @@ SRXAFSCB_Probe(struct rx_call *a_call)
 int
 SRXAFSCB_InitCallBackState(struct rx_call *a_call)
 {
-    register int i;
-    register struct vcache *tvc;
-    register struct rx_connection *tconn;
-    register struct rx_peer *peer;
+    int i;
+    struct vcache *tvc;
+    struct rx_connection *tconn;
+    struct rx_peer *peer;
     struct server *ts;
     int code = 0;
     XSTATS_DECLS;
@@ -621,25 +732,26 @@ SRXAFSCB_InitCallBackState(struct rx_call *a_call)
            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 = NULL;
-                       tvc->states &= ~(CStatd | CUnique | CBulkFetching);
-                       ReleaseWriteLock(&afs_xcbhash);
+                       afs_StaleVCacheFlags(tvc, AFS_STALEVC_NODNLC |
+                                                 AFS_STALEVC_CLEARCB,
+                                            CUnique | CBulkFetching);
                    }
                }
+
+           /* 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;
+           struct volume *tv;
+           int j;
 
            for (i = 0; i < NVOLS; i++)
                for (tv = afs_volumes[i]; tv; tv = tv->next) {
-                   for (j = 0; j < MAXHOSTS; j++)
+                   for (j = 0; j < AFS_MAXHOSTS; j++)
                        if (tv->serverHost[j] == ts)
                            afs_ResetVolumeInfo(tv);
                }
@@ -729,7 +841,7 @@ 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)
 {
-    register int code;         /*Return value */
+    int code;          /*Return value */
     afs_int32 *dataBuffP;      /*Ptr to data to be returned */
     afs_int32 dataBytes;       /*Bytes in data buffer */
     XSTATS_DECLS;
@@ -768,6 +880,7 @@ SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
         */
        dataBytes = sizeof(struct afs_CMStats);
        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_val = dataBuffP;
@@ -788,6 +901,7 @@ SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
        afs_CountServers();
        dataBytes = sizeof(afs_stats_cmperf);
        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_val = dataBuffP;
@@ -812,6 +926,7 @@ SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
 
        dataBytes = sizeof(afs_stats_cmfullperf);
        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_val = dataBuffP;
@@ -869,7 +984,7 @@ afs_RXCallBackServer(void)
     /*
      * Donate this process to Rx.
      */
-    rx_ServerProc();
+    rx_ServerProc(NULL);
     return (0);
 
 }                              /*afs_RXCallBackServer */
@@ -919,7 +1034,7 @@ shutdown_CB(void)
  *      a_call : Ptr to Rx call on which this request came in.
  *
  * Returns:
- *      RXGEN_OPCODE (always). 
+ *      RXGEN_OPCODE (always).
  *
  * Environment:
  *      Nothing interesting.
@@ -1165,8 +1280,8 @@ SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
        p_name = tcell->cellName;
        for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
        i = strlen(p_name);
-       a_hosts->serverList_val =
-           (afs_int32 *) afs_osi_Alloc(j * sizeof(afs_int32));
+       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] =
@@ -1174,9 +1289,10 @@ SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
        afs_PutCell(tcell, READ_LOCK);
     }
 
-    t_name = (char *)afs_osi_Alloc(i + 1);
+    t_name = afs_osi_Alloc(i + 1);
     if (t_name == NULL) {
-       afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
+       if (tcell != NULL)
+           afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
        RX_AFS_GUNLOCK();
        return ENOMEM;
     }
@@ -1232,7 +1348,7 @@ SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
        plen = strlen(p_name);
     else
        plen = 0;
-    t_name = (char *)afs_osi_Alloc(plen + 1);
+    t_name = afs_osi_Alloc(plen + 1);
     if (t_name == NULL) {
        if (tcell)
            afs_PutCell(tcell, READ_LOCK);
@@ -1329,7 +1445,7 @@ SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
      * Currently only support version 1
      */
     allocsize = sizeof(cm_initparams_v1);
-    t_config = (afs_uint32 *) afs_osi_Alloc(allocsize);
+    t_config = afs_osi_Alloc(allocsize);
     if (t_config == NULL) {
        RX_AFS_GUNLOCK();
        return ENOMEM;
@@ -1470,8 +1586,8 @@ SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
 
     for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
     a_hosts->serverList_len = sn;
-    a_hosts->serverList_val =
-       (afs_int32 *) afs_osi_Alloc(sn * sizeof(afs_int32));
+    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);
@@ -1489,7 +1605,7 @@ SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
 {
     int i;
     int code = 0;
-    afs_int32 *dataBuffP;
+    afs_uint32 *dataBuffP;
     afs_int32 dataBytes;
 
     RX_AFS_GLOCK();
@@ -1499,6 +1615,7 @@ SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
     ObtainReadLock(&afs_xinterface);
 
     /* return all network interface addresses */
+    memset(addr, 0, sizeof(*addr));
     addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
     addr->uuid = afs_cb_interface.uuid;
     for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
@@ -1511,11 +1628,146 @@ SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
 
     RX_AFS_GUNLOCK();
 
-    dataBytes = 1 * sizeof(afs_int32);
-    dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
-    dataBuffP[0] = CAPABILITY_ERRORTRANS;
-    capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
+    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*/