remove CopyOnWrite2 and unused vars
[openafs.git] / src / viced / afsfileprocs.c
index d2f418b..4f5589e 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
 /*                                                                      */
 /* ********************************************************************** */
 
-/* 
- * in Check_PermissionRights, certain privileges are afforded to the owner 
- * of the volume, or the owner of a file.  Are these considered "use of 
- * privilege"? 
+/*
+ * in Check_PermissionRights, certain privileges are afforded to the owner
+ * of the volume, or the owner of a file.  Are these considered "use of
+ * privilege"?
  */
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
 #ifdef AFS_SGI_ENV
 #undef SHARED                  /* XXX */
 #endif
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#else
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-
-#ifndef AFS_LINUX20_ENV
+
+#ifdef HAVE_NET_IF_H
 #include <net/if.h>
+#endif
+
+#ifdef HAVE_NETINET_IF_ETHER_H
 #include <netinet/if_ether.h>
 #endif
+
+#if !defined(AFS_SGI_ENV) && defined(HAVE_SYS_MAP_H)
+#include <sys/map.h>
+#endif
+
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+
+#ifdef HAVE_SYS_LOCKF_H
+#include <sys/lockf.h>
+#endif
+
+#ifdef HAVE_SYS_DK_H
+#include <sys/dk.h>
 #endif
+
 #ifdef AFS_HPUX_ENV
 /* included early because of name conflict on IOPEN */
 #include <sys/inode.h>
@@ -61,10 +66,9 @@ RCSID
 #undef IOPEN
 #endif
 #endif /* AFS_HPUX_ENV */
-#include <afs/stds.h>
+
 #include <rx/xdr.h>
 #include <afs/nfs.h>
-#include <afs/assert.h>
 #include <lwp.h>
 #include <lock.h>
 #include <afs/afsint.h>
@@ -79,27 +83,10 @@ RCSID
 #include <afs/acl.h>
 #include <rx/rx.h>
 #include <rx/rx_globals.h>
-#include <sys/stat.h>
-#if ! defined(AFS_SGI_ENV) && ! defined(AFS_AIX32_ENV) && ! defined(AFS_NT40_ENV) && ! defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
-#include <sys/map.h>
-#endif
-#if !defined(AFS_NT40_ENV)
-#include <unistd.h>
-#endif
-#if !defined(AFS_SGI_ENV) && !defined(AFS_NT40_ENV)
-#ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
-#include <sys/lockf.h>
-#else
-#if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
-#include <sys/dk.h>
-#endif
-#endif
-#endif
+
 #include <afs/cellconfig.h>
 #include <afs/keys.h>
 
-#include <signal.h>
 #include <afs/partition.h>
 #include "viced_prototypes.h"
 #include "viced.h"
@@ -110,7 +97,7 @@ RCSID
 #include <afs/afsutil.h>
 #include <afs/dir.h>
 
-extern void SetDirHandle(register DirHandle * dir, register Vnode * vnode);
+extern void SetDirHandle(DirHandle * dir, Vnode * vnode);
 extern void FidZap(DirHandle * file);
 extern void FidZero(DirHandle * file);
 
@@ -118,17 +105,6 @@ extern void FidZero(DirHandle * file);
 pthread_mutex_t fileproc_glock_mutex;
 #endif /* AFS_PTHREAD_ENV */
 
-#ifdef O_LARGEFILE
-#define afs_stat       stat64
-#define afs_fstat      fstat64
-#define afs_open       open64
-#else /* !O_LARGEFILE */
-#define afs_stat       stat
-#define afs_fstat      fstat
-#define afs_open       open
-#endif /* !O_LARGEFILE */
-
-
 /* Useful local defines used by this module */
 
 #define        DONTCHECK       0
@@ -189,8 +165,6 @@ struct afs_FSStats {
 
 struct afs_FSStats afs_fsstats;
 
-void ResetDebug(), SetDebug(), Terminate();
-
 int LogLevel = 0;
 int supported = 1;
 int Console = 0;
@@ -198,6 +172,8 @@ afs_int32 BlocksSpare = 1024;       /* allow 1 MB overruns */
 afs_int32 PctSpare;
 extern afs_int32 implicitAdminRights;
 extern afs_int32 readonlyServer;
+extern int CopyOnWrite_calls, CopyOnWrite_off0, CopyOnWrite_size0;
+extern afs_fsize_t CopyOnWrite_maxsize;
 
 /*
  * Externals used by the xstat code.
@@ -207,25 +183,19 @@ extern int CEs, CEBlocks;
 
 extern int HTs, HTBlocks;
 
-afs_int32 FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
-                           register struct rx_call *Call, afs_sfsize_t Pos,
-                           afs_sfsize_t Len, afs_int32 Int64Mode,
-#if FS_STATS_DETAILED
-                           afs_sfsize_t * a_bytesToFetchP,
-                           afs_sfsize_t * a_bytesFetchedP
-#endif                         /* FS_STATS_DETAILED */
-    );
+static afs_int32 FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
+                                  struct rx_call *Call, afs_sfsize_t Pos,
+                                  afs_sfsize_t Len, afs_int32 Int64Mode,
+                                  afs_sfsize_t * a_bytesToFetchP,
+                                  afs_sfsize_t * a_bytesFetchedP);
 
-afs_int32 StoreData_RXStyle(Volume * volptr, Vnode * targetptr,
-                           struct AFSFid *Fid, struct client *client,
-                           register struct rx_call *Call, afs_fsize_t Pos,
-                           afs_fsize_t Length, afs_fsize_t FileLength,
-                           int sync,
-#if FS_STATS_DETAILED
-                           afs_sfsize_t * a_bytesToStoreP,
-                           afs_sfsize_t * a_bytesStoredP
-#endif                         /* FS_STATS_DETAILED */
-    );
+static afs_int32 StoreData_RXStyle(Volume * volptr, Vnode * targetptr,
+                                  struct AFSFid *Fid, struct client *client,
+                                  struct rx_call *Call, afs_fsize_t Pos,
+                                  afs_fsize_t Length, afs_fsize_t FileLength,
+                                  int sync,
+                                  afs_sfsize_t * a_bytesToStoreP,
+                                  afs_sfsize_t * a_bytesStoredP);
 
 #ifdef AFS_SGI_XFS_IOPS_ENV
 #include <afs/xfsattrs.h>
