viced detailed stats should record stored bytes correctly
[openafs.git] / src / viced / afsfileprocs.c
index 70c3f04..fc24577 100644 (file)
@@ -28,8 +28,6 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -47,14 +45,7 @@ RCSID
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
-
-#ifdef HAVE_STRING_H
 #include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
 
 #ifndef AFS_LINUX20_ENV
 #include <net/if.h>
@@ -196,8 +187,6 @@ struct afs_FSStats {
 
 struct afs_FSStats afs_fsstats;
 
-void ResetDebug(), SetDebug(), Terminate();
-
 int LogLevel = 0;
 int supported = 1;
 int Console = 0;
@@ -205,6 +194,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.
@@ -308,8 +299,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) {
@@ -321,6 +313,11 @@ CallPreamble(register struct rx_call *acall, int activecall,
     H_LOCK;
   retry:
     tclient = h_FindClient_r(*tconn);
+    if (!tclient) {
+       ViceLog(0, ("CallPreamble: Couldn't get CPS. Too many lockers\n"));
+       H_UNLOCK;
+       return VBUSY;
+    }
     thost = tclient->host;
     if (tclient->prfail == 1) {        /* couldn't get the CPS */
        if (!retry_flag) {
@@ -340,11 +337,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);
 
-       assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
+       if (!code)
+           assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
        H_LOCK;
 #else
        code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
@@ -420,31 +420,44 @@ CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
     struct host *thost;
     struct client *tclient;
     int translate = 0;
-    int held;
 
     H_LOCK;
     tclient = h_FindClient_r(aconn);
+    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 (%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));
+           }
+           /* return the reference taken in CallPreamble */
+           h_Release_r(ahost);
+    } else {
+           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));
     }
+
+    /* 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);
 }                              /*CallPostamble */
@@ -457,8 +470,8 @@ CallPostamble(register struct rx_connection *aconn, afs_int32 ret,
 static afs_int32
 CheckVnode(AFSFid * fid, Volume ** volptr, 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) */
@@ -467,6 +480,14 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
        extern int VInit;
 
        while (1) {
+           int restarting = 
+#ifdef AFS_DEMAND_ATTACH_FS
+               VSALVAGE
+#else
+               VRESTARTING
+#endif
+               ;
+
            errorCode = 0;
            *volptr = VGetVolume(&local_errorCode, &errorCode, (afs_int32) fid->Volume);
            if (!errorCode) {
@@ -523,25 +544,25 @@ 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++;
                        FS_UNLOCK;
                    }
-                   return (busyonrst ? VBUSY : VRESTARTING);
+                   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;
                            afs_perfstats.fs_nBusies++;
                            FS_UNLOCK;
                        }
-                       return (busyonrst ? VBUSY : VRESTARTING);
+                       return (busyonrst ? VBUSY : restarting);
                    } else {
-                       return (VRESTARTING);
+                       return (restarting);
                    }
                }
            }
@@ -549,6 +570,14 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
             * must check local_errorCode because demand attach fs
             * can have local_errorCode == VSALVAGING, errorCode == VBUSY */
            else if (local_errorCode == VBUSY && lock == READ_LOCK) {
+#ifdef AFS_DEMAND_ATTACH_FS
+               /* DAFS case is complicated by the fact that local_errorCode can
+                * be VBUSY in cases where the volume is truly offline */
+               if (!*volptr) {
+                   /* volume is in VOL_STATE_UNATTACHED */
+                   return (errorCode);
+               }
+#endif /* AFS_DEMAND_ATTACH_FS */
                errorCode = 0;
                break;
            } else if (errorCode)
@@ -590,7 +619,7 @@ SetAccessList(Vnode ** targetptr, Volume ** volume,
        assert(Fid != 0);
        while (1) {
            VnodeId parentvnode;
-           int errorCode = 0;
+           Error errorCode = 0;
 
            parentvnode = (*targetptr)->disk.parent;
            VPutVnode(&errorCode, *targetptr);
@@ -727,7 +756,7 @@ GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
 {
     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)))
        return (errorCode);
@@ -779,7 +808,7 @@ static void
 PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
                 Vnode * parentptr, Volume * volptr, struct client **client)
 {
-    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);
@@ -841,7 +870,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))
@@ -1074,8 +1103,9 @@ 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_fsize_t off, afs_fsize_t len)
 {
     Inode ino, nearInode;
     int rdlen;
@@ -1092,13 +1122,26 @@ 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;
     }
 
     ino = VN_GET_INO(targetptr);
-    assert(VALID_INO(ino));
+    if (!VALID_INO(ino)) {
+       free(buff);
+       VTakeOffline(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;
@@ -1129,6 +1172,8 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
     newFdP = IH_OPEN(newH);
     assert(newFdP != NULL);
 
+    FDH_SEEK(targFdP, off, SEEK_SET);
+    FDH_SEEK(newFdP, off, SEEK_SET);
     while (size > 0) {
        if (size > COPYBUFFSIZE) {      /* more than a buffer */
            length = COPYBUFFSIZE;
@@ -1151,7 +1196,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",
@@ -1188,6 +1233,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
                VTakeOffline(volptr);
                return EIO;
            }
+       }
 #ifndef AFS_PTHREAD_ENV
        IOMGR_Poll();
 #endif /* !AFS_PTHREAD_ENV */
@@ -1210,6 +1256,42 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr)
     return 0;                  /* success */
 }                              /*CopyOnWrite */
 
+static int
+CopyOnWrite2(FdHandle_t *targFdP, FdHandle_t *newFdP, afs_fsize_t off, afs_fsize_t size) {
+    char *buff = (char *)malloc(COPYBUFFSIZE);
+    register int length;
+    int rdlen;
+    int wrlen;
+    int rc;
+
+    FDH_SEEK(targFdP, off, SEEK_SET);
+    FDH_SEEK(newFdP, off, SEEK_SET);
+
+    if (size > FDH_SIZE(targFdP) - off) size = FDH_SIZE(targFdP) - off;
+    while (size > 0) {
+       if (size > COPYBUFFSIZE) {      /* more than a buffer */
+           length = COPYBUFFSIZE;
+           size -= COPYBUFFSIZE;
+       } else {
+           length = (int)size;
+           size = 0;
+       }
+       rdlen = FDH_READ(targFdP, buff, length);
+       if (rdlen == length)
+           wrlen = FDH_WRITE(newFdP, buff, length);
+       else
+           wrlen = 0;
+
+       if ((rdlen != length) || (wrlen != length)) {
+           /* no error recovery, at the worst we'll have a "hole" in the file */
+           rc = 1;
+           break;
+       }
+    }
+    free(buff);
+    return rc;
+}
+
 
 /*
  * Common code to handle with removing the Name (file when it's called from
@@ -1222,7 +1304,7 @@ 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;
 
     /* watch for invalid names */
@@ -1230,7 +1312,7 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
        return (EINVAL);
     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));
@@ -1265,6 +1347,9 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
       */
     if ((*targetptr)->disk.uniquifier != fileFid->Unique) {
        VTakeOffline(volptr);
+       ViceLog(0,
+               ("Volume %u now offline, must be salvaged.\n",
+                volptr->hashid));
        errorCode = VSALVAGE;
        return errorCode;
     }
@@ -1273,7 +1358,8 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
        SetDirHandle(&childdir, *targetptr);
        if (IsEmpty(&childdir) != 0)
            return (EEXIST);
-       DZap(&childdir);
+       DZap((afs_int32 *) &childdir);
+       FidZap(&childdir);
        (*targetptr)->delete = 1;
     } else if ((--(*targetptr)->disk.linkCount) == 0)
        (*targetptr)->delete = 1;
@@ -1292,10 +1378,10 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
                         errno));
                if (errno != ENOENT)
                {
+                   VTakeOffline(volptr);
                    ViceLog(0,
                            ("Volume %u now offline, must be salvaged.\n",
                             volptr->hashid));
-                   VTakeOffline(volptr);
                    return (EIO);
                }
                DT1++;
@@ -1318,10 +1404,10 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
                ("Error %d deleting %s\n", code,
                 (((*targetptr)->disk.type ==
                   Directory) ? "directory" : "file")));
+       VTakeOffline(volptr);
        ViceLog(0,
                ("Volume %u now offline, must be salvaged.\n",
                 volptr->hashid));