@@ -244,7 +214,7 @@ GetLinkCount(Volume * avp, struct stat *astat)
 afs_int32
 SpareComp(Volume * avolp)
 {
-    register afs_int32 temp;
+    afs_int32 temp;
 
     FS_LOCK;
     if (PctSpare) {
@@ -269,7 +239,7 @@ SpareComp(Volume * avolp)
  * the Cache Manager knows that the volume must be purged from the stat cache.
  */
 static void
-SetVolumeSync(register struct AFSVolSync *async, register Volume * avol)
+SetVolumeSync(struct AFSVolSync *async, Volume * avol)
 {
     FS_LOCK;
     /* date volume instance was created */
@@ -287,13 +257,72 @@ SetVolumeSync(register struct AFSVolSync *async, register Volume * avol)
     FS_UNLOCK;
 }                              /*SetVolumeSync */
 
+/**
+ * Verify that the on-disk size for a vnode matches the length in the vnode
+ * index.
+ *
+ * @param[in] vp   Volume pointer
+ * @param[in] vnp  Vnode pointer
+ * @param[in] alen Size of the vnode on disk, if known. If unknown, give -1,
+ *                 and CheckLength itself will determine the on-disk size.
+ *
+ * @return operation status
+ *  @retval 0 lengths match
+ *  @retval nonzero Error; either the lengths do not match or there was an
+ *                  error determining the on-disk size. The volume should be
+ *                  taken offline and salvaged.
+ */
+static int
+CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
+{
+    afs_sfsize_t vlen;
+    VN_GET_LEN(vlen, vnp);
+
+    if (alen < 0) {
+       FdHandle_t *fdP;
+
+       fdP = IH_OPEN(vnp->handle);
+       if (fdP == NULL) {
+           ViceLog(0, ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n",
+                       afs_printable_uint32_lu(vp->hashid),
+                       afs_printable_uint32_lu(Vn_id(vnp)),
+                       afs_printable_uint32_lu(vnp->disk.uniquifier)));
+           return -1;
+       }
+       alen = FDH_SIZE(fdP);
+       FDH_CLOSE(fdP);
+       if (alen < 0) {
+           afs_int64 alen64 = alen;
+           ViceLog(0, ("CheckLength: cannot get size for inode for fid "
+                       "%lu.%lu.%lu; FDH_SIZE returned %" AFS_INT64_FMT "\n",
+                       afs_printable_uint32_lu(vp->hashid),
+                       afs_printable_uint32_lu(Vn_id(vnp)),
+                       afs_printable_uint32_lu(vnp->disk.uniquifier),
+                       alen64));
+           return -1;
+       }
+    }
+
+    if (alen != vlen) {
+       afs_int64 alen64 = alen, vlen64 = vlen;
+       ViceLog(0, ("Fid %lu.%lu.%lu has inconsistent length (index "
+                   "%lld inode %lld ); volume must be salvaged\n",
+                   afs_printable_uint32_lu(vp->hashid),
+                   afs_printable_uint32_lu(Vn_id(vnp)),
+                   afs_printable_uint32_lu(vnp->disk.uniquifier),
+                   vlen64, alen64));
+       return -1;
+    }
+    return 0;
+}
+
 /*
  * Note that this function always returns a held host, so
  * that CallPostamble can block without the host's disappearing.
  * Call returns rx connection in passed in *tconn
  */
 static int
-CallPreamble(register struct rx_call *acall, int activecall,
+CallPreamble(struct rx_call *acall, int activecall,
             struct rx_connection **tconn, struct host **ahostp)
 {
     struct host *thost;
@@ -301,8 +330,9 @@ CallPreamble(register struct rx_call *acall, int activecall,
     int retry_flag = 1;
     int code = 0;
     char hoststr[16], hoststr2[16];
+#ifdef AFS_PTHREAD_ENV
     struct ubik_client *uclient;
-
+#endif
     *ahostp = NULL;
 
     if (!tconn) {
@@ -315,7 +345,7 @@ CallPreamble(register struct rx_call *acall, int activecall,
   retry:
     tclient = h_FindClient_r(*tconn);
     if (!tclient) {
-       ViceLog(0, ("CallPreamble: Couldn't get CPS. Too many lockers\n"));
+       ViceLog(0, ("CallPreamble: Couldn't get client.\n"));
        H_UNLOCK;
        return VBUSY;
     }
@@ -338,12 +368,14 @@ CallPreamble(register struct rx_call *acall, int activecall,
 
        /* Is it still necessary to drop this? We hit the net, we should... */
        H_UNLOCK;
-       if (uclient) 
+       if (uclient) {
            hpr_End(uclient);
+           uclient = NULL;
+       }
        code = hpr_Initialize(&uclient);
 
        if (!code)
-           assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
+           osi_Assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
        H_LOCK;
 #else
        code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
@@ -377,7 +409,7 @@ CallPreamble(register struct rx_call *acall, int activecall,
        if (BreakDelayedCallBacks_r(thost)) {
            ViceLog(0,
                    ("BreakDelayedCallbacks FAILED for host %s:%d which IS UP.  Connection from %s:%d.  Possible network or routing failure.\n",
-                    afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2), 
+                    afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
                     ntohs(rxr_PortOf(*tconn))));
            if (MultiProbeAlternateAddress_r(thost)) {
                ViceLog(0,
@@ -393,7 +425,7 @@ CallPreamble(register struct rx_call *acall, int activecall,
                if (BreakDelayedCallBacks_r(thost)) {
                    ViceLog(0,
                            ("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP.  Connection from %s:%d.  Possible network or routing failure.\n",
-                             afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2), 
+                             afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
                              ntohs(rxr_PortOf(*tconn))));
                    code = -1;
                }
@@ -413,39 +445,49 @@ CallPreamble(register struct rx_call *acall, int activecall,
 
 
 static afs_int32
-CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
+CallPostamble(struct rx_connection *aconn, afs_int32 ret,
              struct host *ahost)
 {
     struct host *thost;
     struct client *tclient;
     int translate = 0;
-    int held;
 
     H_LOCK;
     tclient = h_FindClient_r(aconn);
-    if (!tclient) 
+    if (!tclient)
        goto busyout;
     thost = tclient->host;
     if (thost->hostFlags & HERRORTRANS)
        translate = 1;
     h_ReleaseClient_r(tclient);
-    held = h_Held_r(thost);
-    if (held)
-       h_Release_r(thost);
-    if (ahost && ahost != thost) {
-       char hoststr[16], hoststr2[16]; 
-       ViceLog(0, ("CallPostamble: ahost %s:%d (%x) != thost %s:%d (%x)\n",
-               afs_inet_ntoa_r(ahost->host, hoststr), ntohs(ahost->port),
-               ahost, 
-               afs_inet_ntoa_r(thost->host, hoststr2), ntohs(thost->port),
-               thost));
-       h_Release_r(ahost);
-    } else if (!ahost) {
-       char hoststr[16];       
-       ViceLog(0, ("CallPostamble: null ahost for thost %s:%d (%x)\n",
-               afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port),
-               thost));
+
+    if (ahost) {
+           if (ahost != thost) {
+                   /* host/client recycle */
+                   char hoststr[16], hoststr2[16];
+                   ViceLog(0, ("CallPostamble: ahost %s:%d (%p) != thost "
+                               "%s:%d (%p)\n",
+                               afs_inet_ntoa_r(ahost->host, hoststr),
+                               ntohs(ahost->port),
+                               ahost,
+                               afs_inet_ntoa_r(thost->host, hoststr2),
+                               ntohs(thost->port),
+                               thost));
+           }
+           /* return the reference taken in CallPreamble */
+           h_Release_r(ahost);
+    } else {
+           char hoststr[16];
+           ViceLog(0, ("CallPostamble: null ahost for thost %s:%d (%p)\n",
+                       afs_inet_ntoa_r(thost->host, hoststr),
+                       ntohs(thost->port),
+                       thost));
     }
+
+    /* return the reference taken in local h_FindClient_r--h_ReleaseClient_r
+     * does not decrement refcount on client->host */
+    h_Release_r(thost);
+
  busyout:
     H_UNLOCK;
     return (translate ? sys_error_to_et(ret) : ret);
@@ -457,10 +499,11 @@ CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
  * are incremented and they must be eventualy released.
  */
 static afs_int32
-CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
+CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
+                   Vnode ** vptr, int lock)
 {
-    int fileCode = 0;
-    afs_int32 local_errorCode, errorCode = -1;
+    Error fileCode = 0;
+    Error local_errorCode, errorCode = -1;
     static struct timeval restartedat = { 0, 0 };
 
     if (fid->Volume == 0 || fid->Vnode == 0)   /* not: || fid->Unique == 0) */
@@ -469,52 +512,59 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
        extern int VInit;
 
        while (1) {
-           int restarting = 
+           int restarting =
 #ifdef AFS_DEMAND_ATTACH_FS
                VSALVAGE
 #else
                VRESTARTING
 #endif
                ;
+#ifdef AFS_PTHREAD_ENV
+           static const struct timespec timeout_ts = { 0, 0 };
+           static const struct timespec * const ts = &timeout_ts;
+#else
+           static const struct timespec * const ts = NULL;
+#endif
 
            errorCode = 0;
-           *volptr = VGetVolume(&local_errorCode, &errorCode, (afs_int32) fid->Volume);
+           *volptr = VGetVolumeWithCall(&local_errorCode, &errorCode,
+                                              fid->Volume, ts, cbv);
            if (!errorCode) {
-               assert(*volptr);
+               osi_Assert(*volptr);
                break;
            }
            if ((errorCode == VOFFLINE) && (VInit < 2)) {
                /* The volume we want may not be attached yet because
                 * the volume initialization is not yet complete.
-                * We can do several things: 
+                * We can do several things:
                 *     1.  return -1, which will cause users to see
                 *         "connection timed out".  This is more or
                 *         less the same as always, except that the servers
                 *         may appear to bounce up and down while they
                 *         are actually restarting.
-                *     2.  return VBUSY which will cause clients to 
+                *     2.  return VBUSY which will cause clients to
                 *         sleep and retry for 6.5 - 15 minutes, depending
                 *         on what version of the CM they are running.  If
-                *         the file server takes longer than that interval 
+                *         the file server takes longer than that interval
                 *         to attach the desired volume, then the application
-                *         will see an ENODEV or EIO.  This approach has 
+                *         will see an ENODEV or EIO.  This approach has
                 *         the advantage that volumes which have been attached
                 *         are immediately available, it keeps the server's
                 *         immediate backlog low, and the call is interruptible
                 *         by the user.  Users see "waiting for busy volume."
                 *     3.  sleep here and retry.  Some people like this approach
-                *         because there is no danger of seeing errors.  However, 
-                *         this approach only works with a bounded number of 
+                *         because there is no danger of seeing errors.  However,
+                *         this approach only works with a bounded number of
                 *         clients, since the pending queues will grow without
                 *         stopping.  It might be better to find a way to take
                 *         this call and stick it back on a queue in order to
-                *         recycle this thread for a different request.    
+                *         recycle this thread for a different request.
                 *     4.  Return a new error code, which new cache managers will
                 *         know enough to interpret as "sleep and retry", without
                 *         the upper bound of 6-15 minutes that is imposed by the
                 *         VBUSY handling.  Users will see "waiting for
                 *         busy volume," so they know that something is
-                *         happening.  Old cache managers must be able to do  
+                *         happening.  Old cache managers must be able to do
                 *         something reasonable with this, for instance, mark the
                 *         server down.  Fortunately, any error code < 0
                 *         will elicit that behavior. See #1.
@@ -533,7 +583,7 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
                if (restartedat.tv_sec == 0) {
                    /* I'm not really worried about when we restarted, I'm   */
                    /* just worried about when the first VBUSY was returned. */
-                   TM_GetTimeOfDay(&restartedat, 0);
+                   FT_GetTimeOfDay(&restartedat, 0);
                    if (busyonrst) {
                        FS_LOCK;
                        afs_perfstats.fs_nBusies++;
@@ -542,7 +592,7 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
                    return (busyonrst ? VBUSY : restarting);
                } else {
                    struct timeval now;
-                   TM_GetTimeOfDay(&now, 0);
+                   FT_GetTimeOfDay(&now, 0);
                    if ((now.tv_sec - restartedat.tv_sec) < (11 * 60)) {
                        if (busyonrst) {
                            FS_LOCK;
@@ -555,7 +605,7 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
                    }
                }
            }
-           /* allow read operations on busy volume. 
+           /* allow read operations on busy volume.
             * must check local_errorCode because demand attach fs
             * can have local_errorCode == VSALVAGING, errorCode == VBUSY */
            else if (local_errorCode == VBUSY && lock == READ_LOCK) {
@@ -573,7 +623,7 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
                return (errorCode);
        }
     }
-    assert(*volptr);
+    osi_Assert(*volptr);
 
     /* get the vnode  */
     *vptr = VGetVnode(&errorCode, *volptr, fid->Vnode, lock);
@@ -581,13 +631,19 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
        return (errorCode);
     if ((*vptr)->disk.uniquifier != fid->Unique) {
        VPutVnode(&fileCode, *vptr);
-       assert(fileCode == 0);
+       osi_Assert(fileCode == 0);
        *vptr = 0;
        return (VNOVNODE);      /* return the right error code, at least */
     }
     return (0);
 }                              /*CheckVnode */
 
+static_inline afs_int32
+CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
+{
+    return CheckVnodeWithCall(fid, volptr, NULL, vptr, lock);
+}
+
 /*
  * This routine returns the ACL associated with the targetptr. If the
  * targetptr isn't a directory, we access its parent dir and get the ACL
@@ -605,10 +661,10 @@ SetAccessList(Vnode ** targetptr, Volume ** volume,
        *ACLSize = VAclSize(*targetptr);
        return (0);
     } else {
-       assert(Fid != 0);
+       osi_Assert(Fid != 0);
        while (1) {
            VnodeId parentvnode;
-           int errorCode = 0;
+           Error errorCode = 0;
 
            parentvnode = (*targetptr)->disk.parent;
            VPutVnode(&errorCode, *targetptr);
@@ -636,7 +692,7 @@ SetAccessList(Vnode ** targetptr, Volume ** volume,
 
 /* Must not be called with H_LOCK held */
 static void
-client_CheckRights(struct client *client, struct acl_accessList *ACL, 
+client_CheckRights(struct client *client, struct acl_accessList *ACL,
                   afs_int32 *rights)
 {
     *rights = 0;
@@ -654,7 +710,7 @@ client_HasAsMember(struct client *client, afs_int32 id)
     afs_int32 code = 0;
 
     ObtainReadLock(&client->lock);
-    if (client->CPS.prlist_len > 0 && !client->deleted && 
+    if (client->CPS.prlist_len > 0 && !client->deleted &&
        client->host && !(client->host->hostFlags & HOSTDELETED))
        code = acl_IsAMember(id, &client->CPS);
     ReleaseReadLock(&client->lock);
@@ -689,7 +745,7 @@ GetRights(struct client *client, struct acl_accessList *ACL,
     while (client->host->hostFlags & HCPS_INPROGRESS) {
        client->host->hostFlags |= HCPS_WAITING;        /* I am waiting */
 #ifdef AFS_PTHREAD_ENV
-       pthread_cond_wait(&client->host->cond, &host_glock_mutex);
+       CV_WAIT(&client->host->cond, &host_glock_mutex);
 #else /* AFS_PTHREAD_ENV */
        if ((code =
             LWP_WaitProcess(&(client->host->hostFlags))) != LWP_SUCCESS)
@@ -701,7 +757,7 @@ GetRights(struct client *client, struct acl_accessList *ACL,
        char hoststr[16];
        ViceLog(5,
                ("CheckRights: len=%u, for host=%s:%d\n",
-                client->host->hcps.prlist_len, 
+                client->host->hcps.prlist_len,
                 afs_inet_ntoa_r(client->host->host, hoststr),
                 ntohs(client->host->port)));
     } else
@@ -738,16 +794,16 @@ VanillaUser(struct client *client)
  * interface calls.
  */
 static afs_int32
-GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
-                Vnode ** targetptr, int chkforDir, Vnode ** parent,
-                struct client **client, int locktype, afs_int32 * rights,
-                afs_int32 * anyrights)
+GetVolumePackageWithCall(struct rx_connection *tcon, struct VCallByVol *cbv,
+                         AFSFid * Fid, Volume ** volptr, Vnode ** targetptr,
+                         int chkforDir, Vnode ** parent, struct client **client,
+                         int locktype, afs_int32 * rights, afs_int32 * anyrights)
 {
     struct acl_accessList *aCL;        /* Internal access List */
     int aCLSize;               /* size of the access list */
-    int errorCode = 0;         /* return code to caller */
+    Error errorCode = 0;               /* return code to caller */
 
-    if ((errorCode = CheckVnode(Fid, volptr, targetptr, locktype)))
+    if ((errorCode = CheckVnodeWithCall(Fid, volptr, cbv, targetptr, locktype)))
        return (errorCode);
     if (chkforDir) {
        if (chkforDir == MustNOTBeDIR
@@ -763,7 +819,7 @@ GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
                       (chkforDir == MustBeDIR ? 0 : locktype))) != 0)
        return (errorCode);
     if (chkforDir == MustBeDIR)
-       assert((*parent) == 0);
+       osi_Assert((*parent) == 0);
     if (!(*client)) {
        if ((errorCode = GetClient(tcon, client)) != 0)
            return (errorCode);
@@ -788,46 +844,66 @@ GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
 
 }                              /*GetVolumePackage */
 
+static_inline afs_int32
+GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
+                Vnode ** targetptr, int chkforDir, Vnode ** parent,
+                struct client **client, int locktype, afs_int32 * rights,
+                afs_int32 * anyrights)
+{
+    return GetVolumePackageWithCall(tcon, NULL, Fid, volptr, targetptr,
+                                    chkforDir, parent, client, locktype,
+                                    rights, anyrights);
+}
+
 
 /*
  * This is the opposite of GetVolumePackage(), and is always used at the end of
  * AFS calls to put back all used vnodes and the volume in the proper order!
  */
 static void
-PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
-                Vnode * parentptr, Volume * volptr, struct client **client)
+PutVolumePackageWithCall(Vnode * parentwhentargetnotdir, Vnode * targetptr,
+                         Vnode * parentptr, Volume * volptr,
+                         struct client **client, struct VCallByVol *cbv)
 {
-    int fileCode = 0;          /* Error code returned by the volume package */
+    Error fileCode = 0;                /* Error code returned by the volume package */
 
     if (parentwhentargetnotdir) {
        VPutVnode(&fileCode, parentwhentargetnotdir);
-       assert(!fileCode || (fileCode == VSALVAGE));
+       osi_Assert(!fileCode || (fileCode == VSALVAGE));
     }
     if (targetptr) {
        VPutVnode(&fileCode, targetptr);
-       assert(!fileCode || (fileCode == VSALVAGE));
+       osi_Assert(!fileCode || (fileCode == VSALVAGE));
     }
     if (parentptr) {
        VPutVnode(&fileCode, parentptr);
-       assert(!fileCode || (fileCode == VSALVAGE));
+       osi_Assert(!fileCode || (fileCode == VSALVAGE));
     }
     if (volptr) {
-       VPutVolume(volptr);
+       VPutVolumeWithCall(volptr, cbv);
     }
     if (*client) {
        PutClient(client);
     }
 }                              /*PutVolumePackage */
 
+static_inline void
+PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
+                Vnode * parentptr, Volume * volptr, struct client **client)
+{
+    PutVolumePackageWithCall(parentwhentargetnotdir, targetptr, parentptr,
+                             volptr, client, NULL);
+}
+
 static int
-VolumeOwner(register struct client *client, register Vnode * targetptr)
+VolumeOwner(struct client *client, Vnode * targetptr)
 {
     afs_int32 owner = V_owner(targetptr->volumePtr);   /* get volume owner */
 
     if (owner >= 0)
        return (client->ViceId == owner);
     else {
-       /* 
+       /*
         * We don't have to check for host's cps since only regular
         * viceid are volume owners.
         */
@@ -850,7 +926,7 @@ VolumeRootVnode(Vnode * targetptr)
  * StoreStatus) related calls
  */
 /* this code should probably just set a "priv" flag where all the audit events
- * are now, and only generate the audit event once at the end of the routine, 
+ * are now, and only generate the audit event once at the end of the routine,
  * thus only generating the event if all the checks succeed, but only because
  * of the privilege       XXX
  */
@@ -859,7 +935,7 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
                       afs_int32 rights, int CallingRoutine,
                       AFSStoreStatus * InStatus)
 {
-    int errorCode = 0;
+    Error errorCode = 0;
 #define OWNSp(client, target) ((client)->ViceId == (target)->disk.owner)
 #define CHOWN(i,t) (((i)->Mask & AFS_SETOWNER) &&((i)->Owner != (t)->disk.owner))
 #define CHGRP(i,t) (((i)->Mask & AFS_SETGROUP) &&((i)->Group != (t)->disk.group))
@@ -878,7 +954,8 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
            } else {            /* file */
                /* must have read access, or be owner and have insert access */
                if (!(rights & PRSFS_READ)
-                   && !(OWNSp(client, targetptr) && (rights & PRSFS_INSERT)))
+                   && !((OWNSp(client, targetptr) && (rights & PRSFS_INSERT)
+                         && (client->ViceId != AnonymousID))))
                    return (EACCES);
            }
            if (CallingRoutine == CHK_FETCHDATA
@@ -1044,8 +1121,8 @@ RXFetch_AccessList(Vnode * targetptr, Vnode * parentwhentargetnotdir,
 {
     char *eACL;                        /* External access list placeholder */
 
-    if (acl_Externalize
-       ((targetptr->disk.type ==
+    if (acl_Externalize_pr
+       (hpr_IdToName, (targetptr->disk.type ==
          vDirectory ? VVnodeACL(targetptr) :
          VVnodeACL(parentwhentargetnotdir)), &eACL) != 0) {
        return EIO;
@@ -1073,7 +1150,8 @@ RXStore_AccessList(Vnode * targetptr, struct AFSOpaque *AccessList)
 {
     struct acl_accessList *newACL;     /* PlaceHolder for new access list */
 
-    if (acl_Internalize(AccessList->AFSOpaque_val, &newACL) != 0)
+    if (acl_Internalize_pr(hpr_NameToId, AccessList->AFSOpaque_val, &newACL)
+       != 0)
        return (EINVAL);
     if ((newACL->size + 4) > VAclSize(targetptr))
        return (E2BIG);
@@ -1092,14 +1170,17 @@ RXStore_AccessList(Vnode * targetptr, struct AFSOpaque *AccessList)
  * disk.inodeNumber and cloned)
  */
 #define        COPYBUFFSIZE    8192
+#define MAXFSIZE (~(afs_fsize_t) 0)
 static int
-CopyOnWrite(Vnode * targetptr, Volume * volptr)
+CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
 {
-    Inode ino, nearInode;
-    int rdlen;
-    int wrlen;
-    register afs_fsize_t size;
-    register int length;
+    Inode ino;
+    Inode nearInode AFS_UNUSED;
+    ssize_t rdlen;
+    ssize_t wrlen;
+    afs_fsize_t size;
+    afs_foff_t done;
+    size_t length;
     char *buff;
     int rc;                    /* return code */
     IHandle_t *newH;           /* Use until finished copying, then cp to vnode. */
@@ -1110,6 +1191,13 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
        DFlush();               /* just in case? */
 
     VN_GET_LEN(size, targetptr);
+    if (size > off)
+       size -= off;
+    else
+       size = 0;
+    if (size > len)
+       size = len;
+
     buff = (char *)malloc(COPYBUFFSIZE);
     if (buff == NULL) {
        return EIO;
@@ -1122,7 +1210,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
        ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
                    volptr->hashid));
        return EIO;
-    }    
+    }
     targFdP = IH_OPEN(targetptr->handle);
     if (targFdP == NULL) {
        rc = errno;
@@ -1151,20 +1239,22 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
     }
     IH_INIT(newH, V_device(volptr), V_id(volptr), ino);
     newFdP = IH_OPEN(newH);
-    assert(newFdP != NULL);
+    osi_Assert(newFdP != NULL);
 
+    done = off;
     while (size > 0) {
        if (size > COPYBUFFSIZE) {      /* more than a buffer */
            length = COPYBUFFSIZE;
            size -= COPYBUFFSIZE;
        } else {
-           length = (int)size;
+           length = size;
            size = 0;
        }
-       rdlen = FDH_READ(targFdP, buff, length);
-       if (rdlen == length)
-           wrlen = FDH_WRITE(newFdP, buff, length);
-       else
+       rdlen = FDH_PREAD(targFdP, buff, length, done);
+       if (rdlen == length) {
+           wrlen = FDH_PWRITE(newFdP, buff, length, done);
+           done += rdlen;
+       } else
            wrlen = 0;
        /*  Callers of this function are not prepared to recover
         *  from error that put the filesystem in an inconsistent
@@ -1175,7 +1265,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
         *  error code indicates that the disk is full, we roll-back to
         *  the initial state.
         */
-       if ((rdlen != length) || (wrlen != length))
+       if ((rdlen != length) || (wrlen != length)) {
            if ((wrlen < 0) && (errno == ENOSPC)) {     /* disk full */
                ViceLog(0,
                        ("CopyOnWrite failed: Partition %s containing volume %u is full\n",
@@ -1194,10 +1284,14 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
                free(buff);
                return ENOSPC;
            } else {
+               /* length, rdlen, and wrlen may or may not be 64-bits wide;
+                * since we never do any I/O anywhere near 2^32 bytes at a
+                * time, just case to an unsigned int for printing */
+
                ViceLog(0,
                        ("CopyOnWrite failed: volume %u in partition %s  (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n",
-                        V_id(volptr), volptr->partition->name, length, rdlen,
-                        wrlen, errno));
+                        V_id(volptr), volptr->partition->name, (unsigned)length, (unsigned)rdlen,
+                        (unsigned)wrlen, errno));
 #if defined(AFS_DEMAND_ATTACH_FS)
                ViceLog(0, ("CopyOnWrite failed: requesting salvage\n"));
 #else
@@ -1212,6 +1306,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
                VTakeOffline(volptr);
                return EIO;
            }
+       }
 #ifndef AFS_PTHREAD_ENV
        IOMGR_Poll();
 #endif /* !AFS_PTHREAD_ENV */
@@ -1219,11 +1314,11 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
     FDH_REALLYCLOSE(targFdP);
     rc = IH_DEC(V_linkHandle(volptr), VN_GET_INO(targetptr),
                V_parentId(volptr));
-    assert(!rc);
+    osi_Assert(!rc);
     IH_RELEASE(targetptr->handle);
 
     rc = FDH_SYNC(newFdP);
-    assert(rc == 0);
+    osi_Assert(rc == 0);
     FDH_CLOSE(newFdP);
     targetptr->handle = newH;
     VN_SET_INO(targetptr, ino);
@@ -1234,7 +1329,6 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
     return 0;                  /* success */
 }                              /*CopyOnWrite */
 
-
 /*
  * Common code to handle with removing the Name (file when it's called from
  * SAFS_RemoveFile() or an empty dir when called from SAFS_rmdir()) from a
@@ -1246,15 +1340,22 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
             DirHandle * dir, AFSFid * fileFid, char *Name, int ChkForDir)
 {
     DirHandle childdir;                /* Handle for dir package I/O */
-    int errorCode = 0;
+    Error errorCode = 0;
     int code;
+    afs_ino_str_t stmp;
 
     /* watch for invalid names */
     if (!strcmp(Name, ".") || !strcmp(Name, ".."))
        return (EINVAL);
+
+    if (CheckLength(volptr, parentptr, -1)) {
+       VTakeOffline(volptr);
+       return VSALVAGE;
+    }
+
     if (parentptr->disk.cloned) {
        ViceLog(25, ("DeleteTarget : CopyOnWrite called\n"));
-       if ((errorCode = CopyOnWrite(parentptr, volptr))) {
+       if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE))) {
            ViceLog(20,
                    ("DeleteTarget %s: CopyOnWrite failed %d\n", Name,
                     errorCode));
@@ -1264,7 +1365,7 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
 
     /* check that the file is in the directory */
     SetDirHandle(dir, parentptr);
-    if (Lookup(dir, Name, fileFid))
+    if (afs_dir_Lookup(dir, Name, fileFid))
        return (ENOENT);
     fileFid->Volume = V_id(volptr);
 
@@ -1282,7 +1383,7 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
     } else if ((*targetptr)->disk.type == vDirectory)
        return (EISDIR);
 
-    /*assert((*targetptr)->disk.uniquifier == fileFid->Unique); */
+    /*osi_Assert((*targetptr)->disk.uniquifier == fileFid->Unique); */
     /**
       * If the uniquifiers dont match then instead of asserting
       * take the volume offline and return VSALVAGE
@@ -1298,7 +1399,7 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
 
     if (ChkForDir == MustBeDIR) {
        SetDirHandle(&childdir, *targetptr);
-       if (IsEmpty(&childdir) != 0)
+       if (afs_dir_IsEmpty(&childdir) != 0)
            return (EEXIST);
        DZap(&childdir);
        FidZap(&childdir);
@@ -1316,7 +1417,7 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
            if (errorCode == -1) {
                ViceLog(0,
                        ("DT: inode=%s, name=%s, errno=%d\n",
-                        PrintInode(NULL, VN_GET_INO(*targetptr)), Name,
+                        PrintInode(stmp, VN_GET_INO(*targetptr)), Name,
                         errno));
                if (errno != ENOENT)
                {
@@ -1340,7 +1441,7 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
 
     (*targetptr)->changed_newTime = 1; /* Status change of deleted file/dir */
 
-    code = Delete(dir, (char *)Name);
+    code = afs_dir_Delete(dir, Name);
     if (code) {
        ViceLog(0,
                ("Error %d deleting %s\n", code,
@@ -1376,7 +1477,7 @@ Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
 {
     afs_fsize_t newlength;     /* Holds new directory length */
     afs_fsize_t parentLength;
-    int errorCode;
+    Error errorCode;
 #if FS_STATS_DETAILED
     Date currDate;             /*Current date */
     int writeIdx;              /*Write index to bump */
@@ -1384,8 +1485,8 @@ Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
 #endif /* FS_STATS_DETAILED */
 
     parentptr->disk.dataVersion++;
-    newlength = (afs_fsize_t) Length(dir);
-    /* 
+    newlength = (afs_fsize_t) afs_dir_Length(dir);
+    /*
      * This is a called on both dir removals (i.e. remove, removedir, rename) but also in dir additions
      * (create, symlink, link, makedir) so we need to check if we have enough space
      * XXX But we still don't check the error since we're dealing with dirs here and really the increase
@@ -1614,8 +1715,8 @@ static afs_int32
 AdjustDiskUsage(Volume * volptr, afs_sfsize_t length,
                afs_sfsize_t checkLength)
 {
-    int rc;
-    int nc;
+    Error rc;
+    Error nc;
 
     VAdjustDiskUsage(&rc, volptr, length, checkLength);
     if (rc) {
@@ -1648,10 +1749,11 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
               Vnode ** targetptr, char *Name, struct AFSFid *OutFid,
               int FileType, afs_sfsize_t BlocksPreallocatedForVnode)
 {
-    int errorCode = 0;         /* Error code returned back */
-    int temp;
+    Error errorCode = 0;               /* Error code returned back */
+    Error temp;
     Inode inode = 0;
-    Inode nearInode;           /* hint for inode allocation in solaris */
+    Inode nearInode AFS_UNUSED;         /* hint for inode allocation in solaris */
+    afs_ino_str_t stmp;
 
     if ((errorCode =
         AdjustDiskUsage(volptr, BlocksPreallocatedForVnode,
@@ -1662,6 +1764,12 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
        return (errorCode);
     }
 
+    if (CheckLength(volptr, parentptr, -1)) {
+       VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
+       VTakeOffline(volptr);
+       return VSALVAGE;
+    }
+
     *targetptr = VAllocVnode(&errorCode, volptr, FileType);
     if (errorCode != 0) {
        VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
@@ -1698,7 +1806,7 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
 
     if (parentptr->disk.cloned) {
        ViceLog(25, ("Alloc_NewVnode : CopyOnWrite called\n"));
-       if ((errorCode = CopyOnWrite(parentptr, volptr))) {     /* disk full */
+       if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE))) {        /* disk full */
            ViceLog(25, ("Alloc_NewVnode : CopyOnWrite failed\n"));
            /* delete the vnode previously allocated */
            (*targetptr)->delete = 1;
@@ -1707,7 +1815,7 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
            if (IH_DEC(V_linkHandle(volptr), inode, V_parentId(volptr)))
                ViceLog(0,
                        ("Alloc_NewVnode: partition %s idec %s failed\n",
-                        volptr->partition->name, PrintInode(NULL, inode)));
+                        volptr->partition->name, PrintInode(stmp, inode)));
            IH_RELEASE((*targetptr)->handle);
 
            return errorCode;
@@ -1716,14 +1824,14 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
 
     /* add the name to the directory */
     SetDirHandle(dir, parentptr);
-    if ((errorCode = Create(dir, (char *)Name, OutFid))) {
+    if ((errorCode = afs_dir_Create(dir, Name, OutFid))) {
        (*targetptr)->delete = 1;
        VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
        IH_REALLYCLOSE((*targetptr)->handle);
        if (IH_DEC(V_linkHandle(volptr), inode, V_parentId(volptr)))
            ViceLog(0,
                    ("Alloc_NewVnode: partition %s idec %s failed\n",
-                    volptr->partition->name, PrintInode(NULL, inode)));
+                    volptr->partition->name, PrintInode(stmp, inode)));
        IH_RELEASE((*targetptr)->handle);
        return (errorCode);
     }
@@ -1753,7 +1861,7 @@ HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLo
                0;
        Time += AFS_LOCKWAIT;
        if (LockingType == LockRead) {
-           if ( !(rights & PRSFS_LOCK) && 
+           if ( !(rights & PRSFS_LOCK) &&
                  !(rights & PRSFS_WRITE) &&
                  !(OWNSp(client, targetptr) && (rights & PRSFS_INSERT)) )
                     return(EACCES);
@@ -1764,7 +1872,7 @@ HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLo
            } else
                return (EAGAIN);
        } else if (LockingType == LockWrite) {
-           if ( !(rights & PRSFS_WRITE) && 
+           if ( !(rights & PRSFS_WRITE) &&
                 !(OWNSp(client, targetptr) && (rights & PRSFS_INSERT)) )
                return(EACCES);
 
@@ -1872,41 +1980,37 @@ RXGetVolumeStatus(AFSFetchVolumeStatus * status, char **name, char **offMsg,
     temp = strlen(V_name(volptr)) + 1;
     *name = malloc(temp);
     if (!*name) {
-       ViceLog(0, ("Failed malloc in RXGetVolumeStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
     }
     strcpy(*name, V_name(volptr));
     temp = strlen(V_offlineMessage(volptr)) + 1;
     *offMsg = malloc(temp);
     if (!*offMsg) {
-       ViceLog(0, ("Failed malloc in RXGetVolumeStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
     }
     strcpy(*offMsg, V_offlineMessage(volptr));
 #if OPENAFS_VOL_STATS
     *motd = malloc(1);
     if (!*motd) {
-       ViceLog(0, ("Failed malloc in RXGetVolumeStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
     }
     strcpy(*motd, nullString);
 #else
     temp = strlen(V_motd(volptr)) + 1;
     *motd = malloc(temp);
     if (!*motd) {
-       ViceLog(0, ("Failed malloc in RXGetVolumeStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
     }
     strcpy(*motd, V_motd(volptr));
-#endif /* FS_STATS_DETAILED */
+#endif /* OPENAFS_VOL_STATS */
     return 0;
 }                              /*RXGetVolumeStatus */
 
 
 static afs_int32
-FileNameOK(register char *aname)
+FileNameOK(char *aname)
 {
-    register afs_int32 i, tc;
+    afs_int32 i, tc;
     i = strlen(aname);
     if (i >= 4) {
        /* watch for @sys on the right */
@@ -1938,21 +2042,29 @@ SRXAFS_DFSSymlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 }
 
 afs_int32
-SRXAFS_ResidencyCmd(struct rx_call * acall, struct AFSFid * Fid,
-                   struct ResidencyCmdInputs * Inputs,
-                   struct ResidencyCmdOutputs * Outputs)
+SRXAFS_FsCmd(struct rx_call * acall, struct AFSFid * Fid,
+                   struct FsCmdInputs * Inputs,
+                   struct FsCmdOutputs * Outputs)
 {
-    return EINVAL;
+    afs_int32 code = 0;
+
+    switch (Inputs->command) {
+    default:
+        code = EINVAL;
+    }
+    ViceLog(1,("FsCmd: cmd = %d, code=%d\n",
+                       Inputs->command, Outputs->code));
+    return code;
 }
 
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
 static struct afs_buffer {
     struct afs_buffer *next;
 } *freeBufferList = 0;
 static int afs_buffersAlloced = 0;
 
-static
-FreeSendBuffer(register struct afs_buffer *adata)
+static int
+FreeSendBuffer(struct afs_buffer *adata)
 {
     FS_LOCK;
     afs_buffersAlloced--;
@@ -1965,9 +2077,9 @@ FreeSendBuffer(register struct afs_buffer *adata)
 
 /* allocate space for sender */
 static char *
-AllocSendBuffer()
+AllocSendBuffer(void)
 {
-    register struct afs_buffer *tp;
+    struct afs_buffer *tp;
 
     FS_LOCK;
     afs_buffersAlloced++;
@@ -1976,8 +2088,7 @@ AllocSendBuffer()
        FS_UNLOCK;
        tmp = malloc(sendBufSize);
        if (!tmp) {
-           ViceLog(0, ("Failed malloc in AllocSendBuffer\n"));
-           assert(0);
+           ViceLogThenPanic(0, ("Failed malloc in AllocSendBuffer\n"));
        }
        return tmp;
     }
@@ -1987,7 +2098,7 @@ AllocSendBuffer()
     return (char *)tp;
 
 }                              /*AllocSendBuffer */
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
 
 /*
  * This routine returns the status info associated with the targetptr vnode
@@ -2049,8 +2160,8 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     Vnode *targetptr = 0;      /* pointer to vnode to fetch */
     Vnode *parentwhentargetnotdir = 0; /* parent vnode if vptr is a file */
     Vnode tparentwhentargetnotdir;     /* parent vnode for GetStatus */
-    int errorCode = 0;         /* return code to caller */
-    int fileCode = 0;          /* return code from vol package */
+    Error errorCode = 0;               /* return code to caller */
+    Error fileCode = 0;                /* return code from vol package */
     Volume *volptr = 0;                /* pointer to the volume */
     struct client *client = 0; /* pointer to the client data */
     struct rx_connection *tcon;        /* the connection we're part of */
@@ -2058,29 +2169,18 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     afs_int32 rights, anyrights;       /* rights for this and any user */
     struct client *t_client = NULL;    /* tmp ptr to client data */
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
+    struct VCallByVol tcbv, *cbv = NULL;
+    static int remainder = 0;  /* shared access protected by FS_LOCK */
+    struct fsstats fsstats;
+    afs_sfsize_t bytesToXfer;  /* # bytes to xfer */
+    afs_sfsize_t bytesXferred; /* # bytes actually xferred */
+
 #if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct fs_stats_xferData *xferP;   /* Ptr to this op's byte size struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval xferStartTime, xferStopTime;        /* Start/stop times for xfer portion */
-    struct timeval elapsedTime;        /* Transfer time */
-    afs_sfsize_t bytesToXfer;  /* # bytes to xfer */
-    afs_sfsize_t bytesXferred; /* # bytes actually xferred */
     int readIdx;               /* Index of read stats array to bump */
-    static afs_int32 tot_bytesXferred; /* shared access protected by FS_LOCK */
-
-    /*
-     * Set our stats pointers, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_FETCHDATA]);
-    xferP = &(afs_FullPerfStats.det.xferOpTimes[FS_STATS_XFERIDX_FETCHDATA]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHDATA);
+
     ViceLog(1,
            ("SRXAFS_FetchData, Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,
             Fid->Unique));
@@ -2097,12 +2197,17 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
            ("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
             Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
             ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+
+    queue_NodeInit(&tcbv);
+    tcbv.call = acall;
+    cbv = &tcbv;
+
     /*
      * Get volume/vnode for the fetched file; caller's access rights to
      * it are also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackageWithCall(tcon, cbv, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, READ_LOCK,
                          &rights, &anyrights)))
        goto Bad_FetchData;
@@ -2136,93 +2241,22 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     if (parentwhentargetnotdir != NULL) {
        tparentwhentargetnotdir = *parentwhentargetnotdir;
        VPutVnode(&fileCode, parentwhentargetnotdir);
-       assert(!fileCode || (fileCode == VSALVAGE));
+       osi_Assert(!fileCode || (fileCode == VSALVAGE));
        parentwhentargetnotdir = NULL;
     }
-#if FS_STATS_DETAILED
-    /*
-     * Remember when the data transfer started.
-     */
-    TM_GetTimeOfDay(&xferStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+
+    fsstats_StartXfer(&fsstats, FS_STATS_XFERIDX_FETCHDATA);
 
     /* actually do the data transfer */
-#if FS_STATS_DETAILED
     errorCode =
        FetchData_RXStyle(volptr, targetptr, acall, Pos, Len, type,
                          &bytesToXfer, &bytesXferred);
-#else
-    if ((errorCode =
-        FetchData_RXStyle(volptr, targetptr, acall, Pos, Len, type)))
-       goto Bad_FetchData;
-#endif /* FS_STATS_DETAILED */
 
-#if FS_STATS_DETAILED
-    /*
-     * At this point, the data transfer is done, for good or ill.  Remember
-     * when the transfer ended, bump the number of successes/failures, and
-     * integrate the transfer size and elapsed time into the stats.  If the
-     * operation failed, we jump to the appropriate point.
-     */
-    TM_GetTimeOfDay(&xferStopTime, 0);
-    FS_LOCK;
-    (xferP->numXfers)++;
-    if (!errorCode) {
-       (xferP->numSuccesses)++;
-
-       /*
-        * Bump the xfer sum by the number of bytes actually sent, NOT the
-        * target number.
-        */
-       tot_bytesXferred += bytesXferred;
-       (xferP->sumBytes) += (tot_bytesXferred >> 10);
-       tot_bytesXferred &= 0x3FF;
-       if (bytesXferred < xferP->minBytes)
-           xferP->minBytes = bytesXferred;
-       if (bytesXferred > xferP->maxBytes)
-           xferP->maxBytes = bytesXferred;
+    fsstats_FinishXfer(&fsstats, errorCode, bytesToXfer, bytesXferred,
+                      &remainder);
 
-       /*
-        * Tally the size of the object.  Note: we tally the actual size,
-        * NOT the number of bytes that made it out over the wire.
-        */
-       if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET0)
-           (xferP->count[0])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET1)
-           (xferP->count[1])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET2)
-           (xferP->count[2])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET3)
-           (xferP->count[3])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET4)
-           (xferP->count[4])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET5)
-           (xferP->count[5])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET6)
-           (xferP->count[6])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET7)
-           (xferP->count[7])++;
-       else
-           (xferP->count[8])++;
-
-       fs_stats_GetDiff(elapsedTime, xferStartTime, xferStopTime);
-       fs_stats_AddTo((xferP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((xferP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (xferP->minTime))) {
-           fs_stats_TimeAssign((xferP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (xferP->maxTime))) {
-           fs_stats_TimeAssign((xferP->maxTime), elapsedTime);
-       }
-    }
-    FS_UNLOCK;
-    /*
-     * Finally, go off to tell our caller the bad news in case the
-     * fetch failed.
-     */
     if (errorCode)
        goto Bad_FetchData;
-#endif /* FS_STATS_DETAILED */
 
     /* write back  the OutStatus from the target vnode  */
     GetStatus(targetptr, OutStatus, rights, anyrights,
@@ -2240,30 +2274,14 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_FetchData:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackageWithCall(parentwhentargetnotdir, targetptr,
+                                   (Vnode *) 0, volptr, &client, cbv);
     ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode));
     errorCode = CallPostamble(tcon, errorCode, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
-    osi_auditU(acall, FetchDataEvent, errorCode, 
+    osi_auditU(acall, FetchDataEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_END);
     return (errorCode);
@@ -2275,7 +2293,7 @@ SRXAFS_FetchData(struct rx_call * acall, struct AFSFid * Fid, afs_int32 Pos,
                 afs_int32 Len, struct AFSFetchStatus * OutStatus,
                 struct AFSCallBack * CallBack, struct AFSVolSync * Sync)
 {
-    return common_FetchData64(acall, Fid, Pos, Len, OutStatus, CallBack, 
+    return common_FetchData64(acall, Fid, Pos, Len, OutStatus, CallBack,
                               Sync, 0);
 }
 
@@ -2287,19 +2305,8 @@ SRXAFS_FetchData64(struct rx_call * acall, struct AFSFid * Fid, afs_int64 Pos,
     int code;
     afs_sfsize_t tPos, tLen;
 
-#ifdef AFS_64BIT_ENV
-#ifndef AFS_LARGEFILE_ENV
-    if (Pos + Len > 0x7fffffff)
-       return EFBIG;
-#endif /* !AFS_LARGEFILE_ENV */
     tPos = (afs_sfsize_t) Pos;
     tLen = (afs_sfsize_t) Len;
-#else /* AFS_64BIT_ENV */
-    if (Pos.high || Len.high)
-       return EFBIG;
-    tPos = Pos.low;
-    tLen = Len.low;
-#endif /* AFS_64BIT_ENV */
 
     code =
        common_FetchData64(acall, Fid, tPos, tLen, OutStatus, CallBack, Sync,
@@ -2314,7 +2321,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
 {
     Vnode *targetptr = 0;      /* pointer to vnode to fetch */
     Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
-    int errorCode = 0;         /* return error code to caller */
+    Error errorCode = 0;               /* return error code to caller */
     Volume *volptr = 0;                /* pointer to the volume */
     struct client *client = 0; /* pointer to the client data */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -2322,21 +2329,9 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_FETCHACL]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHACL);
 
     ViceLog(1,
            ("SAFS_FetchACL, Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,
@@ -2358,8 +2353,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     AccessList->AFSOpaque_len = 0;
     AccessList->AFSOpaque_val = malloc(AFSOPAQUEMAX);
     if (!AccessList->AFSOpaque_val) {
-       ViceLog(0, ("Failed malloc in SRXAFS_FetchACL\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchACL\n"));
     }
 
     /*
@@ -2397,27 +2391,11 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
             AccessList->AFSOpaque_val));
     errorCode = CallPostamble(tcon, errorCode, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
-    osi_auditU(acall, FetchACLEvent, errorCode, 
+    osi_auditU(acall, FetchACLEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, 
+               AUD_FID, Fid,
                AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
     return errorCode;
 }                              /*SRXAFS_FetchACL */
@@ -2435,7 +2413,7 @@ SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
 {
     Vnode *targetptr = 0;      /* pointer to vnode to fetch */
     Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
-    int errorCode = 0;         /* return code to caller */
+    Error errorCode = 0;               /* return code to caller */
     Volume *volptr = 0;                /* pointer to the volume */
     struct client *client = 0; /* pointer to the client data */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -2506,33 +2484,21 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                  struct AFSBulkStats * OutStats, struct AFSCBs * CallBacks,
                  struct AFSVolSync * Sync)
 {
-    register int i;
+    int i;
     afs_int32 nfiles;
     Vnode *targetptr = 0;      /* pointer to vnode to fetch */
     Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
-    int errorCode = 0;         /* return code to caller */
+    Error errorCode = 0;               /* return code to caller */
     Volume *volptr = 0;                /* pointer to the volume */
     struct client *client = 0; /* pointer to the client data */
     afs_int32 rights, anyrights;       /* rights for this and any user */
-    register struct AFSFid *tfid;      /* file id we're dealing with now */
+    struct AFSFid *tfid;       /* file id we're dealing with now */
     struct rx_connection *tcon = rx_ConnectionOf(acall);
     struct host *thost;
     struct client *t_client = NULL;     /* tmp pointer to the client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_BULKSTATUS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_BULKSTATUS);
 
     ViceLog(1, ("SAFS_BulkStatus\n"));
     FS_LOCK;
@@ -2548,15 +2514,13 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
        malloc(nfiles * sizeof(struct AFSFetchStatus));
     if (!OutStats->AFSBulkStats_val) {
-       ViceLog(0, ("Failed malloc in SRXAFS_BulkStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in SRXAFS_BulkStatus\n"));
     }
     OutStats->AFSBulkStats_len = nfiles;
     CallBacks->AFSCBs_val = (struct AFSCallBack *)
        malloc(nfiles * sizeof(struct AFSCallBack));
     if (!CallBacks->AFSCBs_val) {
-       ViceLog(0, ("Failed malloc in SRXAFS_BulkStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in SRXAFS_BulkStatus\n"));
     }
     CallBacks->AFSCBs_len = nfiles;
 
@@ -2575,7 +2539,7 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                              &rights, &anyrights)))
            goto Bad_BulkStatus;
        /* set volume synchronization information, but only once per call */
-       if (i == nfiles)
+       if (i == 0)
            SetVolumeSync(Sync, volptr);
 
        /* Are we allowed to fetch Fid's status? */
@@ -2622,27 +2586,11 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
   Audit_and_Return:
     ViceLog(2, ("SAFS_BulkStatus       returns %d\n", errorCode));
-    osi_auditU(acall, BulkFetchStatusEvent, errorCode, 
+    osi_auditU(acall, BulkFetchStatusEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FIDS, Fids, AUD_END);
     return errorCode;
@@ -2655,34 +2603,23 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                        struct AFSBulkStats * OutStats,
                        struct AFSCBs * CallBacks, struct AFSVolSync * Sync)
 {
-    register int i;
+    int i;
     afs_int32 nfiles;
     Vnode *targetptr = 0;      /* pointer to vnode to fetch */
     Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
-    int errorCode = 0;         /* return code to caller */
+    Error errorCode = 0;               /* return code to caller */
     Volume *volptr = 0;                /* pointer to the volume */
     struct client *client = 0; /* pointer to the client data */
     afs_int32 rights, anyrights;       /* rights for this and any user */
-    register struct AFSFid *tfid;      /* file id we're dealing with now */
+    struct AFSFid *tfid;       /* file id we're dealing with now */
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
     AFSFetchStatus *tstatus;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    int VolSync_set = 0;
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_BULKSTATUS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_BULKSTATUS);
 
     ViceLog(1, ("SAFS_InlineBulkStatus\n"));
     FS_LOCK;
@@ -2698,18 +2635,21 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
        malloc(nfiles * sizeof(struct AFSFetchStatus));
     if (!OutStats->AFSBulkStats_val) {
-       ViceLog(0, ("Failed malloc in SRXAFS_FetchStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchStatus\n"));
     }
     OutStats->AFSBulkStats_len = nfiles;
     CallBacks->AFSCBs_val = (struct AFSCallBack *)
        malloc(nfiles * sizeof(struct AFSCallBack));
     if (!CallBacks->AFSCBs_val) {
-       ViceLog(0, ("Failed malloc in SRXAFS_FetchStatus\n"));
-       assert(0);
+       ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchStatus\n"));
     }
     CallBacks->AFSCBs_len = nfiles;
 
+    /* Zero out return values to avoid leaking information on partial succes */
+    memset(OutStats->AFSBulkStats_val, 0, nfiles * sizeof(struct AFSFetchStatus));
+    memset(CallBacks->AFSCBs_val, 0, nfiles * sizeof(struct AFSCallBack));
+    memset(Sync, 0, sizeof(*Sync));
+
     if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost))) {
        goto Bad_InlineBulkStatus;
     }
@@ -2726,7 +2666,7 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                              &rights, &anyrights))) {
            tstatus = &OutStats->AFSBulkStats_val[i];
            tstatus->errorCode = errorCode;
-           PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
+           PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
                             volptr, &client);
            parentwhentargetnotdir = (Vnode *) 0;
            targetptr = (Vnode *) 0;
@@ -2736,8 +2676,10 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
        }
 
        /* set volume synchronization information, but only once per call */
-       if (i == nfiles)
+       if (!VolSync_set) {
            SetVolumeSync(Sync, volptr);
+           VolSync_set = 1;
+       }
 
        /* Are we allowed to fetch Fid's status? */
        if (targetptr->disk.type != vDirectory) {
@@ -2790,27 +2732,11 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
   Audit_and_Return:
     ViceLog(2, ("SAFS_InlineBulkStatus returns %d\n", errorCode));
-    osi_auditU(acall, InlineBulkFetchStatusEvent, errorCode, 
+    osi_auditU(acall, InlineBulkFetchStatusEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FIDS, Fids, AUD_END);
     return 0;
@@ -2827,21 +2753,9 @@ SRXAFS_FetchStatus(struct rx_call * acall, struct AFSFid * Fid,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_FETCHSTATUS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHSTATUS);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_FetchStatus;
@@ -2853,25 +2767,9 @@ SRXAFS_FetchStatus(struct rx_call * acall, struct AFSFid * Fid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, FetchStatusEvent, code, 
+    osi_auditU(acall, FetchStatusEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_END);
     return code;
@@ -2888,8 +2786,8 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     Vnode *targetptr = 0;      /* pointer to input fid */
     Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
     Vnode tparentwhentargetnotdir;     /* parent vnode for GetStatus */
-    int errorCode = 0;         /* return code for caller */
-    int fileCode = 0;          /* return code from vol package */
+    Error errorCode = 0;               /* return code for caller */
+    Error fileCode = 0;                /* return code from vol package */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -2897,30 +2795,16 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
     struct rx_connection *tcon;
     struct host *thost;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct fs_stats_xferData *xferP;   /* Ptr to this op's byte size struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval xferStartTime, xferStopTime;        /* Start/stop times for xfer portion */
-    struct timeval elapsedTime;        /* Transfer time */
-    afs_sfsize_t bytesToXfer;  /* # bytes to xfer */
-    afs_sfsize_t bytesXferred; /* # bytes actually xfer */
-    static afs_int32 tot_bytesXferred; /* shared access protected by FS_LOCK */
+    struct fsstats fsstats;
+    afs_sfsize_t bytesToXfer;
+    afs_sfsize_t bytesXferred;
+    static int remainder = 0;
 
-    /*
-     * Set our stats pointers, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_STOREDATA]);
-    xferP = &(afs_FullPerfStats.det.xferOpTimes[FS_STATS_XFERIDX_STOREDATA]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
     ViceLog(1,
            ("StoreData: Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,
             Fid->Unique));
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STOREDATA);
 
     FS_LOCK;
     AFSCallStats.StoreData++, AFSCallStats.TotalCalls++;
@@ -2970,99 +2854,26 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     if (parentwhentargetnotdir != NULL) {
        tparentwhentargetnotdir = *parentwhentargetnotdir;
        VPutVnode(&fileCode, parentwhentargetnotdir);
-       assert(!fileCode || (fileCode == VSALVAGE));
+       osi_Assert(!fileCode || (fileCode == VSALVAGE));
        parentwhentargetnotdir = NULL;
     }
-#if FS_STATS_DETAILED
-    /*
-     * Remember when the data transfer started.
-     */
-    TM_GetTimeOfDay(&xferStartTime, 0);
-#endif /* FS_STATS_DETAILED */
 
-    /* Do the actual storing of the data */
-#if FS_STATS_DETAILED
+    fsstats_StartXfer(&fsstats, FS_STATS_XFERIDX_STOREDATA);
+
     errorCode =
        StoreData_RXStyle(volptr, targetptr, Fid, client, acall, Pos, Length,
                          FileLength, (InStatus->Mask & AFS_FSYNC),
                          &bytesToXfer, &bytesXferred);
-#else
-    errorCode =
-       StoreData_RXStyle(volptr, targetptr, Fid, client, acall, Pos, Length,
-                         FileLength, (InStatus->Mask & AFS_FSYNC));
+
+    fsstats_FinishXfer(&fsstats, errorCode, bytesToXfer, bytesXferred,
+                      &remainder);
+
     if (errorCode && (!targetptr->changed_newTime))
        goto Bad_StoreData;
-#endif /* FS_STATS_DETAILED */
-#if FS_STATS_DETAILED
-    /*
-     * At this point, the data transfer is done, for good or ill.  Remember
-     * when the transfer ended, bump the number of successes/failures, and
-     * integrate the transfer size and elapsed time into the stats.  If the
-     * operation failed, we jump to the appropriate point.
-     */
-    TM_GetTimeOfDay(&xferStopTime, 0);
-    FS_LOCK;
-    (xferP->numXfers)++;
-    if (!errorCode) {
-       (xferP->numSuccesses)++;
-
-       /*
-        * Bump the xfer sum by the number of bytes actually sent, NOT the
-        * target number.
-        */
-       tot_bytesXferred += bytesXferred;
-       (xferP->sumBytes) += (tot_bytesXferred >> 10);
-       tot_bytesXferred &= 0x3FF;
-       if (bytesXferred < xferP->minBytes)
-           xferP->minBytes = bytesXferred;
-       if (bytesXferred > xferP->maxBytes)
-           xferP->maxBytes = bytesXferred;
 
-       /*
-        * Tally the size of the object.  Note: we tally the actual size,
-        * NOT the number of bytes that made it out over the wire.
-        */
-       if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET0)
-           (xferP->count[0])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET1)
-           (xferP->count[1])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET2)
-           (xferP->count[2])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET3)
-           (xferP->count[3])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET4)
-           (xferP->count[4])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET5)
-           (xferP->count[5])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET6)
-           (xferP->count[6])++;
-       else if (bytesToXfer <= FS_STATS_MAXBYTES_BUCKET7)
-           (xferP->count[7])++;
-       else
-           (xferP->count[8])++;
-
-       fs_stats_GetDiff(elapsedTime, xferStartTime, xferStopTime);
-       fs_stats_AddTo((xferP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((xferP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (xferP->minTime))) {
-           fs_stats_TimeAssign((xferP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (xferP->maxTime))) {
-           fs_stats_TimeAssign((xferP->maxTime), elapsedTime);
-       }
-    }
-    FS_UNLOCK;
-    /*
-     * Finally, go off to tell our caller the bad news in case the
-     * store failed.
-     */
-    if (errorCode && (!targetptr->changed_newTime))
-       goto Bad_StoreData;
-#endif /* FS_STATS_DETAILED */
-
-    /* Update the status of the target's vnode */
-    Update_TargetVnodeStatus(targetptr, TVS_SDATA, client, InStatus,
-                            targetptr, volptr, 0);
+    /* Update the status of the target's vnode */
+    Update_TargetVnodeStatus(targetptr, TVS_SDATA, client, InStatus,
+                            targetptr, volptr, 0);
 
     /* Get the updated File's status back to the caller */
     GetStatus(targetptr, OutStatus, rights, anyrights,
@@ -3076,24 +2887,9 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
 
     errorCode = CallPostamble(tcon, errorCode, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
-    osi_auditU(acall, StoreDataEvent, errorCode, 
+    fsstats_FinishOp(&fsstats, errorCode);
+
+    osi_auditU(acall, StoreDataEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_END);
     return (errorCode);
@@ -3105,7 +2901,7 @@ SRXAFS_StoreData(struct rx_call * acall, struct AFSFid * Fid,
                 afs_uint32 Length, afs_uint32 FileLength,
                 struct AFSFetchStatus * OutStatus, struct AFSVolSync * Sync)
 {
-    if (FileLength > 0x7fffffff || Pos > 0x7fffffff || 
+    if (FileLength > 0x7fffffff || Pos > 0x7fffffff ||
        (0x7fffffff - Pos) < Length)
         return EFBIG;
 
@@ -3125,21 +2921,9 @@ SRXAFS_StoreData64(struct rx_call * acall, struct AFSFid * Fid,
     afs_fsize_t tLength;
     afs_fsize_t tFileLength;
 
-#ifdef AFS_64BIT_ENV
-#ifndef AFS_LARGEFILE_ENV
-    if (FileLength > 0x7fffffff)
-       return EFBIG;
-#endif /* !AFS_LARGEFILE_ENV */
     tPos = (afs_fsize_t) Pos;
     tLength = (afs_fsize_t) Length;
     tFileLength = (afs_fsize_t) FileLength;
-#else /* AFS_64BIT_ENV */
-    if (FileLength.high)
-       return EFBIG;
-    tPos = Pos.low;
-    tLength = Length.low;
-    tFileLength = FileLength.low;
-#endif /* AFS_64BIT_ENV */
 
     code =
        common_StoreData64(acall, Fid, InStatus, tPos, tLength, tFileLength,
@@ -3154,7 +2938,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
 {
     Vnode *targetptr = 0;      /* pointer to input fid */
     Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
-    int errorCode = 0;         /* return code for caller */
+    Error errorCode = 0;               /* return code for caller */
     struct AFSStoreStatus InStatus;    /* Input status for fid */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
@@ -3163,21 +2947,10 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
+
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STOREACL);
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_STOREACL]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
     if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_StoreACL;
 
@@ -3223,7 +2996,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* break call backs on the directory  */
     BreakCallBack(client->host, Fid, 0);
@@ -3233,30 +3006,14 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
 
   Bad_StoreACL:
     /* Update and store volume/vnode and parent vnodes back */
-    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
+    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
                     volptr, &client);
     ViceLog(2, ("SAFS_StoreACL returns %d\n", errorCode));
     errorCode = CallPostamble(tcon, errorCode, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
-    osi_auditU(acall, StoreACLEvent, errorCode, 
+    osi_auditU(acall, StoreACLEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
     return errorCode;
@@ -3275,7 +3032,7 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
 {
     Vnode *targetptr = 0;      /* pointer to input fid */
     Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
-    int errorCode = 0;         /* return code for caller */
+    Error errorCode = 0;               /* return code for caller */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -3329,7 +3086,7 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* Break call backs on Fid */
     BreakCallBack(client->host, Fid, 0);
@@ -3340,7 +3097,7 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_StoreStatus:
     /* Update and store volume/vnode and parent vnodes back */
-    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
+    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
                     volptr, &client);
     ViceLog(2, ("SAFS_StoreStatus returns %d\n", errorCode));
     return errorCode;
@@ -3358,21 +3115,9 @@ SRXAFS_StoreStatus(struct rx_call * acall, struct AFSFid * Fid,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_STORESTATUS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STORESTATUS);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_StoreStatus;
@@ -3384,25 +3129,9 @@ SRXAFS_StoreStatus(struct rx_call * acall, struct AFSFid * Fid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, StoreStatusEvent, code, 
+    osi_auditU(acall, StoreStatusEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_END);
     return code;
@@ -3423,7 +3152,7 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Vnode *targetptr = 0;      /* file to be deleted */
     Volume *volptr = 0;                /* pointer to the volume header */
     AFSFid fileFid;            /* area for Fid from the directory */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     DirHandle dir;             /* Handle for dir package I/O */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -3486,14 +3215,14 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        DeleteFileCallBacks(&fileFid);
        /* convert the parent lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, parentptr);
-       assert(!errorCode || errorCode == VSALVAGE);
+       osi_Assert(!errorCode || errorCode == VSALVAGE);
     } else {
        /* convert the parent lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, parentptr);
-       assert(!errorCode || errorCode == VSALVAGE);
+       osi_Assert(!errorCode || errorCode == VSALVAGE);
        /* convert the target lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, targetptr);
-       assert(!errorCode || errorCode == VSALVAGE);
+       osi_Assert(!errorCode || errorCode == VSALVAGE);
        /* tell all the file has changed */
        BreakCallBack(client->host, &fileFid, 1);
     }
@@ -3503,7 +3232,7 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
   Bad_RemoveFile:
     /* Update and store volume/vnode and parent vnodes back */
-    PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr, 
+    PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
                     volptr, &client);
     FidZap(&dir);
     ViceLog(2, ("SAFS_RemoveFile returns %d\n", errorCode));
@@ -3521,21 +3250,9 @@ SRXAFS_RemoveFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_REMOVEFILE]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEFILE);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_RemoveFile;
@@ -3547,25 +3264,9 @@ SRXAFS_RemoveFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, RemoveFileEvent, code, 
+    osi_auditU(acall, RemoveFileEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, DirFid, AUD_STR, Name, AUD_END);
     return code;
@@ -3588,7 +3289,7 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Vnode *targetptr = 0;      /* vnode of the new file */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
     Volume *volptr = 0;                /* pointer to the volume header */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     DirHandle dir;             /* Handle for dir package I/O */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -3658,7 +3359,7 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, parentptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* break call back on parent dir */
     BreakCallBack(client->host, DirFid, 0);
@@ -3688,21 +3389,9 @@ SRXAFS_CreateFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_CREATEFILE]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_CREATEFILE);
 
     memset(OutFid, 0, sizeof(struct AFSFid));
 
@@ -3718,25 +3407,9 @@ SRXAFS_CreateFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, CreateFileEvent, code, 
+    osi_auditU(acall, CreateFileEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, DirFid, AUD_STR, Name, AUD_FID, OutFid, AUD_END);
     return code;
@@ -3760,8 +3433,8 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     Vnode *newfileptr = 0;     /* vnode of the file to delete */
     Vnode *testvptr = 0;       /* used in directory tree walk */
     Vnode *parent = 0;         /* parent for use in SetAccessList */
-    int errorCode = 0;         /* error code */
-    int fileCode = 0;          /* used when writing Vnodes */
+    Error errorCode = 0;               /* error code */
+    Error fileCode = 0;                /* used when writing Vnodes */
     VnodeId testnode;          /* used in directory tree walk */
     AFSFid fileFid;            /* Fid of file to move */
     AFSFid newFileFid;         /* Fid of new file */
@@ -3776,9 +3449,12 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     afs_int32 newanyrights;    /* rights for any user */
     int doDelete;              /* deleted the rename target (ref count now 0) */
     int code;
+    int updatefile = 0;                /* are we changing the renamed file? (we do this
+                                * if we need to update .. on a renamed dir) */
     struct client *t_client;   /* tmp ptr to client data */
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
     struct rx_connection *tcon = rx_ConnectionOf(acall);
+    afs_ino_str_t stmp;
 
     FidZero(&olddir);
     FidZero(&newdir);
@@ -3859,27 +3535,34 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
        goto Bad_Rename;
     }
 
+    if (CheckLength(volptr, oldvptr, -1) ||
+        CheckLength(volptr, newvptr, -1)) {
+       VTakeOffline(volptr);
+       errorCode = VSALVAGE;
+       goto Bad_Rename;
+    }
+
     /* The CopyOnWrite might return ENOSPC ( disk full). Even if the second
      *  call to CopyOnWrite returns error, it is not necessary to revert back
-     *  the effects of the first call because the contents of the volume is 
+     *  the effects of the first call because the contents of the volume is
      *  not modified, it is only replicated.
      */
     if (oldvptr->disk.cloned) {
        ViceLog(25, ("Rename : calling CopyOnWrite on  old dir\n"));
-       if ((errorCode = CopyOnWrite(oldvptr, volptr)))
+       if ((errorCode = CopyOnWrite(oldvptr, volptr, 0, MAXFSIZE)))
            goto Bad_Rename;
     }
     SetDirHandle(&olddir, oldvptr);
     if (newvptr->disk.cloned) {
        ViceLog(25, ("Rename : calling CopyOnWrite on  new dir\n"));
-       if ((errorCode = CopyOnWrite(newvptr, volptr)))
+       if ((errorCode = CopyOnWrite(newvptr, volptr, 0, MAXFSIZE)))
            goto Bad_Rename;
     }
 
     SetDirHandle(&newdir, newvptr);
 
     /* Lookup the file to delete its vnode */
-    if (Lookup(&olddir, OldName, &fileFid)) {
+    if (afs_dir_Lookup(&olddir, OldName, &fileFid)) {
        errorCode = ENOENT;
        goto Bad_Rename;
     }
@@ -3919,7 +3602,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     }
 
     /* Lookup the new file  */
-    if (!(Lookup(&newdir, NewName, &newFileFid))) {
+    if (!(afs_dir_Lookup(&newdir, NewName, &newFileFid))) {
        if (readonlyServer) {
            errorCode = VREADONLY;
            goto Bad_Rename;
@@ -3964,7 +3647,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
                errorCode = EISDIR;
                goto Bad_Rename;
            }
-           if ((IsEmpty(&newfiledir))) {
+           if ((afs_dir_IsEmpty(&newfiledir))) {
                errorCode = EEXIST;
                goto Bad_Rename;
            }
@@ -4003,7 +3686,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            }
            if (testnode == 1) top = 1;
            testvptr = VGetVnode(&errorCode, volptr, testnode, READ_LOCK);
-           assert(errorCode == 0);
+           osi_Assert(errorCode == 0);
            testnode = testvptr->disk.parent;
            VPutVnode(&errorCode, testvptr);
            if ((top == 1) && (testnode != 0)) {
@@ -4014,24 +3697,45 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
                errorCode = EIO;
                goto Bad_Rename;
            }
-           assert(errorCode == 0);
+           osi_Assert(errorCode == 0);
        }
     }
+
+    if (fileptr->disk.type == vDirectory) {
+       SetDirHandle(&filedir, fileptr);
+       if (oldvptr != newvptr) {
+           /* we always need to update .. if we've moving fileptr to a
+            * different directory */
+           updatefile = 1;
+       } else {
+           struct AFSFid unused;
+
+           code = afs_dir_Lookup(&filedir, "..", &unused);
+           if (code == ENOENT) {
+               /* only update .. if it doesn't already exist */
+               updatefile = 1;
+           }
+       }
+    }
+
     /* Do the CopyonWrite first before modifying anything else. Copying is
-     *  required because we may have to change entries for .. 
+     * required when we have to change entries for ..
      */
-    if ((fileptr->disk.type == vDirectory) && (fileptr->disk.cloned)) {
+    if (updatefile && (fileptr->disk.cloned)) {
        ViceLog(25, ("Rename : calling CopyOnWrite on  target dir\n"));
-       if ((errorCode = CopyOnWrite(fileptr, volptr)))
+       if ((errorCode = CopyOnWrite(fileptr, volptr, 0, MAXFSIZE)))
            goto Bad_Rename;
+       /* since copyonwrite would mean fileptr has a new handle, do it here */
+       FidZap(&filedir);
+       SetDirHandle(&filedir, fileptr);
     }
 
     /* If the new name exists already, delete it and the file it points to */
     doDelete = 0;
     if (newfileptr) {
        /* Delete NewName from its directory */
-       code = Delete(&newdir, NewName);
-       assert(code == 0);
+       code = afs_dir_Delete(&newdir, NewName);
+       osi_Assert(code == 0);
 
        /* Drop the link count */
        newfileptr->disk.linkCount--;
@@ -4049,7 +3753,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
                if (errorCode == -1) {
                    ViceLog(0,
                            ("Del: inode=%s, name=%s, errno=%d\n",
-                            PrintInode(NULL, VN_GET_INO(newfileptr)),
+                            PrintInode(stmp, VN_GET_INO(newfileptr)),
                             NewName, errno));
                    if ((errno != ENOENT) && (errno != EIO)
                        && (errno != ENXIO))
@@ -4074,11 +3778,11 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
      * highly unlikely that it would work since it would involve issuing
      * another create.
      */
-    if ((errorCode = Create(&newdir, (char *)NewName, &fileFid)))
+    if ((errorCode = afs_dir_Create(&newdir, NewName, &fileFid)))
        goto Bad_Rename;
 
     /* Delete the old name */
-    assert(Delete(&olddir, (char *)OldName) == 0);
+    osi_Assert(afs_dir_Delete(&olddir, OldName) == 0);
 
     /* if the directory length changes, reflect it in the statistics */
 #if FS_STATS_DETAILED
@@ -4096,17 +3800,23 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     if (oldvptr == newvptr)
        oldvptr->disk.dataVersion--;    /* Since it was bumped by 2! */
 
-    fileptr->disk.parent = newvptr->vnodeNumber;
-    fileptr->changed_newTime = 1;      /* status change of moved file */
+    if (fileptr->disk.parent != newvptr->vnodeNumber) {
+       fileptr->disk.parent = newvptr->vnodeNumber;
+       fileptr->changed_newTime = 1;
+    }
+
+    /* if we are dealing with a rename of a directory, and we need to
+     * update the .. entry of that directory */
+    if (updatefile) {
+       osi_Assert(!fileptr->disk.cloned);
+
+       fileptr->changed_newTime = 1;   /* status change of moved file */
 
-    /* if we are dealing with a rename of a directory */
-    if (fileptr->disk.type == vDirectory) {
-       assert(!fileptr->disk.cloned);
-       SetDirHandle(&filedir, fileptr);
        /* fix .. to point to the correct place */
-       Delete(&filedir, ".."); /* No assert--some directories may be bad */
-       assert(Create(&filedir, "..", NewDirFid) == 0);
+       afs_dir_Delete(&filedir, ".."); /* No assert--some directories may be bad */
+       osi_Assert(afs_dir_Create(&filedir, "..", NewDirFid) == 0);
        fileptr->disk.dataVersion++;
+
        /* if the parent directories are different the link counts have to be   */
        /* changed due to .. in the renamed directory */
        if (oldvptr != newvptr) {
@@ -4126,23 +3836,31 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
 
     /* convert the write locks to a read locks before breaking callbacks */
     VVnodeWriteToRead(&errorCode, newvptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
     if (oldvptr != newvptr) {
        VVnodeWriteToRead(&errorCode, oldvptr);
-       assert(!errorCode || errorCode == VSALVAGE);
+       osi_Assert(!errorCode || errorCode == VSALVAGE);
     }
     if (newfileptr && !doDelete) {
        /* convert the write lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, newfileptr);
-       assert(!errorCode || errorCode == VSALVAGE);
+       osi_Assert(!errorCode || errorCode == VSALVAGE);
     }
 
     /* break call back on NewDirFid, OldDirFid, NewDirFid and newFileFid  */
     BreakCallBack(client->host, NewDirFid, 0);
     if (oldvptr != newvptr) {
        BreakCallBack(client->host, OldDirFid, 0);
-       if (fileptr->disk.type == vDirectory)   /* if a dir moved, .. changed */
-           BreakCallBack(client->host, &fileFid, 0);
+    }
+    if (updatefile) {
+       /* if a dir moved, .. changed */
+       /* we do not give an AFSFetchStatus structure back to the
+        * originating client, and the file's status has changed, so be
+        * sure to send a callback break. In theory the client knows
+        * enough to know that the callback could be broken implicitly,
+        * but that may not be clear, and some client implementations
+        * may not know to. */
+       BreakCallBack(client->host, &fileFid, 1);
     }
     if (newfileptr) {
        /* Note:  it is not necessary to break the callback */
@@ -4156,9 +3874,9 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
   Bad_Rename:
     if (newfileptr) {
        VPutVnode(&fileCode, newfileptr);
-       assert(fileCode == 0);
+       osi_Assert(fileCode == 0);
     }
-    (void)PutVolumePackage(fileptr, (newvptr && newvptr != oldvptr ? 
+    (void)PutVolumePackage(fileptr, (newvptr && newvptr != oldvptr ?
                                     newvptr : 0), oldvptr, volptr, &client);
     FidZap(&olddir);
     FidZap(&newdir);
@@ -4181,21 +3899,9 @@ SRXAFS_Rename(struct rx_call * acall, struct AFSFid * OldDirFid,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_RENAME]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RENAME);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_Rename;
@@ -4209,27 +3915,11 @@ SRXAFS_Rename(struct rx_call * acall, struct AFSFid * OldDirFid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, RenameFileEvent, code, 
+    osi_auditU(acall, RenameFileEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, OldDirFid, AUD_STR, OldName, 
+               AUD_FID, OldDirFid, AUD_STR, OldName,
                AUD_FID, NewDirFid, AUD_STR, NewName, AUD_END);
     return code;
 
@@ -4249,8 +3939,9 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Vnode *parentptr = 0;      /* vnode of input Directory */
     Vnode *targetptr = 0;      /* vnode of the new link */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
-    int errorCode = 0;         /* error code */
-    int len, code = 0;
+    Error errorCode = 0;               /* error code */
+    afs_sfsize_t len;
+    int code = 0;
     DirHandle dir;             /* Handle for dir package I/O */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
@@ -4347,11 +4038,11 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
                    volptr->hashid));
        return EIO;
-    }    
+    }
     len = strlen((char *) LinkContents);
-    code = (len == FDH_WRITE(fdP, (char *) LinkContents, len)) ? 0 : VDISKFULL;
-    if (code) 
-       ViceLog(0, ("SAFSS_Symlink FDH_WRITE failed for len=%d, Fid=%u.%d.%d\n", len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
+    code = (len == FDH_PWRITE(fdP, (char *) LinkContents, len, 0)) ? 0 : VDISKFULL;
+    if (code)
+       ViceLog(0, ("SAFSS_Symlink FDH_PWRITE failed for len=%d, Fid=%u.%d.%d\n", (int)len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
     FDH_CLOSE(fdP);
     /*
      * Set up and return modified status for the parent dir and new symlink
@@ -4362,7 +4053,7 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, parentptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* break call back on the parent dir */
     BreakCallBack(client->host, DirFid, 0);
@@ -4379,38 +4070,23 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
 
 afs_int32
-SRXAFS_Symlink(acall, DirFid, Name, LinkContents, InStatus, OutFid,
-              OutFidStatus, OutDirStatus, Sync)
-     struct AFSVolSync *Sync;
-     struct rx_call *acall;    /* Rx call */
-     struct AFSFid *DirFid;    /* Parent dir's fid */
-     char *Name;               /* File name to create */
-     char *LinkContents;       /* Contents of the new created file */
-     struct AFSStoreStatus *InStatus;  /* Input status for the new symbolic link */
-     struct AFSFid *OutFid;    /* Fid for newly created symbolic link */
-     struct AFSFetchStatus *OutFidStatus;      /* Output status for new symbolic link */
-     struct AFSFetchStatus *OutDirStatus;      /* Output status for parent dir */
-
+SRXAFS_Symlink(struct rx_call *acall,  /* Rx call */
+              struct AFSFid *DirFid,   /* Parent dir's fid */
+              char *Name,              /* File name to create */
+              char *LinkContents,      /* Contents of the new created file */
+              struct AFSStoreStatus *InStatus, /* Input status for the new symbolic link */
+              struct AFSFid *OutFid,   /* Fid for newly created symbolic link */
+              struct AFSFetchStatus *OutFidStatus,     /* Output status for new symbolic link */
+              struct AFSFetchStatus *OutDirStatus,     /* Output status for parent dir */
+              struct AFSVolSync *Sync)
 {
     afs_int32 code;
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_SYMLINK]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SYMLINK);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_Symlink;
@@ -4424,26 +4100,10 @@ SRXAFS_Symlink(acall, DirFid, Name, LinkContents, InStatus, OutFid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, SymlinkEvent, code, 
-               AUD_ID, t_client ? t_client->ViceId : 0, 
+    osi_auditU(acall, SymlinkEvent, code,
+               AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, DirFid, AUD_STR, Name,
               AUD_FID, OutFid, AUD_STR, LinkContents, AUD_END);
     return code;
@@ -4464,7 +4124,7 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Vnode *targetptr = 0;      /* vnode of the new file */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
     Volume *volptr = 0;                /* pointer to the volume header */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     DirHandle dir;             /* Handle for dir package I/O */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -4519,6 +4179,12 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        goto Bad_Link;
     }
 
+    if (CheckLength(volptr, parentptr, -1)) {
+       VTakeOffline(volptr);
+       errorCode = VSALVAGE;
+       goto Bad_Link;
+    }
+
     /* get the file vnode  */
     if ((errorCode =
         CheckVnode(ExistingFid, &volptr, &targetptr, WRITE_LOCK))) {
@@ -4534,13 +4200,13 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     }
     if (parentptr->disk.cloned) {
        ViceLog(25, ("Link : calling CopyOnWrite on  target dir\n"));
-       if ((errorCode = CopyOnWrite(parentptr, volptr)))
+       if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE)))
            goto Bad_Link;      /* disk full error */
     }
 
     /* add the name to the directory */
     SetDirHandle(&dir, parentptr);
-    if ((errorCode = Create(&dir, (char *)Name, ExistingFid)))
+    if ((errorCode = afs_dir_Create(&dir, Name, ExistingFid)))
        goto Bad_Link;
     DFlush();
 
@@ -4565,14 +4231,14 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* convert the write locks to read locks before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
     VVnodeWriteToRead(&errorCode, parentptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* break call back on DirFid */
     BreakCallBack(client->host, DirFid, 0);
     /*
-     * We also need to break the callback for the file that is hard-linked since part 
+     * We also need to break the callback for the file that is hard-linked since part
      * of its status (like linkcount) is changed
      */
     BreakCallBack(client->host, ExistingFid, 0);
@@ -4597,21 +4263,9 @@ SRXAFS_Link(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_LINK]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_LINK);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_Link;
@@ -4625,25 +4279,9 @@ SRXAFS_Link(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, LinkEvent, code, 
+    osi_auditU(acall, LinkEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, DirFid, AUD_STR, Name,
               AUD_FID, ExistingFid, AUD_END);
@@ -4667,7 +4305,7 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Vnode *targetptr = 0;      /* vnode of the new file */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
     Volume *volptr = 0;                /* pointer to the volume header */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     struct acl_accessList *newACL;     /* Access list */
     int newACLSize;            /* Size of access list */
     DirHandle dir;             /* Handle for dir package I/O */
@@ -4716,7 +4354,7 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * requires w access for the user to create a directory. this
      * closes a loophole in the current security arrangement, since a
      * user with i access only can create a directory and get the
-     * implcit a access that goes with dir ownership, and proceed to 
+     * implcit a access that goes with dir ownership, and proceed to
      * subvert quota in the volume.
      */
     if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))
@@ -4745,10 +4383,10 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 #endif /* FS_STATS_DETAILED */
 
     /* Point to target's ACL buffer and copy the parent's ACL contents to it */
-    assert((SetAccessList
+    osi_Assert((SetAccessList
            (&targetptr, &volptr, &newACL, &newACLSize,
             &parentwhentargetnotdir, (AFSFid *) 0, 0)) == 0);
-    assert(parentwhentargetnotdir == 0);
+    osi_Assert(parentwhentargetnotdir == 0);
     memcpy((char *)newACL, (char *)VVnodeACL(parentptr), VAclSize(parentptr));
 
     /* update the status for the target vnode */
@@ -4757,9 +4395,9 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* Actually create the New directory in the directory package */
     SetDirHandle(&dir, targetptr);
-    assert(!(MakeDir(&dir, OutFid, DirFid)));
+    osi_Assert(!(afs_dir_MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32 *)DirFid)));
     DFlush();
-    VN_SET_LEN(targetptr, (afs_fsize_t) Length(&dir));
+    VN_SET_LEN(targetptr, (afs_fsize_t) afs_dir_Length(&dir));
 
     /* set up return status */
     GetStatus(targetptr, OutFidStatus, rights, anyrights, parentptr);
@@ -4767,7 +4405,7 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, parentptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* break call back on DirFid */
     BreakCallBack(client->host, DirFid, 0);
@@ -4798,21 +4436,10 @@ SRXAFS_MakeDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
+
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_MAKEDIR);
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_MAKEDIR]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_MakeDir;
 
@@ -4825,25 +4452,9 @@ SRXAFS_MakeDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, MakeDirEvent, code, 
+    osi_auditU(acall, MakeDirEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, DirFid, AUD_STR, Name,
               AUD_FID, OutFid, AUD_END);
@@ -4864,12 +4475,11 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
     Vnode *targetptr = 0;      /* file to be deleted */
     AFSFid fileFid;            /* area for Fid from the directory */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     DirHandle dir;             /* Handle for dir package I/O */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
-    Vnode debugvnode1, debugvnode2;
     struct client *t_client;   /* tmp ptr to client data */
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
     struct rx_connection *tcon = rx_ConnectionOf(acall);
@@ -4896,7 +4506,6 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
                          &rights, &anyrights))) {
        goto Bad_RemoveDir;
     }
-    debugvnode1 = *parentptr;
 
     /* set volume synchronization information */
     SetVolumeSync(Sync, volptr);
@@ -4906,7 +4515,6 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        goto Bad_RemoveDir;
     }
 
-    debugvnode2 = *parentptr;
     /* Do the actual delete of the desired (empty) directory, Name */
     if ((errorCode =
         DeleteTarget(parentptr, volptr, &targetptr, &dir, &fileFid, Name,
@@ -4936,7 +4544,7 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, parentptr);
-    assert(!errorCode || errorCode == VSALVAGE);
+    osi_Assert(!errorCode || errorCode == VSALVAGE);
 
     /* break call back on DirFid and fileFid */
     BreakCallBack(client->host, DirFid, 0);
@@ -4961,21 +4569,9 @@ SRXAFS_RemoveDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_REMOVEDIR]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEDIR);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_RemoveDir;
@@ -4987,25 +4583,9 @@ SRXAFS_RemoveDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, RemoveDirEvent, code, 
+    osi_auditU(acall, RemoveDirEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, DirFid, AUD_STR, Name, AUD_END);
     return code;
@@ -5023,7 +4603,7 @@ SAFSS_SetLock(struct rx_call *acall, struct AFSFid *Fid, ViceLockType type,
 {
     Vnode *targetptr = 0;      /* vnode of input file */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -5093,21 +4673,9 @@ SRXAFS_SetLock(struct rx_call * acall, struct AFSFid * Fid, ViceLockType type,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_SETLOCK]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETLOCK);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_SetLock;
@@ -5119,26 +4687,10 @@ SRXAFS_SetLock(struct rx_call * acall, struct AFSFid * Fid, ViceLockType type,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, SetLockEvent, code, 
-               AUD_ID, t_client ? t_client->ViceId : 0, 
+    osi_auditU(acall, SetLockEvent, code,
+               AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_LONG, type, AUD_END);
     return code;
 }                              /*SRXAFS_SetLock */
@@ -5154,7 +4706,7 @@ SAFSS_ExtendLock(struct rx_call *acall, struct AFSFid *Fid,
 {
     Vnode *targetptr = 0;      /* vnode of input file */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -5219,21 +4771,9 @@ SRXAFS_ExtendLock(struct rx_call * acall, struct AFSFid * Fid,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_EXTENDLOCK]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_EXTENDLOCK);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_ExtendLock;
@@ -5245,25 +4785,9 @@ SRXAFS_ExtendLock(struct rx_call * acall, struct AFSFid * Fid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, ExtendLockEvent, code, 
+    osi_auditU(acall, ExtendLockEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_END);
     return code;
@@ -5281,7 +4805,7 @@ SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
 {
     Vnode *targetptr = 0;      /* vnode of input file */
     Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client structure */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -5321,7 +4845,7 @@ SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
     if (targetptr->disk.lock.lockCount <= 0) {
        /* convert the write lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, targetptr);
-       assert(!errorCode || errorCode == VSALVAGE);
+       osi_Assert(!errorCode || errorCode == VSALVAGE);
        BreakCallBack(client->host, Fid, 0);
     }
 
@@ -5355,21 +4879,9 @@ SRXAFS_ReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_RELEASELOCK]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RELEASELOCK);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_ReleaseLock;
@@ -5381,26 +4893,10 @@ SRXAFS_ReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, ReleaseLockEvent, code, 
-               AUD_ID, t_client ? t_client->ViceId : 0, 
+    osi_auditU(acall, ReleaseLockEvent, code,
+               AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_FID, Fid, AUD_END);
     return code;
 
@@ -5415,7 +4911,7 @@ SetSystemStats(struct AFSStatistics *stats)
     struct timeval time;
 
     /* this works on all system types */
-    TM_GetTimeOfDay(&time, 0);
+    FT_GetTimeOfDay(&time, 0);
     stats->CurrentTime = time.tv_sec;
 }                              /*SetSystemStats */
 
@@ -5490,21 +4986,9 @@ SRXAFS_GetStatistics(struct rx_call *acall, struct ViceStatistics *Statistics)
     struct rx_connection *tcon = rx_ConnectionOf(acall);
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETSTATISTICS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS);
 
     if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
        goto Bad_GetStatistics;
@@ -5523,25 +5007,9 @@ SRXAFS_GetStatistics(struct rx_call *acall, struct ViceStatistics *Statistics)
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, GetStatisticsEvent, code, 
+    osi_auditU(acall, GetStatisticsEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
     return code;
 }                              /*SRXAFS_GetStatistics */
@@ -5557,27 +5025,15 @@ SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatis
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
     struct timeval time;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETSTATISTICS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS);
 
     if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
        goto Bad_GetStatistics64;
 
     ViceLog(1, ("SAFS_GetStatistics64 Received\n"));
-    Statistics->ViceStatistics64_val = 
+    Statistics->ViceStatistics64_val =
        malloc(statsVersion*sizeof(afs_int64));
     Statistics->ViceStatistics64_len = statsVersion;
     FS_LOCK;
@@ -5585,48 +5041,48 @@ SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatis
     Statistics->ViceStatistics64_val[STATS64_STARTTIME] = StartTime;
     Statistics->ViceStatistics64_val[STATS64_CURRENTCONNECTIONS] =
        CurrentConnections;
-    Statistics->ViceStatistics64_val[STATS64_TOTALVICECALLS] = 
+    Statistics->ViceStatistics64_val[STATS64_TOTALVICECALLS] =
        AFSCallStats.TotalCalls;
     Statistics->ViceStatistics64_val[STATS64_TOTALFETCHES] =
        AFSCallStats.FetchData + AFSCallStats.FetchACL +
        AFSCallStats.FetchStatus;
-    Statistics->ViceStatistics64_val[STATS64_FETCHDATAS] = 
+    Statistics->ViceStatistics64_val[STATS64_FETCHDATAS] =
        AFSCallStats.FetchData;
-    Statistics->ViceStatistics64_val[STATS64_FETCHEDBYTES] = 
+    Statistics->ViceStatistics64_val[STATS64_FETCHEDBYTES] =
        AFSCallStats.TotalFetchedBytes;
     seconds = AFSCallStats.AccumFetchTime / 1000;
     if (seconds <= 0)
         seconds = 1;
-    Statistics->ViceStatistics64_val[STATS64_FETCHDATARATE] = 
+    Statistics->ViceStatistics64_val[STATS64_FETCHDATARATE] =
        AFSCallStats.TotalFetchedBytes / seconds;
     Statistics->ViceStatistics64_val[STATS64_TOTALSTORES] =
         AFSCallStats.StoreData + AFSCallStats.StoreACL +
         AFSCallStats.StoreStatus;
-    Statistics->ViceStatistics64_val[STATS64_STOREDATAS] = 
+    Statistics->ViceStatistics64_val[STATS64_STOREDATAS] =
        AFSCallStats.StoreData;
-    Statistics->ViceStatistics64_val[STATS64_STOREDBYTES] = 
+    Statistics->ViceStatistics64_val[STATS64_STOREDBYTES] =
        AFSCallStats.TotalStoredBytes;
     seconds = AFSCallStats.AccumStoreTime / 1000;
     if (seconds <= 0)
         seconds = 1;
-    Statistics->ViceStatistics64_val[STATS64_STOREDATARATE] = 
+    Statistics->ViceStatistics64_val[STATS64_STOREDATARATE] =
        AFSCallStats.TotalStoredBytes / seconds;
 #ifdef AFS_NT40_ENV
     Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] = -1;
 #else
-    Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] = 
+    Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] =
        (afs_int32) ((long)sbrk(0) >> 10);
 #endif
     FS_UNLOCK;
-    h_GetWorkStats((int *)&(Statistics->ViceStatistics64_val[STATS64_WORKSTATIONS]),
-                   (int *)&(Statistics->ViceStatistics64_val[STATS64_ACTIVEWORKSTATIONS]), 
-                  (int *)0,
-                   (afs_int32) (FT_ApproxTime()) - (15 * 60));
+    h_GetWorkStats64(&(Statistics->ViceStatistics64_val[STATS64_WORKSTATIONS]),
+                     &(Statistics->ViceStatistics64_val[STATS64_ACTIVEWORKSTATIONS]),
+                    0,
+                     (afs_int32) (FT_ApproxTime()) - (15 * 60));
 
 
 
     /* this works on all system types */
-    TM_GetTimeOfDay(&time, 0);
+    FT_GetTimeOfDay(&time, 0);
     Statistics->ViceStatistics64_val[STATS64_CURRENTTIME] = time.tv_sec;
 
   Bad_GetStatistics64:
@@ -5634,25 +5090,9 @@ SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatis
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
-    osi_auditU(acall, GetStatisticsEvent, code, 
+    osi_auditU(acall, GetStatisticsEvent, code,
                AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
     return code;
 }                              /*SRXAFS_GetStatistics */
@@ -5684,43 +5124,17 @@ SRXAFS_XStatsVersion(struct rx_call * a_call, afs_int32 * a_versionP)
 
     struct client *t_client = NULL;    /* tmp ptr to client data */
     struct rx_connection *tcon = rx_ConnectionOf(a_call);
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_XSTATSVERSION]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_XSTATSVERSION);
 
     *a_versionP = AFS_XSTAT_VERSION;
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-    fs_stats_AddTo((opP->sumTime), elapsedTime);
-    fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-    if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-       fs_stats_TimeAssign((opP->minTime), elapsedTime);
-    }
-    if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-       fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-    }
-    FS_LOCK;
-    (opP->numSuccesses)++;
-    FS_UNLOCK;
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, 0);
 
-    osi_auditU(a_call, XStatsVersionEvent, 0, 
+    osi_auditU(a_call, XStatsVersionEvent, 0,
                AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
     return (0);
 }                              /*SRXAFS_XStatsVersion */
@@ -5749,10 +5163,10 @@ SRXAFS_XStatsVersion(struct rx_call * a_call, afs_int32 * a_versionP)
 static void
 FillPerfValues(struct afs_PerfStats *a_perfP)
 {                              /*FillPerfValues */
-    afs_uint32 hi, lo;
     int dir_Buffers;           /*# buffers in use by dir package */
     int dir_Calls;             /*# read calls in dir package */
     int dir_IOs;               /*# I/O ops in dir package */
+    struct rx_statistics *stats;
 
     /*
      * Vnode cache section.
@@ -5768,10 +5182,8 @@ FillPerfValues(struct afs_PerfStats *a_perfP)
     a_perfP->vcache_S_Reads = VnodeClassInfo[vSmall].reads;
     a_perfP->vcache_S_Writes = VnodeClassInfo[vSmall].writes;
     a_perfP->vcache_H_Entries = VStats.hdr_cache_size;
-    SplitInt64(VStats.hdr_gets, hi, lo);
-    a_perfP->vcache_H_Gets = lo;
-    SplitInt64(VStats.hdr_loads, hi, lo);
-    a_perfP->vcache_H_Replacements = lo;
+    a_perfP->vcache_H_Gets = (int)VStats.hdr_gets;
+    a_perfP->vcache_H_Replacements = (int)VStats.hdr_loads;
 
     /*
      * Directory section.
@@ -5784,58 +5196,60 @@ FillPerfValues(struct afs_PerfStats *a_perfP)
     /*
      * Rx section.
      */
-    a_perfP->rx_packetRequests = (afs_int32) rx_stats.packetRequests;
+    stats = rx_GetStatistics();
+
+    a_perfP->rx_packetRequests = (afs_int32) stats->packetRequests;
     a_perfP->rx_noPackets_RcvClass =
-       (afs_int32) rx_stats.receivePktAllocFailures;
+       (afs_int32) stats->receivePktAllocFailures;
     a_perfP->rx_noPackets_SendClass =
-       (afs_int32) rx_stats.sendPktAllocFailures;
+       (afs_int32) stats->sendPktAllocFailures;
     a_perfP->rx_noPackets_SpecialClass =
-       (afs_int32) rx_stats.specialPktAllocFailures;
-    a_perfP->rx_socketGreedy = (afs_int32) rx_stats.socketGreedy;
-    a_perfP->rx_bogusPacketOnRead = (afs_int32) rx_stats.bogusPacketOnRead;
-    a_perfP->rx_bogusHost = (afs_int32) rx_stats.bogusHost;
-    a_perfP->rx_noPacketOnRead = (afs_int32) rx_stats.noPacketOnRead;
+       (afs_int32) stats->specialPktAllocFailures;
+    a_perfP->rx_socketGreedy = (afs_int32) stats->socketGreedy;
+    a_perfP->rx_bogusPacketOnRead = (afs_int32) stats->bogusPacketOnRead;
+    a_perfP->rx_bogusHost = (afs_int32) stats->bogusHost;
+    a_perfP->rx_noPacketOnRead = (afs_int32) stats->noPacketOnRead;
     a_perfP->rx_noPacketBuffersOnRead =
-       (afs_int32) rx_stats.noPacketBuffersOnRead;
-    a_perfP->rx_selects = (afs_int32) rx_stats.selects;
-    a_perfP->rx_sendSelects = (afs_int32) rx_stats.sendSelects;
+       (afs_int32) stats->noPacketBuffersOnRead;
+    a_perfP->rx_selects = (afs_int32) stats->selects;
+    a_perfP->rx_sendSelects = (afs_int32) stats->sendSelects;
     a_perfP->rx_packetsRead_RcvClass =
-       (afs_int32) rx_stats.packetsRead[RX_PACKET_CLASS_RECEIVE];
+       (afs_int32) stats->packetsRead[RX_PACKET_CLASS_RECEIVE];
     a_perfP->rx_packetsRead_SendClass =
-       (afs_int32) rx_stats.packetsRead[RX_PACKET_CLASS_SEND];
+       (afs_int32) stats->packetsRead[RX_PACKET_CLASS_SEND];
     a_perfP->rx_packetsRead_SpecialClass =
-       (afs_int32) rx_stats.packetsRead[RX_PACKET_CLASS_SPECIAL];
-    a_perfP->rx_dataPacketsRead = (afs_int32) rx_stats.dataPacketsRead;
-    a_perfP->rx_ackPacketsRead = (afs_int32) rx_stats.ackPacketsRead;
-    a_perfP->rx_dupPacketsRead = (afs_int32) rx_stats.dupPacketsRead;
+       (afs_int32) stats->packetsRead[RX_PACKET_CLASS_SPECIAL];
+    a_perfP->rx_dataPacketsRead = (afs_int32) stats->dataPacketsRead;
+    a_perfP->rx_ackPacketsRead = (afs_int32) stats->ackPacketsRead;
+    a_perfP->rx_dupPacketsRead = (afs_int32) stats->dupPacketsRead;
     a_perfP->rx_spuriousPacketsRead =
-       (afs_int32) rx_stats.spuriousPacketsRead;
+       (afs_int32) stats->spuriousPacketsRead;
     a_perfP->rx_packetsSent_RcvClass =
-       (afs_int32) rx_stats.packetsSent[RX_PACKET_CLASS_RECEIVE];
+       (afs_int32) stats->packetsSent[RX_PACKET_CLASS_RECEIVE];
     a_perfP->rx_packetsSent_SendClass =
-       (afs_int32) rx_stats.packetsSent[RX_PACKET_CLASS_SEND];
+       (afs_int32) stats->packetsSent[RX_PACKET_CLASS_SEND];
     a_perfP->rx_packetsSent_SpecialClass =
-       (afs_int32) rx_stats.packetsSent[RX_PACKET_CLASS_SPECIAL];
-    a_perfP->rx_ackPacketsSent = (afs_int32) rx_stats.ackPacketsSent;
-    a_perfP->rx_pingPacketsSent = (afs_int32) rx_stats.pingPacketsSent;
-    a_perfP->rx_abortPacketsSent = (afs_int32) rx_stats.abortPacketsSent;
-    a_perfP->rx_busyPacketsSent = (afs_int32) rx_stats.busyPacketsSent;
-    a_perfP->rx_dataPacketsSent = (afs_int32) rx_stats.dataPacketsSent;
-    a_perfP->rx_dataPacketsReSent = (afs_int32) rx_stats.dataPacketsReSent;
-    a_perfP->rx_dataPacketsPushed = (afs_int32) rx_stats.dataPacketsPushed;
-    a_perfP->rx_ignoreAckedPacket = (afs_int32) rx_stats.ignoreAckedPacket;
-    a_perfP->rx_totalRtt_Sec = (afs_int32) rx_stats.totalRtt.sec;
-    a_perfP->rx_totalRtt_Usec = (afs_int32) rx_stats.totalRtt.usec;
-    a_perfP->rx_minRtt_Sec = (afs_int32) rx_stats.minRtt.sec;
-    a_perfP->rx_minRtt_Usec = (afs_int32) rx_stats.minRtt.usec;
-    a_perfP->rx_maxRtt_Sec = (afs_int32) rx_stats.maxRtt.sec;
-    a_perfP->rx_maxRtt_Usec = (afs_int32) rx_stats.maxRtt.usec;
-    a_perfP->rx_nRttSamples = (afs_int32) rx_stats.nRttSamples;
-    a_perfP->rx_nServerConns = (afs_int32) rx_stats.nServerConns;
-    a_perfP->rx_nClientConns = (afs_int32) rx_stats.nClientConns;
-    a_perfP->rx_nPeerStructs = (afs_int32) rx_stats.nPeerStructs;
-    a_perfP->rx_nCallStructs = (afs_int32) rx_stats.nCallStructs;
-    a_perfP->rx_nFreeCallStructs = (afs_int32) rx_stats.nFreeCallStructs;
+       (afs_int32) stats->packetsSent[RX_PACKET_CLASS_SPECIAL];
+    a_perfP->rx_ackPacketsSent = (afs_int32) stats->ackPacketsSent;
+    a_perfP->rx_pingPacketsSent = (afs_int32) stats->pingPacketsSent;
+    a_perfP->rx_abortPacketsSent = (afs_int32) stats->abortPacketsSent;
+    a_perfP->rx_busyPacketsSent = (afs_int32) stats->busyPacketsSent;
+    a_perfP->rx_dataPacketsSent = (afs_int32) stats->dataPacketsSent;
+    a_perfP->rx_dataPacketsReSent = (afs_int32) stats->dataPacketsReSent;
+    a_perfP->rx_dataPacketsPushed = (afs_int32) stats->dataPacketsPushed;
+    a_perfP->rx_ignoreAckedPacket = (afs_int32) stats->ignoreAckedPacket;
+    a_perfP->rx_totalRtt_Sec = (afs_int32) stats->totalRtt.sec;
+    a_perfP->rx_totalRtt_Usec = (afs_int32) stats->totalRtt.usec;
+    a_perfP->rx_minRtt_Sec = (afs_int32) stats->minRtt.sec;
+    a_perfP->rx_minRtt_Usec = (afs_int32) stats->minRtt.usec;
+    a_perfP->rx_maxRtt_Sec = (afs_int32) stats->maxRtt.sec;
+    a_perfP->rx_maxRtt_Usec = (afs_int32) stats->maxRtt.usec;
+    a_perfP->rx_nRttSamples = (afs_int32) stats->nRttSamples;
+    a_perfP->rx_nServerConns = (afs_int32) stats->nServerConns;
+    a_perfP->rx_nClientConns = (afs_int32) stats->nClientConns;
+    a_perfP->rx_nPeerStructs = (afs_int32) stats->nPeerStructs;
+    a_perfP->rx_nCallStructs = (afs_int32) stats->nCallStructs;
+    a_perfP->rx_nFreeCallStructs = (afs_int32) stats->nFreeCallStructs;
 
     a_perfP->host_NumHostEntries = HTs;
     a_perfP->host_HostBlocks = HTBlocks;
@@ -5847,8 +5261,9 @@ FillPerfValues(struct afs_PerfStats *a_perfP)
     a_perfP->host_ClientBlocks = CEBlocks;
 
     a_perfP->sysname_ID = afs_perfstats.sysname_ID;
-    a_perfP->rx_nBusies = (afs_int32) rx_stats.nBusies;
+    a_perfP->rx_nBusies = (afs_int32) stats->nBusies;
     a_perfP->fs_nBusies = afs_perfstats.fs_nBusies;
+    rx_FreeStatistics(&stats);
 }                              /*FillPerfValues */
 
 
@@ -5885,24 +5300,12 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
                 afs_int32 * a_timeP, AFS_CollData * a_dataP)
 {                              /*SRXAFS_GetXStats */
 
-    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 */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETXSTATS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETXSTATS);
 
     /*
      * Record the time of day and the server version number.
@@ -6043,23 +5446,7 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
        code = 1;
     }                          /*Switch on collection number */
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
     return (code);
 
@@ -6071,26 +5458,13 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
                       struct AFSCBs *CallBackArray)
 {
     afs_int32 errorCode = 0;
-    register int i;
+    int i;
     struct client *client = 0;
     struct rx_connection *tcon;
     struct host *thost;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP =
-       &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GIVEUPCALLBACKS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GIVEUPCALLBACKS);
 
     if (FidArray)
        ViceLog(1,
@@ -6127,7 +5501,7 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
        errorCode = GetClient(tcon, &client);
        if (!errorCode) {
            for (i = 0; i < FidArray->AFSCBFids_len; i++) {
-               register struct AFSFid *fid = &(FidArray->AFSCBFids_val[i]);
+               struct AFSFid *fid = &(FidArray->AFSCBFids_val[i]);
                DeleteCallBack(client->host, fid);
            }
            PutClient(&client);
@@ -6137,23 +5511,8 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
   Bad_GiveUpCallBacks:
     errorCode = CallPostamble(tcon, errorCode, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
+
     return errorCode;
 
 }                              /*common_GiveUpCallBacks */
@@ -6183,7 +5542,7 @@ SRXAFS_NGetVolumeInfo(struct rx_call * acall, char *avolid,
 
 
 /*
- * Dummy routine. Should never be called (the cache manager should only 
+ * Dummy routine. Should never be called (the cache manager should only
  * invoke this interface when communicating with a AFS/DFS Protocol
  * Translator).
  */
@@ -6205,7 +5564,7 @@ SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
     afs_int32 code;
     struct rx_connection *tcon;
     struct host *thost;
-    afs_int32 *dataBuffP;
+    afs_uint32 *dataBuffP;
     afs_int32 dataBytes;
 
     FS_LOCK;
@@ -6218,11 +5577,9 @@ SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
        goto Bad_GetCaps;
 
     dataBytes = 1 * sizeof(afs_int32);
-    dataBuffP = (afs_int32 *) malloc(dataBytes);
+    dataBuffP = (afs_uint32 *) malloc(dataBytes);
     dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS | VICED_CAPABILITY_WRITELOCKACL;
-#if defined(AFS_64BIT_ENV) && defined(AFS_LARGEFILE_ENV)
     dataBuffP[0] |= VICED_CAPABILITY_64BITFILES;
-#endif
     if (saneacls)
        dataBuffP[0] |= VICED_CAPABILITY_SANEACLS;
 
@@ -6244,9 +5601,8 @@ SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids,
     int i;
     afs_int32 nids, naddrs;
     afs_int32 *vd, *addr;
-    int errorCode = 0;         /* return code to caller */
+    Error errorCode = 0;               /* return code to caller */
     struct client *client = 0;
-    struct rx_connection *tcon = rx_ConnectionOf(acall);
 
     ViceLog(1, ("SRXAFS_FlushCPS\n"));
     FS_LOCK;
@@ -6295,10 +5651,10 @@ SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids,
 
 /* worthless hack to let CS keep running ancient software */
 static int
-afs_vtoi(register char *aname)
+afs_vtoi(char *aname)
 {
-    register afs_int32 temp;
-    register int tc;
+    afs_int32 temp;
+    int tc;
 
     temp = 0;
     while ((tc = *aname++)) {
@@ -6315,10 +5671,10 @@ afs_vtoi(register char *aname)
  * or backup volumes by name or #
  */
 static afs_int32
-CopyVolumeEntry(char *aname, register struct vldbentry *ave,
-               register struct VolumeInfo *av)
+CopyVolumeEntry(char *aname, struct vldbentry *ave,
+               struct VolumeInfo *av)
 {
-    register int i, j, vol;
+    int i, j, vol;
     afs_int32 mask, whichType;
     afs_uint32 *serverHost, *typePtr;
 
@@ -6383,7 +5739,7 @@ TryLocalVLServer(char *avolid, struct VolumeInfo *avolinfo)
     static afs_int32 lastDownTime = 0;
     struct vldbentry tve;
     struct rx_securityClass *vlSec;
-    register afs_int32 code;
+    afs_int32 code;
 
     if (!vlConn) {
        vlSec = rxnull_NewClientSecurityObject();
@@ -6423,21 +5779,10 @@ SRXAFS_GetVolumeInfo(struct rx_call * acall, char *avolid,
     afs_int32 code;
     struct rx_connection *tcon;
     struct host *thost;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
+
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMEINFO);
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETVOLUMEINFO]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_GetVolumeInfo;
 
@@ -6454,23 +5799,7 @@ SRXAFS_GetVolumeInfo(struct rx_call * acall, char *avolid,
   Bad_GetVolumeInfo:
     code = CallPostamble(tcon, code, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
     return code;
 
@@ -6484,7 +5813,7 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
 {
     Vnode *targetptr = 0;      /* vnode of the new file */
     Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client entry */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -6492,22 +5821,9 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     struct rx_connection *tcon;
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP =
-       &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETVOLUMESTATUS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMESTATUS);
 
     ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
     if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -6556,25 +5872,9 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
-    osi_auditU(acall, GetVolumeStatusEvent, errorCode, 
+    osi_auditU(acall, GetVolumeStatusEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_LONG, avolid, AUD_STR, *Name, AUD_END);
     return (errorCode);
@@ -6589,7 +5889,7 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
 {
     Vnode *targetptr = 0;      /* vnode of the new file */
     Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
-    int errorCode = 0;         /* error code */
+    Error errorCode = 0;               /* error code */
     Volume *volptr = 0;                /* pointer to the volume header */
     struct client *client = 0; /* pointer to client entry */
     afs_int32 rights, anyrights;       /* rights for this and any user */
@@ -6597,22 +5897,9 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     struct rx_connection *tcon = rx_ConnectionOf(acall);
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP =
-       &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_SETVOLUMESTATUS]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETVOLUMESTATUS);
 
     ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
     if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -6647,32 +5934,16 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
        RXUpdate_VolumeStatus(volptr, StoreVolStatus, Name, OfflineMsg, Motd);
 
   Bad_SetVolumeStatus:
-    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, 
+    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
                     volptr, &client);
     ViceLog(2, ("SAFS_SetVolumeStatus returns %d\n", errorCode));
     errorCode = CallPostamble(tcon, errorCode, thost);
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
-    osi_auditU(acall, SetVolumeStatusEvent, errorCode, 
+    osi_auditU(acall, SetVolumeStatusEvent, errorCode,
                AUD_ID, t_client ? t_client->ViceId : 0,
                AUD_LONG, avolid, AUD_STR, Name, AUD_END);
     return (errorCode);
@@ -6689,26 +5960,11 @@ SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
     char *temp;
     struct rx_connection *tcon;
     struct host *thost;
+    Error errorCode = 0;
 #endif
-    int errorCode = 0;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime;        /* Start time for RPC op */
-#ifdef notdef
-    struct timeval opStopTime;
-    struct timeval elapsedTime;        /* Transfer time */
-#endif
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETROOTVOLUME]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETROOTVOLUME);
 
     return FSERR_EOPNOTSUPP;
 
@@ -6744,23 +6000,7 @@ SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
   Bad_GetRootVolume:
     errorCode = CallPostamble(tcon, errorCode, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (errorCode == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, errorCode);
 
     return (errorCode);
 #endif /* notdef */
@@ -6776,21 +6016,9 @@ SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
     afs_int32 code;
     struct rx_connection *tcon;
     struct host *thost;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_CHECKTOKEN]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_CHECKTOKEN);
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_CheckToken;
@@ -6800,23 +6028,7 @@ SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
   Bad_CheckToken:
     code = CallPostamble(tcon, code, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
     return code;
 
@@ -6830,21 +6042,9 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
     struct rx_connection *tcon;
     struct host *thost;
     struct timeval tpl;
-#if FS_STATS_DETAILED
-    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
-    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
-    struct timeval elapsedTime;        /* Transfer time */
+    struct fsstats fsstats;
 
-    /*
-     * Set our stats pointer, remember when the RPC operation started, and
-     * tally the operation.
-     */
-    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETTIME]);
-    FS_LOCK;
-    (opP->numOps)++;
-    FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETTIME);
 
     if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
        goto Bad_GetTime;
@@ -6852,7 +6052,7 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
     FS_LOCK;
     AFSCallStats.GetTime++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&tpl, 0);
+    FT_GetTimeOfDay(&tpl, 0);
     *Seconds = tpl.tv_sec;
     *USeconds = tpl.tv_usec;
 
@@ -6861,23 +6061,7 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
   Bad_GetTime:
     code = CallPostamble(tcon, code, thost);
 
-#if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
-    fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
-    if (code == 0) {
-       FS_LOCK;
-       (opP->numSuccesses)++;
-       fs_stats_AddTo((opP->sumTime), elapsedTime);
-       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
-       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
-           fs_stats_TimeAssign((opP->minTime), elapsedTime);
-       }
-       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
-           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
-       }
-       FS_UNLOCK;
-    }
-#endif /* FS_STATS_DETAILED */
+    fsstats_FinishOp(&fsstats, code);
 
     return code;
 
@@ -6896,45 +6080,36 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
  *     Call            : Ptr to the Rx call involved.
  *     Pos             : Offset within the file.
  *     Len             : Length in bytes to read; this value is bogus!
- * if FS_STATS_DETAILED
  *     a_bytesToFetchP : Set to the number of bytes to be fetched from
  *                       the File Server.
  *     a_bytesFetchedP : Set to the actual number of bytes fetched from
  *                       the File Server.
- * endif
  */
 
-afs_int32
+static afs_int32
 FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
-                 register struct rx_call * Call, afs_sfsize_t Pos,
+                 struct rx_call * Call, afs_sfsize_t Pos,
                  afs_sfsize_t Len, afs_int32 Int64Mode,
-#if FS_STATS_DETAILED
                  afs_sfsize_t * a_bytesToFetchP,
-                 afs_sfsize_t * a_bytesFetchedP
-#endif                         /* FS_STATS_DETAILED */
-    )
+                 afs_sfsize_t * a_bytesFetchedP)
 {
     struct timeval StartTime, StopTime;        /* used to calculate file  transfer rates */
-    int errorCode = 0;         /* Returned error code to caller */
     IHandle_t *ihP;
     FdHandle_t *fdP;
-#ifdef AFS_NT40_ENV
-    register char *tbuffer;
-#else /* AFS_NT40_ENV */
+#ifndef HAVE_PIOV
+    char *tbuffer;
+#else /* HAVE_PIOV */
     struct iovec tiov[RX_MAXIOVECS];
     int tnio;
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     afs_sfsize_t tlen;
     afs_int32 optSize;
 
-#if FS_STATS_DETAILED
     /*
      * Initialize the byte count arguments.
      */
     (*a_bytesToFetchP) = 0;
     (*a_bytesFetchedP) = 0;
-#endif /* FS_STATS_DETAILED */
-
 
     ViceLog(25,
            ("FetchData_RXStyle: Pos %llu, Len %llu\n", (afs_uintmax_t) Pos,
@@ -6951,7 +6126,7 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
        rx_Write(Call, (char *)&zero, sizeof(afs_int32));       /* send 0-length  */
        return (0);
     }
-    TM_GetTimeOfDay(&StartTime, 0);
+    FT_GetTimeOfDay(&StartTime, 0);
     ihP = targetptr->handle;
     fdP = IH_OPEN(ihP);
     if (fdP == NULL) {
@@ -6971,17 +6146,22 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
                    volptr->hashid));
        return EIO;
     }
+    if (CheckLength(volptr, targetptr, tlen)) {
+       FDH_CLOSE(fdP);
+       VTakeOffline(volptr);
+       return VSALVAGE;
+    }
     if (Pos > tlen) {
        Len = 0;
     }
 
-    if (Pos + Len > tlen)
-       Len = tlen - Pos;       /* get length we should send */
-    (void)FDH_SEEK(fdP, Pos, 0);
+    if (Pos + Len > tlen) /* get length we should send */
+       Len = ((tlen - Pos) < 0) ? 0 : tlen - Pos;
+
     {
        afs_int32 high, low;
        SplitOffsetOrSize(Len, high, low);
-       assert(Int64Mode || (Len >= 0 && high == 0) || Len < 0);
+       osi_Assert(Int64Mode || (Len >= 0 && high == 0) || Len < 0);
        if (Int64Mode) {
            high = htonl(high);
            rx_Write(Call, (char *)&high, sizeof(afs_int32));   /* High order bits */
@@ -6989,21 +6169,20 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
        low = htonl(low);
        rx_Write(Call, (char *)&low, sizeof(afs_int32));        /* send length on fetch */
     }
-#if FS_STATS_DETAILED
     (*a_bytesToFetchP) = Len;
-#endif /* FS_STATS_DETAILED */
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     tbuffer = AllocSendBuffer();
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     while (Len > 0) {
-       int wlen;
+       size_t wlen;
+       ssize_t nBytes;
        if (Len > optSize)
            wlen = optSize;
        else
-           wlen = (int)Len;
-#ifdef AFS_NT40_ENV
-       errorCode = FDH_READ(fdP, tbuffer, wlen);
-       if (errorCode != wlen) {
+           wlen = Len;
+#ifndef HAVE_PIOV
+       nBytes = FDH_PREAD(fdP, tbuffer, wlen, Pos);
+       if (nBytes != wlen) {
            FDH_CLOSE(fdP);
            FreeSendBuffer((struct afs_buffer *)tbuffer);
            VTakeOffline(volptr);
@@ -7011,45 +6190,49 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
                        volptr->hashid));
            return EIO;
        }
-       errorCode = rx_Write(Call, tbuffer, wlen);
-#else /* AFS_NT40_ENV */
-       errorCode = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS, wlen);
-       if (errorCode <= 0) {
+       nBytes = rx_Write(Call, tbuffer, wlen);
+#else /* HAVE_PIOV */
+       nBytes = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS, wlen);
+       if (nBytes <= 0) {
            FDH_CLOSE(fdP);
            return EIO;
        }
-       wlen = errorCode;
-       errorCode = FDH_READV(fdP, tiov, tnio);
-       if (errorCode != wlen) {
+       wlen = nBytes;
+       nBytes = FDH_PREADV(fdP, tiov, tnio, Pos);
+       if (nBytes != wlen) {
            FDH_CLOSE(fdP);
            VTakeOffline(volptr);
            ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
                        volptr->hashid));
            return EIO;
        }
-       errorCode = rx_Writev(Call, tiov, tnio, wlen);
-#endif /* AFS_NT40_ENV */
-#if FS_STATS_DETAILED
+       nBytes = rx_Writev(Call, tiov, tnio, wlen);
+#endif /* HAVE_PIOV */
+       Pos += wlen;
        /*
         * Bump the number of bytes actually sent by the number from this
         * latest iteration
         */
-       (*a_bytesFetchedP) += errorCode;
-#endif /* FS_STATS_DETAILED */
-       if (errorCode != wlen) {
+       (*a_bytesFetchedP) += nBytes;
+       if (nBytes != wlen) {
+           afs_int32 err;
            FDH_CLOSE(fdP);
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
            FreeSendBuffer((struct afs_buffer *)tbuffer);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
+           err = VIsGoingOffline(volptr);
+           if (err) {
+               return err;
+           }
            return -31;
        }
        Len -= wlen;
     }
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     FreeSendBuffer((struct afs_buffer *)tbuffer);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     FDH_CLOSE(fdP);
-    TM_GetTimeOfDay(&StopTime, 0);
+    FT_GetTimeOfDay(&StopTime, 0);
 
     /* Adjust all Fetch Data related stats */
     FS_LOCK;
@@ -7086,11 +6269,7 @@ GetLinkCountAndSize(Volume * vp, FdHandle_t * fdP, int *lc,
     lhp = IH_OPEN(V_linkHandle(vp));
     if (!lhp)
        return EIO;
-#ifdef AFS_NT40_ENV
-    *lc = nt_GetLinkCount(lhp, fdP->fd_ih->ih_ino, 0);
-#else
-    *lc = namei_GetLinkCount(lhp, fdP->fd_ih->ih_ino, 0);
-#endif
+    *lc = namei_GetLinkCount(lhp, fdP->fd_ih->ih_ino, 0, 0, 1);
     FDH_CLOSE(lhp);
     if (*lc < 0)
        return -1;
@@ -7121,33 +6300,28 @@ GetLinkCountAndSize(Volume * vp, FdHandle_t * fdP, int *lc,
  *     Call            : Ptr to the Rx call involved.
  *     Pos             : Offset within the file.
  *     Len             : Length in bytes to store; this value is bogus!
- * if FS_STATS_DETAILED
  *     a_bytesToStoreP : Set to the number of bytes to be stored to
  *                       the File Server.
  *     a_bytesStoredP  : Set to the actual number of bytes stored to
  *                       the File Server.
- * endif
  */
 afs_int32
 StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
-                 struct client * client, register struct rx_call * Call,
+                 struct client * client, struct rx_call * Call,
                  afs_fsize_t Pos, afs_fsize_t Length, afs_fsize_t FileLength,
                  int sync,
-#if FS_STATS_DETAILED
                  afs_sfsize_t * a_bytesToStoreP,
-                 afs_sfsize_t * a_bytesStoredP
-#endif                         /* FS_STATS_DETAILED */
-    )
+                 afs_sfsize_t * a_bytesStoredP)
 {
     afs_sfsize_t bytesTransfered;      /* number of bytes actually transfered */
     struct timeval StartTime, StopTime;        /* Used to measure how long the store takes */
-    int errorCode = 0;         /* Returned error code to caller */
-#ifdef AFS_NT40_ENV
-    register char *tbuffer;    /* data copying buffer */
-#else /* AFS_NT40_ENV */
+    Error errorCode = 0;               /* Returned error code to caller */
+#ifndef HAVE_PIOV
+    char *tbuffer;     /* data copying buffer */
+#else /* HAVE_PIOV */
     struct iovec tiov[RX_MAXIOVECS];   /* no data copying with iovec */
     int tnio;                  /* temp for iovec size */
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     afs_sfsize_t tlen;         /* temp for xfr length */
     Inode tinode;              /* inode for I/O */
     afs_int32 optSize;         /* optimal transfer size */
@@ -7156,16 +6330,16 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     afs_fsize_t NewLength;     /* size after this store completes */
     afs_sfsize_t adjustSize;   /* bytes to call VAdjust... with */
     int linkCount = 0;         /* link count on inode */
+    ssize_t nBytes;
     FdHandle_t *fdP;
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
+    afs_ino_str_t stmp;
 
-#if FS_STATS_DETAILED
     /*
      * Initialize the byte count arguments.
      */
     (*a_bytesToStoreP) = 0;
     (*a_bytesStoredP) = 0;
-#endif /* FS_STATS_DETAILED */
 
     /*
      * We break the callbacks here so that the following signal will not
@@ -7190,7 +6364,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
         */
        ViceLog(25,
                ("StoreData_RXStyle : Opening inode %s\n",
-                PrintInode(NULL, VN_GET_INO(targetptr))));
+                PrintInode(stmp, VN_GET_INO(targetptr))));
        fdP = IH_OPEN(targetptr->handle);
        if (fdP == NULL)
            return ENOENT;
@@ -7201,12 +6375,17 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
                        volptr->hashid));
            return EIO;
        }
+       if (CheckLength(volptr, targetptr, DataLength)) {
+           FDH_CLOSE(fdP);
+           VTakeOffline(volptr);
+           return VSALVAGE;
+       }
 
        if (linkCount != 1) {
            afs_fsize_t size;
            ViceLog(25,
                    ("StoreData_RXStyle : inode %s has more than onelink\n",
-                    PrintInode(NULL, VN_GET_INO(targetptr))));
+                    PrintInode(stmp, VN_GET_INO(targetptr))));
            /* other volumes share this data, better copy it first */
 
            /* Adjust the disk block count by the creation of the new inode.
@@ -7226,7 +6405,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
            }
 
            ViceLog(25, ("StoreData : calling CopyOnWrite on  target dir\n"));
-           if ((errorCode = CopyOnWrite(targetptr, volptr))) {
+           if ((errorCode = CopyOnWrite(targetptr, volptr, 0, MAXFSIZE))) {
                ViceLog(25, ("StoreData : CopyOnWrite failed\n"));
                volptr->partition->flags &= ~PART_DONTUPDATE;
                return (errorCode);
@@ -7275,7 +6454,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     /* this bit means that the locks are set and protections are OK */
     rx_SetLocalStatus(Call, 1);
 
-    TM_GetTimeOfDay(&StartTime, 0);
+    FT_GetTimeOfDay(&StartTime, 0);
 
     optSize = sendBufSize;
     ViceLog(25,
@@ -7286,12 +6465,10 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
     if (FileLength < DataLength)
        FDH_TRUNC(fdP, FileLength);
-    if (Pos > 0)
-       FDH_SEEK(fdP, Pos, 0);
     bytesTransfered = 0;
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     tbuffer = AllocSendBuffer();
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     /* if length == 0, the loop below isn't going to do anything, including
      * extend the length of the inode, which it must do, since the file system
      * assumes that the inode length == vnode's file length.  So, we extend
@@ -7303,15 +6480,15 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
        /* Set the file's length; we've already done an lseek to the right
         * spot above.
         */
-       errorCode = FDH_WRITE(fdP, &tlen, 1);
-       if (errorCode != 1)
+       nBytes = FDH_PWRITE(fdP, &tlen, 1, Pos);
+       if (nBytes != 1) {
+           errorCode = -1;
            goto done;
+       }
        errorCode = FDH_TRUNC(fdP, Pos);
     } else {
        /* have some data to copy */
-#if FS_STATS_DETAILED
        (*a_bytesToStoreP) = Length;
-#endif /* FS_STATS_DETAILED */
        while (1) {
            int rlen;
            if (bytesTransfered >= Length) {
@@ -7323,40 +6500,41 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
                rlen = optSize; /* bound by buffer size */
            else
                rlen = (int)tlen;
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
            errorCode = rx_Read(Call, tbuffer, rlen);
-#else /* AFS_NT40_ENV */
+#else /* HAVE_PIOV */
            errorCode = rx_Readv(Call, tiov, &tnio, RX_MAXIOVECS, rlen);
-#endif /* AFS_NT40_ENV */
-#if FS_STATS_DETAILED
-           (*a_bytesStoredP) += errorCode;
-#endif /* FS_STATS_DETAILED */
+#endif /* HAVE_PIOV */
            if (errorCode <= 0) {
                errorCode = -32;
                break;
            }
+           (*a_bytesStoredP) += errorCode;
            rlen = errorCode;
-#ifdef AFS_NT40_ENV
-           errorCode = FDH_WRITE(fdP, tbuffer, rlen);
-#else /* AFS_NT40_ENV */
-           errorCode = FDH_WRITEV(fdP, tiov, tnio);
-#endif /* AFS_NT40_ENV */
-           if (errorCode != rlen) {
+#ifndef HAVE_PIOV
+           nBytes = FDH_PWRITE(fdP, tbuffer, rlen, Pos);
+#else /* HAVE_PIOV */
+           nBytes = FDH_PWRITEV(fdP, tiov, tnio, Pos);
+#endif /* HAVE_PIOV */
+           if (nBytes != rlen) {
                errorCode = VDISKFULL;
                break;
            }
            bytesTransfered += rlen;
+           Pos += rlen;
        }
     }
   done:
-#ifdef AFS_NT40_ENV
+#ifndef HAVE_PIOV
     FreeSendBuffer((struct afs_buffer *)tbuffer);
-#endif /* AFS_NT40_ENV */
+#endif /* HAVE_PIOV */
     if (sync) {
        FDH_SYNC(fdP);
     }
     if (errorCode) {
-       afs_fsize_t nfSize = (afs_fsize_t) FDH_SIZE(fdP);
+       Error tmp_errorCode = 0;
+       afs_sfsize_t nfSize = FDH_SIZE(fdP);
+       osi_Assert(nfSize >= 0);
        /* something went wrong: adjust size and return */
        VN_SET_LEN(targetptr, nfSize);  /* set new file size. */
        /* changed_newTime is tested in StoreData to detemine if we
@@ -7365,14 +6543,17 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
        targetptr->changed_newTime = 1;
        FDH_CLOSE(fdP);
        /* set disk usage to be correct */
-       VAdjustDiskUsage(&errorCode, volptr,
+       VAdjustDiskUsage(&tmp_errorCode, volptr,
                         (afs_sfsize_t) (nBlocks(nfSize) -
                                         nBlocks(NewLength)), 0);
+       if (tmp_errorCode) {
+           errorCode = tmp_errorCode;
+       }
        return errorCode;
     }
     FDH_CLOSE(fdP);
 
-    TM_GetTimeOfDay(&StopTime, 0);
+    FT_GetTimeOfDay(&StopTime, 0);
 
     VN_SET_LEN(targetptr, NewLength);
 
@@ -7536,18 +6717,18 @@ init_sys_error_to_et(void)
     sys2et[EIO] = UAEIO;
 }
 
-/* NOTE:  2006-03-01                                                     
- *  SRXAFS_CallBackRxConnAddr should be re-written as follows:           
- *  - pass back the connection, client, and host from CallPreamble       
- *  - keep a ref on the client, which we don't now                       
- *  - keep a hold on the host, which we already do                       
- *  - pass the connection, client, and host down into SAFSS_*, and use   
- *    them instead of independently discovering them via rx_ConnectionOf 
- *    (safe) and rx_GetSpecific (not so safe)                            
+/* NOTE:  2006-03-01
+ *  SRXAFS_CallBackRxConnAddr should be re-written as follows:
+ *  - pass back the connection, client, and host from CallPreamble
+ *  - keep a ref on the client, which we don't now
+ *  - keep a hold on the host, which we already do
+ *  - pass the connection, client, and host down into SAFSS_*, and use
+ *    them instead of independently discovering them via rx_ConnectionOf
+ *    (safe) and rx_GetSpecific (not so safe)
  *  The idea being that we decide what client and host we're going to use
  *  when CallPreamble is called, and stay consistent throughout the call.
- *  This change is too invasive for 1.4.1 but should be made in 1.5.x.   
- */                                                                      
+ *  This change is too invasive for 1.4.1 but should be made in 1.5.x.
+ */
 
 afs_int32
 SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
@@ -7562,10 +6743,10 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
     int i,j;
     struct rx_connection *conn;
 #endif
-    
-    if (errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &tcallhost))
+
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &tcallhost)))
            goto Bad_CallBackRxConnAddr1;
-    
+
 #ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
     errorCode = 1;
 #else
@@ -7576,34 +6757,34 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
        goto Bad_CallBackRxConnAddr;
     }
     thost = tclient->host;
-    
+
     /* nothing more can be done */
-    if ( !thost->interface ) 
+    if ( !thost->interface )
        goto Bad_CallBackRxConnAddr;
-    
+
     /* the only address is the primary interface */
     /* can't change when there's only 1 address, anyway */
-    if ( thost->interface->numberOfInterfaces <= 1 ) 
+    if ( thost->interface->numberOfInterfaces <= 1 )
        goto Bad_CallBackRxConnAddr;
-    
+
     /* initialise a security object only once */
     if ( !sc )
        sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
-    
+
     for ( i=0; i < thost->interface->numberOfInterfaces; i++)
     {
            if ( *addr == thost->interface->addr[i] ) {
                    break;
            }
     }
-    
-    if ( *addr != thost->interface->addr[i] ) 
+
+    if ( *addr != thost->interface->addr[i] )
        goto Bad_CallBackRxConnAddr;
 
     conn = rx_NewConnection (thost->interface->addr[i],
                             thost->port, 1, sc, 0);
-    rx_SetConnDeadTime(conn, 2); 
-    rx_SetConnHardDeadTime(conn, AFS_HARDDEADTIME); 
+    rx_SetConnDeadTime(conn, 2);
+    rx_SetConnHardDeadTime(conn, AFS_HARDDEADTIME);
     H_UNLOCK;
     errorCode = RXAFSCB_Probe(conn);
     H_LOCK;
@@ -7621,7 +6802,7 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
        return errorCode;
     } else {
        rx_DestroyConnection(conn);
-    }      
+    }
   Bad_CallBackRxConnAddr:
     h_ReleaseClient_r(tclient);
     /* The hold on thost will be released by CallPostamble */
@@ -7640,7 +6821,7 @@ sys_error_to_et(afs_int32 in)
        return 0;
     if (in < 0 || in > 511)
        return in;
-    if (in >= VICE_SPECIAL_ERRORS && in <= VIO || in == VRESTRICTED)
+    if ((in >= VICE_SPECIAL_ERRORS && in <= VIO) || in == VRESTRICTED)
        return in;
     if (sys2et[in] != 0)
        return sys2et[in];