-       VTakeOffline(volptr);
        if (!errorCode)
            errorCode = code;
     }
@@ -1348,7 +1434,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 */
@@ -1586,8 +1672,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) {
@@ -1620,8 +1706,8 @@ 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 */
 
@@ -1629,7 +1715,7 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
         AdjustDiskUsage(volptr, BlocksPreallocatedForVnode,
                         BlocksPreallocatedForVnode))) {
        ViceLog(25,
-               ("Insufficient space to allocate %lld blocks\n",
+               ("Insufficient space to allocate %" AFS_INT64_FMT " blocks\n",
                 (afs_intmax_t) BlocksPreallocatedForVnode));
        return (errorCode);
     }
@@ -1670,7 +1756,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;
@@ -1729,7 +1815,6 @@ HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLo
                  !(rights & PRSFS_WRITE) &&
                  !(OWNSp(client, targetptr) && (rights & PRSFS_INSERT)) )
                     return(EACCES);
-            return(EACCES);
 
            if (targetptr->disk.lock.lockCount >= 0) {
                ++(targetptr->disk.lock.lockCount);
@@ -1838,8 +1923,8 @@ RXGetVolumeStatus(AFSFetchVolumeStatus * status, char **name, char **offMsg,
     status->MinQuota = V_minquota(volptr);
     status->MaxQuota = V_maxquota(volptr);
     status->BlocksInUse = V_diskused(volptr);
-    status->PartBlocksAvail = volptr->partition->free;
-    status->PartMaxBlocks = volptr->partition->totalUsable;
+    status->PartBlocksAvail = RoundInt64ToInt32(volptr->partition->free);
+    status->PartMaxBlocks = RoundInt64ToInt32(volptr->partition->totalUsable);
 
     /* now allocate and copy these things; they're freed by the RXGEN stub */
     temp = strlen(V_name(volptr)) + 1;
@@ -1911,11 +1996,19 @@ 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
@@ -2022,8 +2115,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 */
@@ -2051,7 +2144,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     ViceLog(1,
@@ -2116,7 +2209,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     /*
      * Remember when the data transfer started.
      */
-    TM_GetTimeOfDay(&xferStartTime, 0);
+    FT_GetTimeOfDay(&xferStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     /* actually do the data transfer */
@@ -2137,7 +2230,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
      * integrate the transfer size and elapsed time into the stats.  If the
      * operation failed, we jump to the appropriate point.
      */
-    TM_GetTimeOfDay(&xferStopTime, 0);
+    FT_GetTimeOfDay(&xferStopTime, 0);
     FS_LOCK;
     (xferP->numXfers)++;
     if (!errorCode) {
@@ -2219,7 +2312,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     errorCode = CallPostamble(tcon, errorCode, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -2261,10 +2354,6 @@ SRXAFS_FetchData64(struct rx_call * acall, struct AFSFid * Fid, afs_int64 Pos,
     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 */
@@ -2287,7 +2376,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 */
@@ -2308,7 +2397,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     ViceLog(1,
@@ -2371,7 +2460,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     errorCode = CallPostamble(tcon, errorCode, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -2408,7 +2497,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 */
@@ -2483,7 +2572,7 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     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 */
@@ -2504,7 +2593,7 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     ViceLog(1, ("SAFS_BulkStatus\n"));
@@ -2548,7 +2637,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? */
@@ -2596,7 +2685,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -2632,7 +2721,7 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     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 */
@@ -2654,7 +2743,7 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     ViceLog(1, ("SAFS_InlineBulkStatus\n"));
@@ -2709,7 +2798,7 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
        }
 
        /* 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? */
@@ -2764,7 +2853,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -2813,7 +2902,7 @@ SRXAFS_FetchStatus(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -2827,7 +2916,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -2861,8 +2950,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 */
@@ -2892,7 +2981,7 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(1,
            ("StoreData: Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,
             Fid->Unique));
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     FS_LOCK;
@@ -2950,7 +3039,7 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     /*
      * Remember when the data transfer started.
      */
-    TM_GetTimeOfDay(&xferStartTime, 0);
+    FT_GetTimeOfDay(&xferStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     /* Do the actual storing of the data */
@@ -2973,7 +3062,7 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
      * integrate the transfer size and elapsed time into the stats.  If the
      * operation failed, we jump to the appropriate point.
      */
-    TM_GetTimeOfDay(&xferStopTime, 0);
+    FT_GetTimeOfDay(&xferStopTime, 0);
     FS_LOCK;
     (xferP->numXfers)++;
     if (!errorCode) {
@@ -3050,7 +3139,7 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     errorCode = CallPostamble(tcon, errorCode, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -3099,10 +3188,6 @@ SRXAFS_StoreData64(struct rx_call * acall, struct AFSFid * Fid,
     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;
@@ -3127,7 +3212,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 */
@@ -3149,7 +3234,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
     if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_StoreACL;
@@ -3212,7 +3297,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
     errorCode = CallPostamble(tcon, errorCode, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -3248,7 +3333,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 */
@@ -3344,7 +3429,7 @@ SRXAFS_StoreStatus(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -3358,7 +3443,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -3396,7 +3481,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 */
@@ -3507,7 +3592,7 @@ SRXAFS_RemoveFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -3521,7 +3606,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -3561,7 +3646,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 */
@@ -3674,7 +3759,7 @@ SRXAFS_CreateFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     memset(OutFid, 0, sizeof(struct AFSFid));
@@ -3692,7 +3777,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -3733,8 +3818,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 */
@@ -3839,13 +3924,13 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
      */
     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;
     }
 
@@ -3981,6 +4066,9 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            VPutVnode(&errorCode, testvptr);
            if ((top == 1) && (testnode != 0)) {
                VTakeOffline(volptr);
+               ViceLog(0,
+                       ("Volume %u now offline, must be salvaged.\n",
+                        volptr->hashid));
                errorCode = EIO;
                goto Bad_Rename;
            }
@@ -3992,7 +4080,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
      */
     if ((fileptr->disk.type == vDirectory) && (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;
     }
 
@@ -4164,7 +4252,7 @@ SRXAFS_Rename(struct rx_call * acall, struct AFSFid * OldDirFid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -4180,7 +4268,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -4219,7 +4307,7 @@ 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 */
+    Error errorCode = 0;               /* error code */
     int len, code = 0;
     DirHandle dir;             /* Handle for dir package I/O */
     Volume *volptr = 0;                /* pointer to the volume header */
@@ -4310,10 +4398,18 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* Write the contents of the symbolic link name into the target inode */
     fdP = IH_OPEN(targetptr->handle);
-    assert(fdP != NULL);
+    if (fdP == NULL) {
+       (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+                              volptr, &client);
+       VTakeOffline(volptr);
+       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_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));
     FDH_CLOSE(fdP);
     /*
      * Set up and return modified status for the parent dir and new symlink
@@ -4341,18 +4437,15 @@ 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;
@@ -4371,7 +4464,7 @@ SRXAFS_Symlink(acall, DirFid, Name, LinkContents, InStatus, OutFid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -4387,7 +4480,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -4426,7 +4519,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 */
@@ -4496,7 +4589,7 @@ 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 */
     }
 
@@ -4572,7 +4665,7 @@ SRXAFS_Link(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -4588,7 +4681,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -4629,7 +4722,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 */
@@ -4719,7 +4812,7 @@ 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)));
+    assert(!(MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32 *)DirFid)));
     DFlush();
     VN_SET_LEN(targetptr, (afs_fsize_t) Length(&dir));
 
@@ -4773,7 +4866,7 @@ SRXAFS_MakeDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_MakeDir;
@@ -4788,7 +4881,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -4826,7 +4919,7 @@ 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 */
@@ -4936,7 +5029,7 @@ SRXAFS_RemoveDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -4950,7 +5043,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -4985,7 +5078,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 */
@@ -5068,7 +5161,7 @@ SRXAFS_SetLock(struct rx_call * acall, struct AFSFid * Fid, ViceLockType type,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -5082,7 +5175,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -5116,7 +5209,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 */
@@ -5194,7 +5287,7 @@ SRXAFS_ExtendLock(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -5208,7 +5301,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -5243,7 +5336,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 */
@@ -5330,7 +5423,7 @@ SRXAFS_ReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -5344,7 +5437,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -5377,7 +5470,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 */
 
@@ -5428,13 +5521,13 @@ SetAFSStats(struct AFSStatistics *stats)
 void
 SetVolumeStats(struct AFSStatistics *stats)
 {
-    struct DiskPartition *part;
+    struct DiskPartition64 *part;
     int i = 0;
 
     for (part = DiskPartitionList; part && i < AFS_MSTATDISKS;
         part = part->next) {
-       stats->Disks[i].TotalBlocks = part->totalUsable;
-       stats->Disks[i].BlocksAvailable = part->free;
+       stats->Disks[i].TotalBlocks = RoundInt64ToInt32(part->totalUsable);
+       stats->Disks[i].BlocksAvailable = RoundInt64ToInt32(part->free);
        memset(stats->Disks[i].Name, 0, AFS_DISKNAMESIZE);
        strncpy(stats->Disks[i].Name, part->name, AFS_DISKNAMESIZE);
        i++;
@@ -5465,7 +5558,7 @@ SRXAFS_GetStatistics(struct rx_call *acall, struct ViceStatistics *Statistics)
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
@@ -5486,7 +5579,118 @@ 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);
+    FT_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 */
+
+    osi_auditU(acall, GetStatisticsEvent, code, 
+               AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+    return code;
+}                              /*SRXAFS_GetStatistics */
+
+
+afs_int32
+SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatistics64 *Statistics)
+{
+    extern afs_int32 StartTime, CurrentConnections;
+    int seconds;
+    afs_int32 code;
+    struct rx_connection *tcon = rx_ConnectionOf(acall);
+    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 */
+
+    /*
+     * 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;
+    FT_GetTimeOfDay(&opStartTime, 0);
+#endif /* FS_STATS_DETAILED */
+
+    if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+       goto Bad_GetStatistics64;
+
+    ViceLog(1, ("SAFS_GetStatistics64 Received\n"));
+    Statistics->ViceStatistics64_val = 
+       malloc(statsVersion*sizeof(afs_int64));
+    Statistics->ViceStatistics64_len = statsVersion;
+    FS_LOCK;
+    AFSCallStats.GetStatistics++, AFSCallStats.TotalCalls++;
+    Statistics->ViceStatistics64_val[STATS64_STARTTIME] = StartTime;
+    Statistics->ViceStatistics64_val[STATS64_CURRENTCONNECTIONS] =
+       CurrentConnections;
+    Statistics->ViceStatistics64_val[STATS64_TOTALVICECALLS] = 
+       AFSCallStats.TotalCalls;
+    Statistics->ViceStatistics64_val[STATS64_TOTALFETCHES] =
+       AFSCallStats.FetchData + AFSCallStats.FetchACL +
+       AFSCallStats.FetchStatus;
+    Statistics->ViceStatistics64_val[STATS64_FETCHDATAS] = 
+       AFSCallStats.FetchData;
+    Statistics->ViceStatistics64_val[STATS64_FETCHEDBYTES] = 
+       AFSCallStats.TotalFetchedBytes;
+    seconds = AFSCallStats.AccumFetchTime / 1000;
+    if (seconds <= 0)
+        seconds = 1;
+    Statistics->ViceStatistics64_val[STATS64_FETCHDATARATE] = 
+       AFSCallStats.TotalFetchedBytes / seconds;
+    Statistics->ViceStatistics64_val[STATS64_TOTALSTORES] =
+        AFSCallStats.StoreData + AFSCallStats.StoreACL +
+        AFSCallStats.StoreStatus;
+    Statistics->ViceStatistics64_val[STATS64_STOREDATAS] = 
+       AFSCallStats.StoreData;
+    Statistics->ViceStatistics64_val[STATS64_STOREDBYTES] = 
+       AFSCallStats.TotalStoredBytes;
+    seconds = AFSCallStats.AccumStoreTime / 1000;
+    if (seconds <= 0)
+        seconds = 1;
+    Statistics->ViceStatistics64_val[STATS64_STOREDATARATE] = 
+       AFSCallStats.TotalStoredBytes / seconds;
+#ifdef AFS_NT40_ENV
+    Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] = -1;
+#else
+    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));
+
+
+
+    /* this works on all system types */
+    FT_GetTimeOfDay(&time, 0);
+    Statistics->ViceStatistics64_val[STATS64_CURRENTTIME] = time.tv_sec;
+
+  Bad_GetStatistics64:
+    code = CallPostamble(tcon, code, thost);
+
+    t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
+
+#if FS_STATS_DETAILED
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -5548,7 +5752,7 @@ SRXAFS_XStatsVersion(struct rx_call * a_call, afs_int32 * a_versionP)
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     *a_versionP = AFS_XSTAT_VERSION;
@@ -5556,7 +5760,7 @@ SRXAFS_XStatsVersion(struct rx_call * a_call, afs_int32 * a_versionP)
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
     fs_stats_AddTo((opP->sumTime), elapsedTime);
     fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
@@ -5752,7 +5956,7 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     /*
@@ -5895,7 +6099,7 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
     }                          /*Switch on collection number */
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -5940,7 +6144,7 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if (FidArray)
@@ -5960,7 +6164,9 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
                 (tcon->peer ? tcon->peer->host : 0)));
        errorCode = GetClient(tcon, &client);
        if (!errorCode) {
+           H_LOCK;
            DeleteAllCallBacks_r(client->host, 1);
+           H_UNLOCK;
            PutClient(&client);
        }
     } else {
@@ -5987,7 +6193,7 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
     errorCode = CallPostamble(tcon, errorCode, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -6054,7 +6260,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;
@@ -6067,9 +6273,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)
+#if defined(AFS_64BIT_ENV)
     dataBuffP[0] |= VICED_CAPABILITY_64BITFILES;
 #endif
     if (saneacls)
@@ -6093,9 +6299,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;
@@ -6285,7 +6490,7 @@ SRXAFS_GetVolumeInfo(struct rx_call * acall, char *avolid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
        goto Bad_GetVolumeInfo;
@@ -6304,7 +6509,7 @@ SRXAFS_GetVolumeInfo(struct rx_call * acall, char *avolid,
     code = CallPostamble(tcon, code, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -6333,7 +6538,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 */
@@ -6355,7 +6560,7 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
@@ -6406,7 +6611,7 @@ 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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -6438,7 +6643,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 */
@@ -6460,7 +6665,7 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
@@ -6504,7 +6709,7 @@ SRXAFS_SetVolumeStatus(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);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -6538,8 +6743,8 @@ 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 */
@@ -6556,7 +6761,7 @@ SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     return FSERR_EOPNOTSUPP;
@@ -6594,7 +6799,7 @@ SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
     errorCode = CallPostamble(tcon, errorCode, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (errorCode == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -6638,7 +6843,7 @@ SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
@@ -6650,7 +6855,7 @@ SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
     code = CallPostamble(tcon, code, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     if (code == 0) {
        FS_LOCK;
        (opP->numSuccesses)++;
@@ -6692,7 +6897,7 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
     FS_LOCK;
     (opP->numOps)++;
     FS_UNLOCK;
-    TM_GetTimeOfDay(&opStartTime, 0);
+    FT_GetTimeOfDay(&opStartTime, 0);
 #endif /* FS_STATS_DETAILED */
 
     if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
@@ -6701,7 +6906,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;
 
@@ -6711,7 +6916,7 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
     code = CallPostamble(tcon, code, thost);
 
 #if FS_STATS_DETAILED
-    TM_GetTimeOfDay(&opStopTime, 0);
+    FT_GetTimeOfDay(&opStopTime, 0);
     fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
     if (code == 0) {
        FS_LOCK;
@@ -6764,7 +6969,7 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     )
 {
     struct timeval StartTime, StopTime;        /* used to calculate file  transfer rates */
-    int errorCode = 0;         /* Returned error code to caller */
+    Error errorCode = 0;               /* Returned error code to caller */
     IHandle_t *ihP;
     FdHandle_t *fdP;
 #ifdef AFS_NT40_ENV
@@ -6800,11 +7005,13 @@ 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) {
        VTakeOffline(volptr);
+       ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+                   volptr->hashid));
        return EIO;
     }
     optSize = sendBufSize;
@@ -6814,14 +7021,17 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     if (tlen < 0) {
        FDH_CLOSE(fdP);
        VTakeOffline(volptr);
+       ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+                   volptr->hashid));
        return EIO;
     }
     if (Pos > tlen) {
        Len = 0;
     }
 
-    if (Pos + Len > tlen)
-       Len = tlen - Pos;       /* get length we should send */
+    if (Pos + Len > tlen) /* get length we should send */
+       Len = ((tlen - Pos) < 0) ? 0 : tlen - Pos;
+
     (void)FDH_SEEK(fdP, Pos, 0);
     {
        afs_int32 high, low;
@@ -6852,6 +7062,8 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
            FDH_CLOSE(fdP);
            FreeSendBuffer((struct afs_buffer *)tbuffer);
            VTakeOffline(volptr);
+           ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+                       volptr->hashid));
            return EIO;
        }
        errorCode = rx_Write(Call, tbuffer, wlen);
@@ -6866,6 +7078,8 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
        if (errorCode != 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);
@@ -6890,7 +7104,7 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     FreeSendBuffer((struct afs_buffer *)tbuffer);
 #endif /* AFS_NT40_ENV */
     FDH_CLOSE(fdP);
-    TM_GetTimeOfDay(&StopTime, 0);
+    FT_GetTimeOfDay(&StopTime, 0);
 
     /* Adjust all Fetch Data related stats */
     FS_LOCK;
@@ -6982,7 +7196,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
 {
     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 */
+    Error errorCode = 0;               /* Returned error code to caller */
 #ifdef AFS_NT40_ENV
     register char *tbuffer;    /* data copying buffer */
 #else /* AFS_NT40_ENV */
@@ -6992,12 +7206,13 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     afs_sfsize_t tlen;         /* temp for xfr length */
     Inode tinode;              /* inode for I/O */
     afs_int32 optSize;         /* optimal transfer size */
-    afs_sfsize_t DataLength;   /* size of inode */
+    afs_sfsize_t DataLength = 0;       /* size of inode */
     afs_sfsize_t TruncatedLength;      /* size after ftruncate */
     afs_fsize_t NewLength;     /* size after this store completes */
     afs_sfsize_t adjustSize;   /* bytes to call VAdjust... with */
-    int linkCount;             /* link count on inode */
-    FdHandle_t *fdP;
+    int linkCount = 0;         /* link count on inode */
+    afs_fsize_t CoW_off, CoW_len;
+    FdHandle_t *fdP, *origfdP = NULL;
     struct in_addr logHostAddr;        /* host ip holder for inet_ntoa */
 
 #if FS_STATS_DETAILED
@@ -7038,6 +7253,8 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
        if (GetLinkCountAndSize(volptr, fdP, &linkCount, &DataLength) < 0) {
            FDH_CLOSE(fdP);
            VTakeOffline(volptr);
+           ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+                       volptr->hashid));
            return EIO;
        }
 
@@ -7054,20 +7271,29 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
             * mechanisms (i.e. copy on write overhead.) Also the right size
             * of the disk will be recorded...
             */
-           FDH_CLOSE(fdP);
+           origfdP = fdP;
            VN_GET_LEN(size, targetptr);
            volptr->partition->flags &= ~PART_DONTUPDATE;
            VSetPartitionDiskUsage(volptr->partition);
            volptr->partition->flags |= PART_DONTUPDATE;
            if ((errorCode = VDiskUsage(volptr, nBlocks(size)))) {
                volptr->partition->flags &= ~PART_DONTUPDATE;
+               FDH_CLOSE(origfdP);
                return (errorCode);
            }
 
-           ViceLog(25, ("StoreData : calling CopyOnWrite on  target dir\n"));
-           if ((errorCode = CopyOnWrite(targetptr, volptr))) {
+           CoW_len = (FileLength >= (Length + Pos)) ? FileLength - Length : Pos;
+           CopyOnWrite_calls++;
+           if (CoW_len == 0) CopyOnWrite_size0++;
+           if (Pos == 0) CopyOnWrite_off0++;
+           if (CoW_len > CopyOnWrite_maxsize) CopyOnWrite_maxsize = CoW_len;
+
+           ViceLog(1, ("StoreData : calling CopyOnWrite on vnode %lu.%lu (%s) off 0x%llx size 0x%llx\n",
+                       V_id(volptr), targetptr->vnodeNumber, V_name(volptr), 0, Pos));
+           if ((errorCode = CopyOnWrite(targetptr, volptr, 0, Pos))) {
                ViceLog(25, ("StoreData : CopyOnWrite failed\n"));
                volptr->partition->flags &= ~PART_DONTUPDATE;
+               FDH_CLOSE(origfdP);
                return (errorCode);
            }
            volptr->partition->flags &= ~PART_DONTUPDATE;
@@ -7076,12 +7302,18 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
            if (fdP == NULL) {
                ViceLog(25,
                        ("StoreData : Reopen after CopyOnWrite failed\n"));
+               FDH_CLOSE(origfdP);
                return ENOENT;
            }
        }
        tinode = VN_GET_INO(targetptr);
     }
-    assert(VALID_INO(tinode));
+    if (!VALID_INO(tinode)) {
+       VTakeOffline(volptr);
+       ViceLog(0,("Volume %u now offline, must be salvaged.\n",
+                  volptr->hashid));
+       return EIO;
+    }
 
     /* compute new file length */
     NewLength = DataLength;
@@ -7102,6 +7334,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
         AdjustDiskUsage(volptr, adjustSize,
                         adjustSize - SpareComp(volptr)))) {
        FDH_CLOSE(fdP);
+       if (origfdP) FDH_CLOSE(origfdP);
        return (errorCode);
     }
 
@@ -7109,7 +7342,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,
@@ -7162,13 +7395,13 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
 #else /* AFS_NT40_ENV */
            errorCode = rx_Readv(Call, tiov, &tnio, RX_MAXIOVECS, rlen);
 #endif /* AFS_NT40_ENV */
-#if FS_STATS_DETAILED
-           (*a_bytesStoredP) += errorCode;
-#endif /* FS_STATS_DETAILED */
            if (errorCode <= 0) {
                errorCode = -32;
                break;
            }
+#if FS_STATS_DETAILED
+           (*a_bytesStoredP) += errorCode;
+#endif /* FS_STATS_DETAILED */
            rlen = errorCode;
 #ifdef AFS_NT40_ENV
            errorCode = FDH_WRITE(fdP, tbuffer, rlen);
@@ -7197,6 +7430,9 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
         * need to update the target vnode.
         */
        targetptr->changed_newTime = 1;
+       if (origfdP && (bytesTransfered < Length))      /* Need to "finish" CopyOnWrite still */
+           CopyOnWrite2(origfdP, fdP, Pos + bytesTransfered, NewLength - Pos - bytesTransfered);
+       if (origfdP) FDH_CLOSE(origfdP);
        FDH_CLOSE(fdP);
        /* set disk usage to be correct */
        VAdjustDiskUsage(&errorCode, volptr,
@@ -7204,9 +7440,17 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
                                         nBlocks(NewLength)), 0);
        return errorCode;
     }
+    if (origfdP) {                                     /* finish CopyOnWrite */
+       if ( (CoW_off = Pos + Length) < NewLength) {
+           errorCode = CopyOnWrite2(origfdP, fdP, CoW_off, CoW_len = NewLength - CoW_off);
+           ViceLog(1, ("StoreData : CopyOnWrite2 on vnode %lu.%lu (%s) off 0x%llx size 0x%llx returns %d\n",
+                        V_id(volptr), targetptr->vnodeNumber, V_name(volptr), CoW_off, CoW_len, errorCode));
+       }
+       FDH_CLOSE(origfdP);
+    }
     FDH_CLOSE(fdP);
 
-    TM_GetTimeOfDay(&StopTime, 0);
+    FT_GetTimeOfDay(&StopTime, 0);
 
     VN_SET_LEN(targetptr, NewLength);
 
@@ -7397,7 +7641,7 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
     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
@@ -7405,17 +7649,19 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
 #else
     H_LOCK;
     tclient = h_FindClient_r(tcon);
+    if (!tclient) {
+       errorCode = VBUSY;
+       goto Bad_CallBackRxConnAddr;
+    }
     thost = tclient->host;
     
     /* nothing more can be done */
     if ( !thost->interface ) 
        goto Bad_CallBackRxConnAddr;
     
-    assert(thost->interface->numberOfInterfaces > 0 );
-    
     /* 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 */
@@ -7472,7 +7718,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];