vol: Use FDH_SIZE more consistently
[openafs.git] / src / viced / afsfileprocs.c
index 31aa5b8..0ac27e9 100644 (file)
 #endif
 #endif /* AFS_HPUX_ENV */
 
-#include <rx/xdr.h>
+#include <afs/opr.h>
+#include <rx/rx_queue.h>
+#include <opr/lock.h>
+#include <opr/proc.h>
 #include <afs/nfs.h>
-#include <lwp.h>
-#include <lock.h>
 #include <afs/afsint.h>
 #include <afs/vldbint.h>
 #include <afs/errors.h>
@@ -150,6 +151,13 @@ pthread_mutex_t fileproc_glock_mutex;
 
 #define CREATE_SGUID_ADMIN_ONLY 1
 
+
+/**
+ * Abort the fileserver on fatal errors returned from vnode operations.
+ */
+#define assert_vnode_success_or_salvaging(code) \
+    opr_Assert((code) == 0 || (code) == VSALVAGE || (code) == VSALVAGING)
+
 extern struct afsconf_dir *confDir;
 extern afs_int32 dataVersionHigh;
 
@@ -165,13 +173,13 @@ struct afs_FSStats {
 
 struct afs_FSStats afs_fsstats;
 
-int LogLevel = 0;
 int supported = 1;
 int Console = 0;
 afs_int32 BlocksSpare = 1024;  /* allow 1 MB overruns */
 afs_int32 PctSpare;
 extern afs_int32 implicitAdminRights;
 extern afs_int32 readonlyServer;
+extern afs_int32 adminwriteServer;
 extern int CopyOnWrite_calls, CopyOnWrite_off0, CopyOnWrite_size0;
 extern afs_fsize_t CopyOnWrite_maxsize;
 
@@ -245,7 +253,7 @@ SetVolumeSync(struct AFSVolSync *async, Volume * avol)
     /* date volume instance was created */
     if (async) {
        if (avol)
-           async->spare1 = avol->header->diskstuff.creationDate;
+           async->spare1 = V_creationDate(avol);
        else
            async->spare1 = 0;
        async->spare2 = 0;
@@ -283,8 +291,8 @@ CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
 
        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),
+           ViceLog(0, ("CheckLength: cannot open inode for fid %" AFS_VOLID_FMT ".%lu.%lu\n",
+                       afs_printable_VolumeId_lu(vp->hashid),
                        afs_printable_uint32_lu(Vn_id(vnp)),
                        afs_printable_uint32_lu(vnp->disk.uniquifier)));
            return -1;
@@ -293,9 +301,9 @@ CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
        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),
+           ViceLog(0, ("CheckLength: cannot get size for inode for fid %"
+                       AFS_VOLID_FMT ".%lu.%lu; FDH_SIZE returned %" AFS_INT64_FMT "\n",
+                       afs_printable_VolumeId_lu(vp->hashid),
                        afs_printable_uint32_lu(Vn_id(vnp)),
                        afs_printable_uint32_lu(vnp->disk.uniquifier),
                        alen64));
@@ -305,9 +313,9 @@ CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
 
     if (alen != vlen) {
        afs_int64 alen64 = alen, vlen64 = vlen;
-       ViceLog(0, ("Fid %lu.%lu.%lu has inconsistent length (index "
+       ViceLog(0, ("Fid %" AFS_VOLID_FMT ".%lu.%lu has inconsistent length (index "
                    "%lld inode %lld ); volume must be salvaged\n",
-                   afs_printable_uint32_lu(vp->hashid),
+                   afs_printable_VolumeId_lu(vp->hashid),
                    afs_printable_uint32_lu(Vn_id(vnp)),
                    afs_printable_uint32_lu(vnp->disk.uniquifier),
                    vlen64, alen64));
@@ -316,17 +324,44 @@ CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
     return 0;
 }
 
+static void
+LogClientError(const char *message, struct rx_connection *tcon, afs_int32 viceid, struct AFSFid *Fid)
+{
+    char hoststr[16];
+    if (Fid) {
+       ViceLog(0, ("%s while handling request from host %s:%d viceid %d "
+                   "fid %" AFS_VOLID_FMT ".%lu.%lu, failing request\n",
+                   message,
+                   afs_inet_ntoa_r(rx_HostOf(rx_PeerOf(tcon)), hoststr),
+                   (int)ntohs(rx_PortOf(rx_PeerOf(tcon))),
+                   viceid,
+                   afs_printable_VolumeId_lu(Fid->Volume),
+                   afs_printable_uint32_lu(Fid->Vnode),
+                   afs_printable_uint32_lu(Fid->Unique)));
+    } else {
+       ViceLog(0, ("%s while handling request from host %s:%d viceid %d "
+                   "fid (none), failing request\n",
+                   message,
+                   afs_inet_ntoa_r(rx_HostOf(rx_PeerOf(tcon)), hoststr),
+                   (int)ntohs(rx_PortOf(rx_PeerOf(tcon))),
+                   viceid));
+    }
+}
+
 /*
  * 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
+ *
+ * 'Fid' is optional, and is just used for printing log messages.
  */
 static int
-CallPreamble(struct rx_call *acall, int activecall,
+CallPreamble(struct rx_call *acall, int activecall, struct AFSFid *Fid,
             struct rx_connection **tconn, struct host **ahostp)
 {
     struct host *thost;
     struct client *tclient;
+    afs_int32 viceid = -1;
     int retry_flag = 1;
     int code = 0;
     char hoststr[16], hoststr2[16];
@@ -341,19 +376,19 @@ CallPreamble(struct rx_call *acall, int activecall,
 
     H_LOCK;
   retry:
-    tclient = h_FindClient_r(*tconn);
+    tclient = h_FindClient_r(*tconn, &viceid);
     if (!tclient) {
-       ViceLog(0, ("CallPreamble: Couldn't get client.\n"));
        H_UNLOCK;
+       LogClientError("CallPreamble: Couldn't get client", *tconn, viceid, Fid);
        return VBUSY;
     }
-    thost = tclient->host;
-    if (tclient->prfail == 1) {        /* couldn't get the CPS */
+    thost = tclient->z.host;
+    if (tclient->z.prfail == 1) {      /* couldn't get the CPS */
        if (!retry_flag) {
            h_ReleaseClient_r(tclient);
            h_Release_r(thost);
-           ViceLog(0, ("CallPreamble: Couldn't get CPS. Fail\n"));
            H_UNLOCK;
+           LogClientError("CallPreamble: Couldn't get CPS", *tconn, viceid, Fid);
            return -1001;
        }
        retry_flag = 0;         /* Retry once */
@@ -372,55 +407,56 @@ CallPreamble(struct rx_call *acall, int activecall,
        code = hpr_Initialize(&uclient);
 
        if (!code)
-           osi_Assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
+           opr_Verify(pthread_setspecific(viced_uclient_key,
+                                          (void *)uclient) == 0);
        H_LOCK;
 
        if (code) {
            h_ReleaseClient_r(tclient);
            h_Release_r(thost);
            H_UNLOCK;
-           ViceLog(0, ("CallPreamble: couldn't reconnect to ptserver\n"));
+           LogClientError("CallPreamble: couldn't reconnect to ptserver", *tconn, viceid, Fid);
            return -1001;
        }
 
-       tclient->prfail = 2;    /* Means re-eval client's cps */
+       tclient->z.prfail = 2;  /* Means re-eval client's cps */
        h_ReleaseClient_r(tclient);
        h_Release_r(thost);
        goto retry;
     }
 
-    tclient->LastCall = thost->LastCall = FT_ApproxTime();
+    tclient->z.LastCall = thost->z.LastCall = time(NULL);
     if (activecall)            /* For all but "GetTime", "GetStats", and "GetCaps" calls */
-       thost->ActiveCall = thost->LastCall;
+       thost->z.ActiveCall = thost->z.LastCall;
 
     h_Lock_r(thost);
-    if (thost->hostFlags & HOSTDELETED) {
+    if (thost->z.hostFlags & HOSTDELETED) {
        ViceLog(3,
                ("Discarded a packet for deleted host %s:%d\n",
-                afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port)));
+                afs_inet_ntoa_r(thost->z.host, hoststr), ntohs(thost->z.port)));
        code = VBUSY;           /* raced, so retry */
-    } else if ((thost->hostFlags & VENUSDOWN)
-              || (thost->hostFlags & HFE_LATER)) {
+    } else if ((thost->z.hostFlags & VENUSDOWN)
+              || (thost->z.hostFlags & HFE_LATER)) {
        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->z.host, hoststr), ntohs(thost->z.port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
                     ntohs(rxr_PortOf(*tconn))));
            if (MultiProbeAlternateAddress_r(thost)) {
                ViceLog(0,
                        ("MultiProbe failed to find new address for host %s:%d\n",
-                        afs_inet_ntoa_r(thost->host, hoststr),
-                        ntohs(thost->port)));
+                        afs_inet_ntoa_r(thost->z.host, hoststr),
+                        ntohs(thost->z.port)));
                code = -1;
            } else {
                ViceLog(0,
                        ("MultiProbe found new address for host %s:%d\n",
-                        afs_inet_ntoa_r(thost->host, hoststr),
-                        ntohs(thost->port)));
+                        afs_inet_ntoa_r(thost->z.host, hoststr),
+                        ntohs(thost->z.port)));
                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->z.host, hoststr), ntohs(thost->z.port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
                              ntohs(rxr_PortOf(*tconn))));
                    code = -1;
                }
@@ -448,11 +484,11 @@ CallPostamble(struct rx_connection *aconn, afs_int32 ret,
     int translate = 0;
 
     H_LOCK;
-    tclient = h_FindClient_r(aconn);
+    tclient = h_FindClient_r(aconn, NULL);
     if (!tclient)
        goto busyout;
-    thost = tclient->host;
-    if (thost->hostFlags & HERRORTRANS)
+    thost = tclient->z.host;
+    if (thost->z.hostFlags & HERRORTRANS)
        translate = 1;
     h_ReleaseClient_r(tclient);
 
@@ -462,11 +498,11 @@ CallPostamble(struct rx_connection *aconn, afs_int32 ret,
                    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),
+                               afs_inet_ntoa_r(ahost->z.host, hoststr),
+                               ntohs(ahost->z.port),
                                ahost,
-                               afs_inet_ntoa_r(thost->host, hoststr2),
-                               ntohs(thost->port),
+                               afs_inet_ntoa_r(thost->z.host, hoststr2),
+                               ntohs(thost->z.port),
                                thost));
            }
            /* return the reference taken in CallPreamble */
@@ -474,13 +510,13 @@ CallPostamble(struct rx_connection *aconn, afs_int32 ret,
     } 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),
+                       afs_inet_ntoa_r(thost->z.host, hoststr),
+                       ntohs(thost->z.port),
                        thost));
     }
 
     /* return the reference taken in local h_FindClient_r--h_ReleaseClient_r
-     * does not decrement refcount on client->host */
+     * does not decrement refcount on client->z.host */
     h_Release_r(thost);
 
  busyout:
@@ -521,7 +557,7 @@ CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
            *volptr = VGetVolumeWithCall(&local_errorCode, &errorCode,
                                               fid->Volume, ts, cbv);
            if (!errorCode) {
-               osi_Assert(*volptr);
+               opr_Assert(*volptr);
                break;
            }
            if ((errorCode == VOFFLINE) && (VInit < 2)) {
@@ -574,7 +610,7 @@ CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
                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. */
-                   FT_GetTimeOfDay(&restartedat, 0);
+                   gettimeofday(&restartedat, 0);
                    if (busyonrst) {
                        FS_LOCK;
                        afs_perfstats.fs_nBusies++;
@@ -583,7 +619,7 @@ CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
                    return (busyonrst ? VBUSY : restarting);
                } else {
                    struct timeval now;
-                   FT_GetTimeOfDay(&now, 0);
+                   gettimeofday(&now, 0);
                    if ((now.tv_sec - restartedat.tv_sec) < (11 * 60)) {
                        if (busyonrst) {
                            FS_LOCK;
@@ -614,7 +650,7 @@ CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
                return (errorCode);
        }
     }
-    osi_Assert(*volptr);
+    opr_Assert(*volptr);
 
     /* get the vnode  */
     *vptr = VGetVnode(&errorCode, *volptr, fid->Vnode, lock);
@@ -622,7 +658,7 @@ CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
        return (errorCode);
     if ((*vptr)->disk.uniquifier != fid->Unique) {
        VPutVnode(&fileCode, *vptr);
-       osi_Assert(fileCode == 0);
+       assert_vnode_success_or_salvaging(fileCode);
        *vptr = 0;
        return (VNOVNODE);      /* return the right error code, at least */
     }
@@ -652,7 +688,7 @@ SetAccessList(Vnode ** targetptr, Volume ** volume,
        *ACLSize = VAclSize(*targetptr);
        return (0);
     } else {
-       osi_Assert(Fid != 0);
+       opr_Assert(Fid != 0);
        while (1) {
            VnodeId parentvnode;
            Error errorCode = 0;
@@ -688,9 +724,9 @@ client_CheckRights(struct client *client, struct acl_accessList *ACL,
 {
     *rights = 0;
     ObtainReadLock(&client->lock);
-    if (client->CPS.prlist_len > 0 && !client->deleted &&
-       client->host && !(client->host->hostFlags & HOSTDELETED))
-       acl_CheckRights(ACL, &client->CPS, rights);
+    if (client->z.CPS.prlist_len > 0 && !client->z.deleted &&
+       client->z.host && !(client->z.host->z.hostFlags & HOSTDELETED))
+       acl_CheckRights(ACL, &client->z.CPS, rights);
     ReleaseReadLock(&client->lock);
 }
 
@@ -701,9 +737,9 @@ client_HasAsMember(struct client *client, afs_int32 id)
     afs_int32 code = 0;
 
     ObtainReadLock(&client->lock);
-    if (client->CPS.prlist_len > 0 && !client->deleted &&
-       client->host && !(client->host->hostFlags & HOSTDELETED))
-       code = acl_IsAMember(id, &client->CPS);
+    if (client->z.CPS.prlist_len > 0 && !client->z.deleted &&
+       client->z.host && !(client->z.host->z.hostFlags & HOSTDELETED))
+       code = acl_IsAMember(id, &client->z.CPS);
     ReleaseReadLock(&client->lock);
     return code;
 }
@@ -730,20 +766,20 @@ GetRights(struct client *client, struct acl_accessList *ACL,
 
     /* wait if somebody else is already doing the getCPS call */
     H_LOCK;
-    while (client->host->hostFlags & HCPS_INPROGRESS) {
-       client->host->hostFlags |= HCPS_WAITING;        /* I am waiting */
-       CV_WAIT(&client->host->cond, &host_glock_mutex);
+    while (client->z.host->z.hostFlags & HCPS_INPROGRESS) {
+       client->z.host->z.hostFlags |= HCPS_WAITING;    /* I am waiting */
+       opr_cv_wait(&client->z.host->cond, &host_glock_mutex);
     }
 
-    if (!client->host->hcps.prlist_len || !client->host->hcps.prlist_val) {
+    if (!client->z.host->z.hcps.prlist_len || !client->z.host->z.hcps.prlist_val) {
        char hoststr[16];
        ViceLog(5,
                ("CheckRights: len=%u, for host=%s:%d\n",
-                client->host->hcps.prlist_len,
-                afs_inet_ntoa_r(client->host->host, hoststr),
-                ntohs(client->host->port)));
+                client->z.host->z.hcps.prlist_len,
+                afs_inet_ntoa_r(client->z.host->z.host, hoststr),
+                ntohs(client->z.host->z.port)));
     } else
-       acl_CheckRights(ACL, &client->host->hcps, &hrights);
+       acl_CheckRights(ACL, &client->z.host->z.hcps, &hrights);
     H_UNLOCK;
     /* Allow system:admin the rights given with the -implicit option */
     if (client_HasAsMember(client, SystemId))
@@ -810,13 +846,11 @@ GetVolumePackageWithCall(struct rx_call *acall, struct VCallByVol *cbv,
                         struct client **client, int locktype,
                         afs_int32 * rights, afs_int32 * anyrights, int remote)
 {
-    struct acl_accessList *aCL;        /* Internal access List */
+    struct acl_accessList *aCL = NULL; /* Internal access List */
     int aCLSize;               /* size of the access list */
     Error errorCode = 0;               /* return code to caller */
     struct rx_connection *tcon = rx_ConnectionOf(acall);
 
-    rx_KeepAliveOff(acall);
-
     if ((errorCode = CheckVnodeWithCall(Fid, volptr, cbv, targetptr, locktype)))
        goto gvpdone;
 
@@ -843,19 +877,20 @@ GetVolumePackageWithCall(struct rx_call *acall, struct VCallByVol *cbv,
                (chkforDir == MustBeDIR ? 0 : locktype))) != 0)
            goto gvpdone;
        if (chkforDir == MustBeDIR)
-           osi_Assert((*parent) == 0);
+           opr_Assert((*parent) == 0);
        if (!(*client)) {
            if ((errorCode = GetClient(tcon, client)) != 0)
                goto gvpdone;
-           if (!(*client))
+           if (!(*client)) {
                errorCode = EINVAL;
                goto gvpdone;
+           }
        }
        GetRights(*client, aCL, rights, anyrights);
        /* ok, if this is not a dir, set the PRSFS_ADMINISTER bit iff we're the owner */
        if ((*targetptr)->disk.type != vDirectory) {
            /* anyuser can't be owner, so only have to worry about rights, not anyrights */
-           if ((*targetptr)->disk.owner == (*client)->ViceId)
+           if ((*targetptr)->disk.owner == (*client)->z.ViceId)
                (*rights) |= PRSFS_ADMINISTER;
            else
                (*rights) &= ~PRSFS_ADMINISTER;
@@ -865,10 +900,8 @@ GetVolumePackageWithCall(struct rx_call *acall, struct VCallByVol *cbv,
        if (!VanillaUser(*client))
            (*rights) |= PRSFS_LOOKUP;
 #endif /* ADMIN_IMPLICIT_LOOKUP */
-gvpdone:
-    if (errorCode)
-       rx_KeepAliveOn(acall);
     }
+gvpdone:
     return errorCode;
 
 }                              /*GetVolumePackage */
@@ -920,23 +953,21 @@ PutVolumePackageWithCall(struct rx_call *acall, Vnode *
 {
     Error fileCode = 0;                /* Error code returned by the volume package */
 
-    rx_KeepAliveOff(acall);
     if (parentwhentargetnotdir) {
        VPutVnode(&fileCode, parentwhentargetnotdir);
-       osi_Assert(!fileCode || (fileCode == VSALVAGE));
+       assert_vnode_success_or_salvaging(fileCode);
     }
     if (targetptr) {
        VPutVnode(&fileCode, targetptr);
-       osi_Assert(!fileCode || (fileCode == VSALVAGE));
+       assert_vnode_success_or_salvaging(fileCode);
     }
     if (parentptr) {
        VPutVnode(&fileCode, parentptr);
-       osi_Assert(!fileCode || (fileCode == VSALVAGE));
+       assert_vnode_success_or_salvaging(fileCode);
     }
     if (volptr) {
        VPutVolumeWithCall(volptr, cbv);
     }
-    rx_KeepAliveOn(acall);
 
     if (*client) {
        PutClient(client);
@@ -958,7 +989,7 @@ VolumeOwner(struct client *client, Vnode * targetptr)
     afs_int32 owner = V_owner(targetptr->volumePtr);   /* get volume owner */
 
     if (owner >= 0)
-       return (client->ViceId == owner);
+       return (client->z.ViceId == owner);
     else {
        /*
         * We don't have to check for host's cps since only regular
@@ -977,6 +1008,30 @@ VolumeRootVnode(Vnode * targetptr)
 
 }                              /*VolumeRootVnode */
 
+/**
+ * Check if server can perform writes.
+ *
+ * This functions checks if the fileserver is read-only for the client received
+ * as an argument. Read-only fileservers allow write requests for members of
+ * system:administrators when started with both -readonly and -admin-write.
+ *
+ * @param[in]  client  calling user
+ *
+ * @return 1 if not read-only for this user; 0 otherwise
+ */
+static int
+IsWriteAllowed(struct client *client)
+{
+    if (readonlyServer) {
+       if (adminwriteServer && !VanillaUser(client)) {
+           /* admins can write */
+           return 1;
+       }
+       return 0;
+    }
+    return 1;
+}
+
 /*
  * Check if target file has the proper access permissions for the Fetch
  * (FetchData, FetchACL, FetchStatus) and Store (StoreData, StoreACL,
@@ -993,7 +1048,7 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
                       AFSStoreStatus * InStatus)
 {
     Error errorCode = 0;
-#define OWNSp(client, target) ((client)->ViceId == (target)->disk.owner)
+#define OWNSp(client, target) ((client)->z.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))
 
@@ -1012,7 +1067,7 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
                /* must have read access, or be owner and have insert access */
                if (!(rights & PRSFS_READ)
                    && !((OWNSp(client, targetptr) && (rights & PRSFS_INSERT)
-                         && (client->ViceId != AnonymousID))))
+                         && (client->z.ViceId != AnonymousID))))
                    return (EACCES);
            }
            if (CallingRoutine == CHK_FETCHDATA
@@ -1034,7 +1089,7 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
                 * reading of files created with no read permission. The owner
                 * of the file is always allowed to read it.
                 */
-               if ((client->ViceId != targetptr->disk.owner)
+               if ((client->z.ViceId != targetptr->disk.owner)
                    && VanillaUser(client))
                    errorCode =
                        (((OWNERREAD | OWNEREXEC) & targetptr->disk.
@@ -1043,10 +1098,13 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
        } else {                /*  !VanillaUser(client) && !FetchData */
 
            osi_audit(PrivilegeEvent, 0, AUD_ID,
-                     (client ? client->ViceId : 0), AUD_INT, CallingRoutine,
+                     (client ? client->z.ViceId : 0), AUD_INT, CallingRoutine,
                      AUD_END);
        }
     } else {                   /* a store operation */
+       if (!IsWriteAllowed(client)) {
+           return (VREADONLY);
+       }
        if ((rights & PRSFS_INSERT) && OWNSp(client, targetptr)
            && (CallingRoutine != CHK_STOREACL)
            && (targetptr->disk.type == vFile)) {
@@ -1055,24 +1113,19 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
             * unless you are a system administrator */
          /******  InStatus->Owner && UnixModeBits better be SET!! */
            if (CHOWN(InStatus, targetptr) || CHGRP(InStatus, targetptr)) {
-               if (readonlyServer)
-                   return (VREADONLY);
-               else if (VanillaUser(client))
+               if (VanillaUser(client))
                    return (EPERM);     /* Was EACCES */
                else
                    osi_audit(PrivilegeEvent, 0, AUD_ID,
-                             (client ? client->ViceId : 0), AUD_INT,
+                             (client ? client->z.ViceId : 0), AUD_INT,
                              CallingRoutine, AUD_END);
            }
        } else {
            if (CallingRoutine != CHK_STOREDATA && !VanillaUser(client)) {
                osi_audit(PrivilegeEvent, 0, AUD_ID,
-                         (client ? client->ViceId : 0), AUD_INT,
+                         (client ? client->z.ViceId : 0), AUD_INT,
                          CallingRoutine, AUD_END);
            } else {
-               if (readonlyServer) {
-                   return (VREADONLY);
-               }
                if (CallingRoutine == CHK_STOREACL) {
                    if (!(rights & PRSFS_ADMINISTER)
                        && !VolumeOwner(client, targetptr))
@@ -1081,13 +1134,11 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
                    /* watch for chowns and chgrps */
                    if (CHOWN(InStatus, targetptr)
                        || CHGRP(InStatus, targetptr)) {
-                       if (readonlyServer)
-                           return (VREADONLY);
-                       else if (VanillaUser(client))
+                       if (VanillaUser(client))
                            return (EPERM);     /* Was EACCES */
                        else
                            osi_audit(PrivilegeEvent, 0, AUD_ID,
-                                     (client ? client->ViceId : 0), AUD_INT,
+                                     (client ? client->z.ViceId : 0), AUD_INT,
                                      CallingRoutine, AUD_END);
                    }
                    /* must be sysadmin to set suid/sgid bits */
@@ -1097,18 +1148,14 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
 #else
                        (InStatus->UnixModeBits & (S_ISUID | S_ISGID)) != 0) {
 #endif
-                       if (readonlyServer)
-                           return (VREADONLY);
                        if (VanillaUser(client))
                            return (EACCES);
                        else
                            osi_audit(PrivSetID, 0, AUD_ID,
-                                     (client ? client->ViceId : 0), AUD_INT,
+                                     (client ? client->z.ViceId : 0), AUD_INT,
                                      CallingRoutine, AUD_END);
                    }
                    if (CallingRoutine == CHK_STOREDATA) {
-                       if (readonlyServer)
-                           return (VREADONLY);
                        if (!(rights & PRSFS_WRITE))
                            return (EACCES);
                        /* Next thing is tricky.  We want to prevent people
@@ -1136,18 +1183,14 @@ Check_PermissionRights(Vnode * targetptr, struct client *client,
 #endif
                            if ((targetptr->disk.type != vDirectory)
                                && (!(targetptr->disk.modeBits & OWNERWRITE))) {
-                           if (readonlyServer)
-                               return (VREADONLY);
                            if (VanillaUser(client))
                                return (EACCES);
                            else
                                osi_audit(PrivilegeEvent, 0, AUD_ID,
-                                         (client ? client->ViceId : 0),
+                                         (client ? client->z.ViceId : 0),
                                          AUD_INT, CallingRoutine, AUD_END);
                        }
                    } else {    /* a status store */
-                       if (readonlyServer)
-                           return (VREADONLY);
                        if (targetptr->disk.type == vDirectory) {
                            if (!(rights & PRSFS_DELETE)
                                && !(rights & PRSFS_INSERT))
@@ -1218,6 +1261,26 @@ RXStore_AccessList(Vnode * targetptr, struct AFSOpaque *AccessList)
 
 }                              /*RXStore_AccessList */
 
+static int
+CheckLink(Volume *volptr, FdHandle_t *fdP, const char *descr)
+{
+    int code;
+    afs_ino_str_t ino;
+
+    code = FDH_ISUNLINKED(fdP);
+    if (code < 0) {
+       ViceLog(0, ("CopyOnWrite: error fstating volume %u inode %s (%s), errno %d\n",
+                   V_id(volptr), PrintInode(ino, fdP->fd_ih->ih_ino), descr, errno));
+       return -1;
+    }
+    if (code) {
+       ViceLog(0, ("CopyOnWrite corruption prevention: detected zero nlink for "
+                   "volume %u inode %s (%s), forcing volume offline\n",
+                   V_id(volptr), PrintInode(ino, fdP->fd_ih->ih_ino), descr));
+       return -1;
+    }
+    return 0;
+}
 
 /* In our current implementation, each successive data store (new file
  * data version) creates a new inode. This function creates the new
@@ -1255,7 +1318,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
     if (size > len)
        size = len;
 
-    buff = (char *)malloc(COPYBUFFSIZE);
+    buff = malloc(COPYBUFFSIZE);
     if (buff == NULL) {
        return EIO;
     }
@@ -1264,16 +1327,16 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
     if (!VALID_INO(ino)) {
        free(buff);
        VTakeOffline(volptr);
-       ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
-                   volptr->hashid));
+       ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                   afs_printable_VolumeId_lu(volptr->hashid)));
        return EIO;
     }
     targFdP = IH_OPEN(targetptr->handle);
     if (targFdP == NULL) {
        rc = errno;
        ViceLog(0,
-               ("CopyOnWrite failed: Failed to open target vnode %u in volume %u (errno = %d)\n",
-                targetptr->vnodeNumber, V_id(volptr), rc));
+               ("CopyOnWrite failed: Failed to open target vnode %u in volume %" AFS_VOLID_FMT " (errno = %d)\n",
+                targetptr->vnodeNumber, afs_printable_VolumeId_lu(V_id(volptr)), rc));
        free(buff);
        VTakeOffline(volptr);
        return rc;
@@ -1288,15 +1351,29 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
                  (int)targetptr->disk.dataVersion);
     if (!VALID_INO(ino)) {
        ViceLog(0,
-               ("CopyOnWrite failed: Partition %s that contains volume %u may be out of free inodes(errno = %d)\n",
-                volptr->partition->name, V_id(volptr), errno));
+               ("CopyOnWrite failed: Partition %s that contains volume %" AFS_VOLID_FMT " may be out of free inodes(errno = %d)\n",
+                volptr->partition->name, afs_printable_VolumeId_lu(V_id(volptr)), errno));
        FDH_CLOSE(targFdP);
        free(buff);
        return ENOSPC;
     }
     IH_INIT(newH, V_device(volptr), V_id(volptr), ino);
     newFdP = IH_OPEN(newH);
-    osi_Assert(newFdP != NULL);
+    opr_Assert(newFdP != NULL);
+
+    rc = CheckLink(volptr, targFdP, "source");
+    if (!rc) {
+       rc = CheckLink(volptr, newFdP, "dest");
+    }
+    if (rc) {
+       FDH_REALLYCLOSE(newFdP);
+       IH_RELEASE(newH);
+       FDH_REALLYCLOSE(targFdP);
+       IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
+       free(buff);
+       VTakeOffline(volptr);
+       return VSALVAGE;
+    }
 
     done = off;
     while (size > 0) {
@@ -1325,8 +1402,8 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
        if ((rdlen != length) || (wrlen != length)) {
            if ((wrlen < 0) && (errno == ENOSPC)) {     /* disk full */
                ViceLog(0,
-                       ("CopyOnWrite failed: Partition %s containing volume %u is full\n",
-                        volptr->partition->name, V_id(volptr)));
+                       ("CopyOnWrite failed: Partition %s containing volume %" AFS_VOLID_FMT " is full\n",
+                        volptr->partition->name, afs_printable_VolumeId_lu(V_id(volptr))));
                /* remove destination inode which was partially copied till now */
                FDH_REALLYCLOSE(newFdP);
                IH_RELEASE(newH);
@@ -1334,8 +1411,8 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
                rc = IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
                if (rc) {
                    ViceLog(0,
-                           ("CopyOnWrite failed: error %u after i_dec on disk full, volume %u in partition %s needs salvage\n",
-                            rc, V_id(volptr), volptr->partition->name));
+                           ("CopyOnWrite failed: error %u after i_dec on disk full, volume %" AFS_VOLID_FMT " in partition %s needs salvage\n",
+                            rc, afs_printable_VolumeId_lu(V_id(volptr)), volptr->partition->name));
                    VTakeOffline(volptr);
                }
                free(buff);
@@ -1346,8 +1423,8 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
                 * 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, (unsigned)length, (unsigned)rdlen,
+                       ("CopyOnWrite failed: volume %" AFS_VOLID_FMT " in partition %s  (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n",
+                        afs_printable_VolumeId_lu(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"));
@@ -1358,7 +1435,7 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
                FDH_REALLYCLOSE(newFdP);
                IH_RELEASE(newH);
                FDH_REALLYCLOSE(targFdP);
-               rc = IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
+               IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
                free(buff);
                VTakeOffline(volptr);
                return EIO;
@@ -1368,11 +1445,11 @@ CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
     FDH_REALLYCLOSE(targFdP);
     rc = IH_DEC(V_linkHandle(volptr), VN_GET_INO(targetptr),
                V_parentId(volptr));
-    osi_Assert(!rc);
+    opr_Assert(!rc);
     IH_RELEASE(targetptr->handle);
 
     rc = FDH_SYNC(newFdP);
-    osi_Assert(rc == 0);
+    opr_Assert(rc == 0);
     FDH_CLOSE(newFdP);
     targetptr->handle = newH;
     VN_SET_INO(targetptr, ino);
@@ -1419,8 +1496,13 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
 
     /* check that the file is in the directory */
     SetDirHandle(dir, parentptr);
-    if (afs_dir_Lookup(dir, Name, fileFid))
-       return (ENOENT);
+    errorCode = afs_dir_Lookup(dir, Name, fileFid);
+    if (errorCode && errorCode != ENOENT) {
+        errorCode = EIO;
+    }
+    if (errorCode) {
+       return errorCode;
+    }
     fileFid->Volume = V_id(volptr);
 
     /* just-in-case check for something causing deadlock */
@@ -1445,8 +1527,8 @@ 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));
+               ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                afs_printable_VolumeId_lu(volptr->hashid)));
        errorCode = VSALVAGE;
        return errorCode;
     }
@@ -1477,8 +1559,8 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
                {
                    VTakeOffline(volptr);
                    ViceLog(0,
-                           ("Volume %u now offline, must be salvaged.\n",
-                            volptr->hashid));
+                           ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                            afs_printable_VolumeId_lu(volptr->hashid)));
                    return (EIO);
                }
                DT1++;
@@ -1503,8 +1585,8 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
                   Directory) ? "directory" : "file")));
        VTakeOffline(volptr);
        ViceLog(0,
-               ("Volume %u now offline, must be salvaged.\n",
-                volptr->hashid));
+               ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                afs_printable_VolumeId_lu(volptr->hashid)));
        if (!errorCode)
            errorCode = code;
     }
@@ -1531,6 +1613,7 @@ Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
     Date currDate;             /*Current date */
     int writeIdx;              /*Write index to bump */
     int timeIdx;               /*Authorship time index to bump */
+    time_t now;
 
     parentptr->disk.dataVersion++;
     newlength = (afs_fsize_t) afs_dir_Length(dir);
@@ -1567,7 +1650,8 @@ Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
      * directory operation.  Get the current time, decide to which time
      * slot this operation belongs, and bump the appropriate slot.
      */
-    currDate = (FT_ApproxTime() - parentptr->disk.unixModifyTime);
+    now = time(NULL);
+    currDate = (now - parentptr->disk.unixModifyTime);
     timeIdx =
        (currDate < VOL_STATS_TIME_CAP_0 ? VOL_STATS_TIME_IDX_0 : currDate <
         VOL_STATS_TIME_CAP_1 ? VOL_STATS_TIME_IDX_1 : currDate <
@@ -1582,8 +1666,8 @@ Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
 
     parentptr->disk.author = author;
     parentptr->disk.linkCount = linkcount;
-    parentptr->disk.unixModifyTime = FT_ApproxTime();  /* This should be set from CLIENT!! */
-    parentptr->disk.serverModifyTime = FT_ApproxTime();
+    parentptr->disk.unixModifyTime = now;      /* This should be set from CLIENT!! */
+    parentptr->disk.serverModifyTime = now;
     parentptr->changed_newTime = 1;    /* vnode changed, write it back. */
 }
 
@@ -1592,6 +1676,8 @@ Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
  * Update the target file's (or dir's) status block after the specified
  * operation is complete. Note that some other fields maybe updated by
  * the individual module.
+ * If remote is set, the volume is a RW replica and access checks can
+ * be skipped.
  */
 
 /* XXX INCOMPLETE - More attention is needed here! */
@@ -1599,7 +1685,7 @@ static void
 Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
                         struct client *client, AFSStoreStatus * InStatus,
                         Vnode * parentptr, Volume * volptr,
-                        afs_fsize_t length)
+                        afs_fsize_t length, int remote)
 {
     Date currDate;             /*Current date */
     int writeIdx;              /*Write index to bump */
@@ -1610,7 +1696,7 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
        VN_SET_LEN(targetptr, length);
        /* targetptr->disk.group =      0;  save some cycles */
        targetptr->disk.modeBits = 0777;
-       targetptr->disk.owner = client->ViceId;
+       targetptr->disk.owner = client->z.ViceId;
        targetptr->disk.dataVersion = 0;        /* consistent with the client */
        targetptr->disk.linkCount = (Caller & TVS_MKDIR ? 2 : 1);
        /* the inode was created in Alloc_NewVnode() */
@@ -1620,12 +1706,12 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
      * counter is located immediately after its associated ``distance''
      * counter.
      */
-    if (client->InSameNetwork)
+    if (client->z.InSameNetwork)
        writeIdx = VOL_STATS_SAME_NET;
     else
        writeIdx = VOL_STATS_DIFF_NET;
     V_stat_writes(volptr, writeIdx)++;
-    if (client->ViceId != AnonymousID) {
+    if (client->z.ViceId != AnonymousID) {
        V_stat_writes(volptr, writeIdx + 1)++;
     }
 
@@ -1640,7 +1726,7 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
         * file operation.  Get the current time, decide to which time
         * slot this operation belongs, and bump the appropriate slot.
         */
-       currDate = (FT_ApproxTime() - targetptr->disk.unixModifyTime);
+       currDate = (time(NULL) - targetptr->disk.unixModifyTime);
        timeIdx =
            (currDate <
             VOL_STATS_TIME_CAP_0 ? VOL_STATS_TIME_IDX_0 : currDate <
@@ -1649,7 +1735,7 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
             VOL_STATS_TIME_CAP_3 ? VOL_STATS_TIME_IDX_3 : currDate <
             VOL_STATS_TIME_CAP_4 ? VOL_STATS_TIME_IDX_4 :
             VOL_STATS_TIME_IDX_5);
-       if (targetptr->disk.author == client->ViceId) {
+       if (targetptr->disk.author == client->z.ViceId) {
            V_stat_fileSameAuthor(volptr, timeIdx)++;
        } else {
            V_stat_fileDiffAuthor(volptr, timeIdx)++;
@@ -1657,13 +1743,15 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
     }
 
     if (!(Caller & TVS_SSTATUS))
-       targetptr->disk.author = client->ViceId;
+       targetptr->disk.author = client->z.ViceId;
     if (Caller & TVS_SDATA) {
        targetptr->disk.dataVersion++;
-       if (VanillaUser(client)) {
-           targetptr->disk.modeBits &= ~04000; /* turn off suid for file. */
+       if (!remote && VanillaUser(client)) {
+           /* turn off suid */
+           targetptr->disk.modeBits = targetptr->disk.modeBits & ~04000;
 #ifdef CREATE_SGUID_ADMIN_ONLY
-           targetptr->disk.modeBits &= ~02000; /* turn off sgid for file. */
+           /* turn off sgid */
+           targetptr->disk.modeBits = targetptr->disk.modeBits & ~02000;
 #endif
        }
     }
@@ -1674,14 +1762,16 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
     } else {                   /* other: date always changes, but perhaps to what is specified by caller */
        targetptr->disk.unixModifyTime =
            (InStatus->Mask & AFS_SETMODTIME ? InStatus->
-            ClientModTime : FT_ApproxTime());
+            ClientModTime : time(NULL));
     }
     if (InStatus->Mask & AFS_SETOWNER) {
        /* admin is allowed to do chmod, chown as well as chown, chmod. */
-       if (VanillaUser(client)) {
-           targetptr->disk.modeBits &= ~04000; /* turn off suid for file. */
+       if (!remote && VanillaUser(client)) {
+           /* turn off suid */
+           targetptr->disk.modeBits = targetptr->disk.modeBits & ~04000;
 #ifdef CREATE_SGUID_ADMIN_ONLY
-           targetptr->disk.modeBits &= ~02000; /* turn off sgid for file. */
+           /* turn off sgid */
+           targetptr->disk.modeBits = targetptr->disk.modeBits & ~02000;
 #endif
        }
        targetptr->disk.owner = InStatus->Owner;
@@ -1694,23 +1784,22 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
     }
     if (InStatus->Mask & AFS_SETMODE) {
        int modebits = InStatus->UnixModeBits;
-#define        CREATE_SGUID_ADMIN_ONLY 1
 #ifdef CREATE_SGUID_ADMIN_ONLY
-       if (VanillaUser(client))
+       if (!remote && VanillaUser(client))
            modebits = modebits & 0777;
 #endif
-       if (VanillaUser(client)) {
+       if (!remote && VanillaUser(client)) {
            targetptr->disk.modeBits = modebits;
        } else {
            targetptr->disk.modeBits = modebits;
            switch (Caller) {
            case TVS_SDATA:
-               osi_audit(PrivSetID, 0, AUD_ID, client->ViceId, AUD_INT,
+               osi_audit(PrivSetID, 0, AUD_ID, client->z.ViceId, AUD_INT,
                          CHK_STOREDATA, AUD_END);
                break;
            case TVS_CFILE:
            case TVS_SSTATUS:
-               osi_audit(PrivSetID, 0, AUD_ID, client->ViceId, AUD_INT,
+               osi_audit(PrivSetID, 0, AUD_ID, client->z.ViceId, AUD_INT,
                          CHK_STORESTATUS, AUD_END);
                break;
            default:
@@ -1718,7 +1807,7 @@ Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
            }
        }
     }
-    targetptr->disk.serverModifyTime = FT_ApproxTime();
+    targetptr->disk.serverModifyTime = time(NULL);
     if (InStatus->Mask & AFS_SETGROUP)
        targetptr->disk.group = InStatus->Group;
     /* vnode changed : to be written back by VPutVnode */
@@ -1739,7 +1828,7 @@ SetCallBackStruct(afs_uint32 CallBackTime, struct AFSCallBack *CallBack)
        ViceLog(0, ("WARNING: CallBackTime == 0!\n"));
        CallBack->ExpirationTime = 0;
     } else
-       CallBack->ExpirationTime = CallBackTime - FT_ApproxTime();
+       CallBack->ExpirationTime = CallBackTime - time(NULL);
     CallBack->CallBackVersion = CALLBACK_VERSION;
     CallBack->CallBackType = CB_SHARED;        /* The default for now */
 
@@ -1765,14 +1854,16 @@ AdjustDiskUsage(Volume * volptr, afs_sfsize_t length,
        VAdjustDiskUsage(&nc, volptr, -length, 0);
        if (rc == VOVERQUOTA) {
            ViceLog(2,
-                   ("Volume %u (%s) is full\n", V_id(volptr),
+                   ("Volume %" AFS_VOLID_FMT " (%s) is full\n",
+                    afs_printable_VolumeId_lu(V_id(volptr)),
                     V_name(volptr)));
            return (rc);
        }
        if (rc == VDISKFULL) {
            ViceLog(0,
-                   ("Partition %s that contains volume %u is full\n",
-                    volptr->partition->name, V_id(volptr)));
+                   ("Partition %s that contains volume %" AFS_VOLID_FMT " is full\n",
+                    volptr->partition->name,
+                    afs_printable_VolumeId_lu(V_id(volptr))));
            return (rc);
        }
        ViceLog(0, ("Got error return %d from VAdjustDiskUsage\n", rc));
@@ -1833,8 +1924,8 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
     /* error in creating inode */
     if (!VALID_INO(inode)) {
        ViceLog(0,
-               ("Volume : %u vnode = %u Failed to create inode: errno = %d\n",
-                (*targetptr)->volumePtr->header->diskstuff.id,
+               ("Volume : %" AFS_VOLID_FMT " vnode = %u Failed to create inode: errno = %d\n",
+                afs_printable_VolumeId_lu(V_id((*targetptr)->volumePtr)),
                 (*targetptr)->vnodeNumber, errno));
        VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
        (*targetptr)->delete = 1;       /* delete vnode */
@@ -1894,7 +1985,7 @@ HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLo
     int writeVnode = targetptr->changed_oldTime;       /* save original status */
 
     targetptr->changed_oldTime = 1;    /* locking doesn't affect any time stamp */
-    Time = FT_ApproxTime();
+    Time = time(NULL);
     switch (LockingType) {
     case LockRead:
     case LockWrite:
@@ -1947,9 +2038,10 @@ HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLo
 /* Checks if caller has the proper AFS and Unix (WRITE) access permission to the target directory; Prfs_Mode refers to the AFS Mode operation while rights contains the caller's access permissions to the directory. */
 
 static afs_int32
-CheckWriteMode(Vnode * targetptr, afs_int32 rights, int Prfs_Mode)
+CheckWriteMode(Vnode * targetptr, afs_int32 rights, int Prfs_Mode,
+              struct client *client)
 {
-    if (readonlyServer)
+    if (!IsWriteAllowed(client))
        return (VREADONLY);
     if (!(rights & Prfs_Mode))
        return (EACCES);
@@ -1994,7 +2086,6 @@ static afs_int32
 RXGetVolumeStatus(AFSFetchVolumeStatus * status, char **name, char **offMsg,
                  char **motd, Volume * volptr)
 {
-    int temp;
 
     status->Vid = V_id(volptr);
     status->ParentId = V_parentId(volptr);
@@ -2013,18 +2104,14 @@ RXGetVolumeStatus(AFSFetchVolumeStatus * status, char **name, char **offMsg,
     status->PartMaxBlocks = RoundInt64ToInt31(volptr->partition->totalUsable);
 
     /* now allocate and copy these things; they're freed by the RXGEN stub */
-    temp = strlen(V_name(volptr)) + 1;
-    *name = malloc(temp);
+    *name = strdup(V_name(volptr));
     if (!*name) {
        ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
     }
-    strcpy(*name, V_name(volptr));
-    temp = strlen(V_offlineMessage(volptr)) + 1;
-    *offMsg = malloc(temp);
+    *offMsg = strdup(V_offlineMessage(volptr));
     if (!*offMsg) {
        ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
     }
-    strcpy(*offMsg, V_offlineMessage(volptr));
     *motd = malloc(1);
     if (!*motd) {
        ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"));
@@ -2137,7 +2224,7 @@ static
 GetStatus(Vnode * targetptr, AFSFetchStatus * status, afs_int32 rights,
          afs_int32 anyrights, Vnode * parentptr)
 {
-    int Time =FT_ApproxTime();
+    int Time = time(NULL);
 
     /* initialize return status from a vnode  */
     status->InterfaceVersion = 1;
@@ -2212,7 +2299,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     FS_LOCK;
     AFSCallStats.FetchData++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_FetchData;
 
     /* Get ptr to client data for user Id for logging */
@@ -2221,7 +2308,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(5,
            ("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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
 
     queue_NodeInit(&tcbv);
     tcbv.call = acall;
@@ -2243,12 +2330,12 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
      * Remember that another read operation was performed.
      */
     FS_LOCK;
-    if (client->InSameNetwork)
+    if (client->z.InSameNetwork)
        readIdx = VOL_STATS_SAME_NET;
     else
        readIdx = VOL_STATS_DIFF_NET;
     V_stat_reads(volptr, readIdx)++;
-    if (client->ViceId != AnonymousID) {
+    if (client->z.ViceId != AnonymousID) {
        V_stat_reads(volptr, readIdx + 1)++;
     }
     FS_UNLOCK;
@@ -2264,7 +2351,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     if (parentwhentargetnotdir != NULL) {
        tparentwhentargetnotdir = *parentwhentargetnotdir;
        VPutVnode(&fileCode, parentwhentargetnotdir);
-       osi_Assert(!fileCode || (fileCode == VSALVAGE));
+       assert_vnode_success_or_salvaging(fileCode);
        parentwhentargetnotdir = NULL;
     }
 
@@ -2285,16 +2372,14 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     GetStatus(targetptr, OutStatus, rights, anyrights,
              &tparentwhentargetnotdir);
 
-    rx_KeepAliveOn(acall); /* I/O done */
-
     /* if a r/w volume, promise a callback to the caller */
     if (VolumeWriteable(volptr))
-       SetCallBackStruct(AddCallBack(client->host, Fid), CallBack);
+       SetCallBackStruct(AddCallBack(client->z.host, Fid), CallBack);
     else {
        struct AFSFid myFid;
        memset(&myFid, 0, sizeof(struct AFSFid));
        myFid.Volume = Fid->Volume;
-       SetCallBackStruct(AddVolCallBack(client->host, &myFid), CallBack);
+       SetCallBackStruct(AddVolCallBack(client->z.host, &myFid), CallBack);
     }
 
   Bad_FetchData:
@@ -2307,8 +2392,8 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
     fsstats_FinishOp(&fsstats, errorCode);
 
     osi_auditU(acall, FetchDataEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_END);
     return (errorCode);
 
 }                              /*SRXAFS_FetchData */
@@ -2364,7 +2449,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     FS_LOCK;
     AFSCallStats.FetchACL++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_FetchACL;
 
     /* Get ptr to client data for user Id for logging */
@@ -2373,7 +2458,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     ViceLog(5,
            ("SAFS_FetchACL, 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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
 
     AccessList->AFSOpaque_len = 0;
     AccessList->AFSOpaque_val = malloc(AFSOPAQUEMAX);
@@ -2419,9 +2504,9 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
     fsstats_FinishOp(&fsstats, errorCode);
 
     osi_auditU(acall, FetchACLEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid,
-               AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid,
+              AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
     return errorCode;
 }                              /*SRXAFS_FetchACL */
 
@@ -2451,7 +2536,7 @@ SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(1,
            ("SAFS_FetchStatus,  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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.FetchStatus++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -2465,8 +2550,6 @@ SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
                          &rights, &anyrights)))
        goto Bad_FetchStatus;
 
-    rx_KeepAliveOn(acall);
-
     /* set volume synchronization information */
     SetVolumeSync(Sync, volptr);
 
@@ -2487,12 +2570,12 @@ SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
 
     /* If a r/w volume, also set the CallBack state */
     if (VolumeWriteable(volptr))
-       SetCallBackStruct(AddCallBack(client->host, Fid), CallBack);
+       SetCallBackStruct(AddCallBack(client->z.host, Fid), CallBack);
     else {
        struct AFSFid myFid;
        memset(&myFid, 0, sizeof(struct AFSFid));
        myFid.Volume = Fid->Volume;
-       SetCallBackStruct(AddVolCallBack(client->host, &myFid), CallBack);
+       SetCallBackStruct(AddVolCallBack(client->z.host, &myFid), CallBack);
     }
 
   Bad_FetchStatus:
@@ -2537,23 +2620,22 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     }
 
     /* allocate space for return output parameters */
-    OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
-       malloc(nfiles * sizeof(struct AFSFetchStatus));
+    OutStats->AFSBulkStats_val = malloc(nfiles * sizeof(struct AFSFetchStatus));
     if (!OutStats->AFSBulkStats_val) {
        ViceLogThenPanic(0, ("Failed malloc in SRXAFS_BulkStatus\n"));
     }
     OutStats->AFSBulkStats_len = nfiles;
-    CallBacks->AFSCBs_val = (struct AFSCallBack *)
-       malloc(nfiles * sizeof(struct AFSCallBack));
+    CallBacks->AFSCBs_val = malloc(nfiles * sizeof(struct AFSCallBack));
     if (!CallBacks->AFSCBs_val) {
        ViceLogThenPanic(0, ("Failed malloc in SRXAFS_BulkStatus\n"));
     }
     CallBacks->AFSCBs_len = nfiles;
 
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    tfid = Fids->AFSCBFids_val;
+
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, tfid, &tcon, &thost)))
        goto Bad_BulkStatus;
 
-    tfid = Fids->AFSCBFids_val;
     for (i = 0; i < nfiles; i++, tfid++) {
        /*
         * Get volume/vnode for the fetched file; caller's rights to it
@@ -2565,8 +2647,6 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                              &rights, &anyrights)))
            goto Bad_BulkStatus;
 
-       rx_KeepAliveOn(acall);
-
        /* set volume synchronization information, but only once per call */
        if (i == 0)
            SetVolumeSync(Sync, volptr);
@@ -2588,13 +2668,13 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
 
        /* If a r/w volume, also set the CallBack state */
        if (VolumeWriteable(volptr))
-           SetCallBackStruct(AddBulkCallBack(client->host, tfid),
+           SetCallBackStruct(AddBulkCallBack(client->z.host, tfid),
                              &CallBacks->AFSCBs_val[i]);
        else {
            struct AFSFid myFid;
            memset(&myFid, 0, sizeof(struct AFSFid));
            myFid.Volume = tfid->Volume;
-           SetCallBackStruct(AddVolCallBack(client->host, &myFid),
+           SetCallBackStruct(AddVolCallBack(client->z.host, &myFid),
                              &CallBacks->AFSCBs_val[i]);
        }
 
@@ -2620,8 +2700,8 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
   Audit_and_Return:
     ViceLog(2, ("SAFS_BulkStatus       returns %d\n", errorCode));
     osi_auditU(acall, BulkFetchStatusEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FIDS, Fids, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FIDS, Fids, AUD_END);
     return errorCode;
 
 }                              /*SRXAFS_BulkStatus */
@@ -2661,29 +2741,26 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
     }
 
     /* allocate space for return output parameters */
-    OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
-       malloc(nfiles * sizeof(struct AFSFetchStatus));
+    OutStats->AFSBulkStats_val = calloc(nfiles, sizeof(struct AFSFetchStatus));
     if (!OutStats->AFSBulkStats_val) {
        ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchStatus\n"));
     }
     OutStats->AFSBulkStats_len = nfiles;
-    CallBacks->AFSCBs_val = (struct AFSCallBack *)
-       malloc(nfiles * sizeof(struct AFSCallBack));
+    CallBacks->AFSCBs_val = calloc(nfiles, sizeof(struct AFSCallBack));
     if (!CallBacks->AFSCBs_val) {
        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))) {
+    tfid = Fids->AFSCBFids_val;
+
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, tfid, &tcon, &thost))) {
        goto Bad_InlineBulkStatus;
     }
 
-    tfid = Fids->AFSCBFids_val;
     for (i = 0; i < nfiles; i++, tfid++) {
        /*
         * Get volume/vnode for the fetched file; caller's rights to it
@@ -2695,7 +2772,8 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                              &rights, &anyrights))) {
            tstatus = &OutStats->AFSBulkStats_val[i];
 
-           if (thost->hostFlags & HERRORTRANS) {
+           tstatus->InterfaceVersion = 1;
+           if (thost->z.hostFlags & HERRORTRANS) {
                tstatus->errorCode = sys_error_to_et(errorCode);
            } else {
                tstatus->errorCode = errorCode;
@@ -2710,8 +2788,6 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
            continue;
        }
 
-       rx_KeepAliveOn(acall);
-
        /* set volume synchronization information, but only once per call */
        if (!VolSync_set) {
            SetVolumeSync(Sync, volptr);
@@ -2725,7 +2801,8 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                                        CHK_FETCHSTATUS, 0))) {
                tstatus = &OutStats->AFSBulkStats_val[i];
 
-               if (thost->hostFlags & HERRORTRANS) {
+               tstatus->InterfaceVersion = 1;
+               if (thost->z.hostFlags & HERRORTRANS) {
                    tstatus->errorCode = sys_error_to_et(errorCode);
                } else {
                    tstatus->errorCode = errorCode;
@@ -2749,13 +2826,13 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
 
        /* If a r/w volume, also set the CallBack state */
        if (VolumeWriteable(volptr))
-           SetCallBackStruct(AddBulkCallBack(client->host, tfid),
+           SetCallBackStruct(AddBulkCallBack(client->z.host, tfid),
                              &CallBacks->AFSCBs_val[i]);
        else {
            struct AFSFid myFid;
            memset(&myFid, 0, sizeof(struct AFSFid));
            myFid.Volume = tfid->Volume;
-           SetCallBackStruct(AddVolCallBack(client->host, &myFid),
+           SetCallBackStruct(AddVolCallBack(client->z.host, &myFid),
                              &CallBacks->AFSCBs_val[i]);
        }
 
@@ -2782,8 +2859,8 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
   Audit_and_Return:
     ViceLog(2, ("SAFS_InlineBulkStatus returns %d\n", errorCode));
     osi_auditU(acall, InlineBulkFetchStatusEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FIDS, Fids, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FIDS, Fids, AUD_END);
     return errorCode;
 
 }                              /*SRXAFS_InlineBulkStatus */
@@ -2802,7 +2879,7 @@ SRXAFS_FetchStatus(struct rx_call * acall, struct AFSFid * Fid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHSTATUS);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_FetchStatus;
 
     code = SAFSS_FetchStatus(acall, Fid, OutStatus, CallBack, Sync);
@@ -2815,8 +2892,8 @@ SRXAFS_FetchStatus(struct rx_call * acall, struct AFSFid * Fid,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, FetchStatusEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_END);
     return code;
 
 }                              /*SRXAFS_FetchStatus */
@@ -2854,7 +2931,7 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     FS_LOCK;
     AFSCallStats.StoreData++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_StoreData;
 
     /* Get ptr to client data for user Id for logging */
@@ -2863,7 +2940,7 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(5,
            ("StoreData: 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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
 
     /*
      * Get associated volume/vnode for the stored file; caller's rights
@@ -2876,8 +2953,6 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
        goto Bad_StoreData;
     }
 
-    rx_KeepAliveOn(acall);
-
     /* set volume synchronization information */
     SetVolumeSync(Sync, volptr);
 
@@ -2900,10 +2975,8 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
      */
     if (parentwhentargetnotdir != NULL) {
        tparentwhentargetnotdir = *parentwhentargetnotdir;
-       rx_KeepAliveOff(acall);
        VPutVnode(&fileCode, parentwhentargetnotdir);
-       rx_KeepAliveOn(acall);
-       osi_Assert(!fileCode || (fileCode == VSALVAGE));
+       assert_vnode_success_or_salvaging(fileCode);
        parentwhentargetnotdir = NULL;
     }
 
@@ -2920,11 +2993,9 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     if (errorCode && (!targetptr->changed_newTime))
        goto Bad_StoreData;
 
-    rx_KeepAliveOff(acall);
     /* Update the status of the target's vnode */
     Update_TargetVnodeStatus(targetptr, TVS_SDATA, client, InStatus,
-                            targetptr, volptr, 0);
-    rx_KeepAliveOn(acall);
+                            targetptr, volptr, 0, 0);
 
     /* Get the updated File's status back to the caller */
     GetStatus(targetptr, OutStatus, rights, anyrights,
@@ -2941,8 +3012,8 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
     fsstats_FinishOp(&fsstats, errorCode);
 
     osi_auditU(acall, StoreDataEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_END);
     return (errorCode);
 }                              /*common_StoreData64 */
 
@@ -3002,7 +3073,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STOREACL);
 
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_StoreACL;
 
     /* Get ptr to client data for user Id for logging */
@@ -3011,7 +3082,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
     ViceLog(1,
            ("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n",
             Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->AFSOpaque_val,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.StoreACL++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -3047,12 +3118,10 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
-
-    rx_KeepAliveOn(acall);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* break call backs on the directory  */
-    BreakCallBack(client->host, Fid, 0);
+    BreakCallBack(client->z.host, Fid, 0);
 
     /* Get the updated dir's status back to the caller */
     GetStatus(targetptr, OutStatus, rights, anyrights, 0);
@@ -3067,8 +3136,8 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
     fsstats_FinishOp(&fsstats, errorCode);
 
     osi_auditU(acall, StoreACLEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
     return errorCode;
 
 }                              /*SRXAFS_StoreACL */
@@ -3099,7 +3168,7 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(1,
            ("SAFS_StoreStatus,  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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.StoreStatus++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -3135,16 +3204,14 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
     /* Update the status of the target's vnode */
     Update_TargetVnodeStatus(targetptr, TVS_SSTATUS, client, InStatus,
                             (parentwhentargetnotdir ? parentwhentargetnotdir
-                             : targetptr), volptr, 0);
-
-    rx_KeepAliveOn(acall);
+                             : targetptr), volptr, 0, 0);
 
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* Break call backs on Fid */
-    BreakCallBack(client->host, Fid, 0);
+    BreakCallBack(client->z.host, Fid, 0);
 
     /* Return the updated status back to caller */
     GetStatus(targetptr, OutStatus, rights, anyrights,
@@ -3174,7 +3241,7 @@ SRXAFS_StoreStatus(struct rx_call * acall, struct AFSFid * Fid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STORESTATUS);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_StoreStatus;
 
     code = SAFSS_StoreStatus(acall, Fid, InStatus, OutStatus, Sync);
@@ -3187,8 +3254,8 @@ SRXAFS_StoreStatus(struct rx_call * acall, struct AFSFid * Fid,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, StoreStatusEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_END);
     return code;
 
 }                              /*SRXAFS_StoreStatus */
@@ -3222,7 +3289,7 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     ViceLog(1,
            ("SAFS_RemoveFile %s,  Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
             DirFid->Volume, DirFid->Vnode, DirFid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.RemoveFile++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -3240,7 +3307,7 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     SetVolumeSync(Sync, volptr);
 
     /* Does the caller has delete (& write) access to the parent directory? */
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE))) {
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE, client))) {
        goto Bad_RemoveFile;
     }
 
@@ -3252,11 +3319,9 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     }
 
     /* Update the vnode status of the parent dir */
-    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
                             parentptr->disk.linkCount,
-                            client->InSameNetwork);
-
-    rx_KeepAliveOn(acall);
+                            client->z.InSameNetwork);
 
     /* Return the updated parent dir's status back to caller */
     GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
@@ -3267,20 +3332,20 @@ 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);
-       osi_Assert(!errorCode || errorCode == VSALVAGE);
+       assert_vnode_success_or_salvaging(errorCode);
     } else {
        /* convert the parent lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, parentptr);
-       osi_Assert(!errorCode || errorCode == VSALVAGE);
+       assert_vnode_success_or_salvaging(errorCode);
        /* convert the target lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, targetptr);
-       osi_Assert(!errorCode || errorCode == VSALVAGE);
+       assert_vnode_success_or_salvaging(errorCode);
        /* tell all the file has changed */
-       BreakCallBack(client->host, &fileFid, 1);
+       BreakCallBack(client->z.host, &fileFid, 1);
     }
 
     /* break call back on the directory */
-    BreakCallBack(client->host, DirFid, 0);
+    BreakCallBack(client->z.host, DirFid, 0);
 
   Bad_RemoveFile:
     /* Update and store volume/vnode and parent vnodes back */
@@ -3306,7 +3371,7 @@ SRXAFS_RemoveFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEFILE);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
        goto Bad_RemoveFile;
 
     code = SAFSS_RemoveFile(acall, DirFid, Name, OutDirStatus, Sync);
@@ -3319,8 +3384,8 @@ SRXAFS_RemoveFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, RemoveFileEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, DirFid, AUD_STR, Name, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, DirFid, AUD_STR, Name, AUD_END);
     return code;
 
 }                              /*SRXAFS_RemoveFile */
@@ -3357,7 +3422,7 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     ViceLog(1,
            ("SAFS_CreateFile %s,  Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
             DirFid->Volume, DirFid->Vnode, DirFid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.CreateFile++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -3381,7 +3446,7 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     SetVolumeSync(Sync, volptr);
 
     /* Can we write (and insert) onto the parent directory? */
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))) {
        goto Bad_CreateFile;
     }
 
@@ -3392,15 +3457,13 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        goto Bad_CreateFile;
 
     /* update the status of the parent vnode */
-    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
                             parentptr->disk.linkCount,
-                            client->InSameNetwork);
+                            client->z.InSameNetwork);
 
     /* update the status of the new file's vnode */
     Update_TargetVnodeStatus(targetptr, TVS_CFILE, client, InStatus,
-                            parentptr, volptr, 0);
-
-    rx_KeepAliveOn(acall);
+                            parentptr, volptr, 0, 0);
 
     /* set up the return status for the parent dir and the newly created file, and since the newly created file is owned by the creator, give it PRSFS_ADMINISTER to tell the client its the owner of the file */
     GetStatus(targetptr, OutFidStatus, rights | PRSFS_ADMINISTER, anyrights, parentptr);
@@ -3408,13 +3471,13 @@ 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);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* break call back on parent dir */
-    BreakCallBack(client->host, DirFid, 0);
+    BreakCallBack(client->z.host, DirFid, 0);
 
     /* Return a callback promise for the newly created file to the caller */
-    SetCallBackStruct(AddCallBack(client->host, OutFid), CallBack);
+    SetCallBackStruct(AddCallBack(client->z.host, OutFid), CallBack);
 
   Bad_CreateFile:
     /* Update and store volume/vnode and parent vnodes back */
@@ -3444,7 +3507,7 @@ SRXAFS_CreateFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     memset(OutFid, 0, sizeof(struct AFSFid));
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
        goto Bad_CreateFile;
 
     code =
@@ -3459,8 +3522,8 @@ SRXAFS_CreateFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     fsstats_FinishOp(&fsstats, 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);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, DirFid, AUD_STR, Name, AUD_FID, OutFid, AUD_END);
     return code;
 
 }                              /*SRXAFS_CreateFile */
@@ -3517,7 +3580,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            ("SAFS_Rename %s    to %s,  Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n",
             OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode,
             OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode,
-            NewDirFid->Unique, inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            NewDirFid->Unique, inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.Rename++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -3577,10 +3640,11 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     /* set volume synchronization information */
     SetVolumeSync(Sync, volptr);
 
-    if ((errorCode = CheckWriteMode(oldvptr, rights, PRSFS_DELETE))) {
+    if ((errorCode = CheckWriteMode(oldvptr, rights, PRSFS_DELETE, client))) {
        goto Bad_Rename;
     }
-    if ((errorCode = CheckWriteMode(newvptr, newrights, PRSFS_INSERT))) {
+    if ((errorCode = CheckWriteMode(newvptr, newrights, PRSFS_INSERT,
+                                   client))) {
        goto Bad_Rename;
     }
 
@@ -3611,8 +3675,11 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     SetDirHandle(&newdir, newvptr);
 
     /* Lookup the file to delete its vnode */
-    if (afs_dir_Lookup(&olddir, OldName, &fileFid)) {
-       errorCode = ENOENT;
+    errorCode = afs_dir_Lookup(&olddir, OldName, &fileFid);
+    if (errorCode && errorCode != ENOENT) {
+        errorCode = EIO;
+    }
+    if (errorCode) {
        goto Bad_Rename;
     }
     if (fileFid.Vnode == oldvptr->vnodeNumber
@@ -3651,8 +3718,13 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     }
 
     /* Lookup the new file  */
-    if (!(afs_dir_Lookup(&newdir, NewName, &newFileFid))) {
-       if (readonlyServer) {
+    code = afs_dir_Lookup(&newdir, NewName, &newFileFid);
+    if (code && code != ENOENT) {
+        errorCode = EIO;
+        goto Bad_Rename;
+    }
+    if (!code) {
+       if (!IsWriteAllowed(client)) {
            errorCode = VREADONLY;
            goto Bad_Rename;
        }
@@ -3735,18 +3807,18 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            }
            if (testnode == 1) top = 1;
            testvptr = VGetVnode(&errorCode, volptr, testnode, READ_LOCK);
-           osi_Assert(errorCode == 0);
+           assert_vnode_success_or_salvaging(errorCode);
            testnode = testvptr->disk.parent;
            VPutVnode(&errorCode, testvptr);
            if ((top == 1) && (testnode != 0)) {
                VTakeOffline(volptr);
                ViceLog(0,
-                       ("Volume %u now offline, must be salvaged.\n",
-                        volptr->hashid));
+                       ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                        afs_printable_VolumeId_lu(volptr->hashid)));
                errorCode = EIO;
                goto Bad_Rename;
            }
-           osi_Assert(errorCode == 0);
+           assert_vnode_success_or_salvaging(errorCode);
        }
     }
 
@@ -3760,6 +3832,10 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            struct AFSFid unused;
 
            code = afs_dir_Lookup(&filedir, "..", &unused);
+            if (code && code != ENOENT) {
+                errorCode = EIO;
+                goto Bad_Rename;
+            }
            if (code == ENOENT) {
                /* only update .. if it doesn't already exist */
                updatefile = 1;
@@ -3784,7 +3860,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     if (newfileptr) {
        /* Delete NewName from its directory */
        code = afs_dir_Delete(&newdir, NewName);
-       osi_Assert(code == 0);
+       opr_Assert(code == 0);
 
        /* Drop the link count */
        newfileptr->disk.linkCount--;
@@ -3806,7 +3882,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
                             NewName, errno));
                    if ((errno != ENOENT) && (errno != EIO)
                        && (errno != ENXIO))
-                       ViceLog(0, ("Do we need to fsck?"));
+                       ViceLog(0, ("Do we need to fsck?\n"));
                }
            }
            VN_SET_INO(newfileptr, (Inode) 0);
@@ -3831,13 +3907,13 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
        goto Bad_Rename;
 
     /* Delete the old name */
-    osi_Assert(afs_dir_Delete(&olddir, OldName) == 0);
+    opr_Assert(afs_dir_Delete(&olddir, OldName) == 0);
 
     /* if the directory length changes, reflect it in the statistics */
-    Update_ParentVnodeStatus(oldvptr, volptr, &olddir, client->ViceId,
-                            oldvptr->disk.linkCount, client->InSameNetwork);
-    Update_ParentVnodeStatus(newvptr, volptr, &newdir, client->ViceId,
-                            newvptr->disk.linkCount, client->InSameNetwork);
+    Update_ParentVnodeStatus(oldvptr, volptr, &olddir, client->z.ViceId,
+                            oldvptr->disk.linkCount, client->z.InSameNetwork);
+    Update_ParentVnodeStatus(newvptr, volptr, &newdir, client->z.ViceId,
+                            newvptr->disk.linkCount, client->z.InSameNetwork);
 
     if (oldvptr == newvptr)
        oldvptr->disk.dataVersion--;    /* Since it was bumped by 2! */
@@ -3850,13 +3926,13 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
     /* 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);
+       opr_Assert(!fileptr->disk.cloned);
 
        fileptr->changed_newTime = 1;   /* status change of moved file */
 
        /* fix .. to point to the correct place */
        afs_dir_Delete(&filedir, ".."); /* No assert--some directories may be bad */
-       osi_Assert(afs_dir_Create(&filedir, "..", NewDirFid) == 0);
+       opr_Assert(afs_dir_Create(&filedir, "..", NewDirFid) == 0);
        fileptr->disk.dataVersion++;
 
        /* if the parent directories are different the link counts have to be   */
@@ -3878,23 +3954,21 @@ 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);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
+    assert_vnode_success_or_salvaging(errorCode);
     if (oldvptr != newvptr) {
        VVnodeWriteToRead(&errorCode, oldvptr);
-       osi_Assert(!errorCode || errorCode == VSALVAGE);
+       assert_vnode_success_or_salvaging(errorCode);
     }
     if (newfileptr && !doDelete) {
        /* convert the write lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, newfileptr);
-       osi_Assert(!errorCode || errorCode == VSALVAGE);
+       assert_vnode_success_or_salvaging(errorCode);
     }
 
-    rx_KeepAliveOn(acall);
-
     /* break call back on NewDirFid, OldDirFid, NewDirFid and newFileFid  */
-    BreakCallBack(client->host, NewDirFid, 0);
+    BreakCallBack(client->z.host, NewDirFid, 0);
     if (oldvptr != newvptr) {
-       BreakCallBack(client->host, OldDirFid, 0);
+       BreakCallBack(client->z.host, OldDirFid, 0);
     }
     if (updatefile) {
        /* if a dir moved, .. changed */
@@ -3904,7 +3978,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
         * 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);
+       BreakCallBack(client->z.host, &fileFid, 1);
     }
     if (newfileptr) {
        /* Note:  it is not necessary to break the callback */
@@ -3912,14 +3986,13 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            DeleteFileCallBacks(&newFileFid);   /* no other references */
        else
            /* other's still exist (with wrong link count) */
-           BreakCallBack(client->host, &newFileFid, 1);
+           BreakCallBack(client->z.host, &newFileFid, 1);
     }
 
   Bad_Rename:
     if (newfileptr) {
-       rx_KeepAliveOff(acall);
        VPutVnode(&fileCode, newfileptr);
-       osi_Assert(fileCode == 0);
+       assert_vnode_success_or_salvaging(fileCode);
     }
     (void)PutVolumePackage(acall, fileptr, (newvptr && newvptr != oldvptr ?
                                     newvptr : 0), oldvptr, volptr, &client);
@@ -3948,7 +4021,7 @@ SRXAFS_Rename(struct rx_call * acall, struct AFSFid * OldDirFid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RENAME);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, OldDirFid, &tcon, &thost)))
        goto Bad_Rename;
 
     code =
@@ -3963,9 +4036,9 @@ SRXAFS_Rename(struct rx_call * acall, struct AFSFid * OldDirFid,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, RenameFileEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, OldDirFid, AUD_STR, OldName,
-               AUD_FID, NewDirFid, AUD_STR, NewName, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, OldDirFid, AUD_STR, OldName,
+              AUD_FID, NewDirFid, AUD_STR, NewName, AUD_END);
     return code;
 
 }                              /*SRXAFS_Rename */
@@ -4004,7 +4077,7 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     ViceLog(1,
            ("SAFS_Symlink %s to %s,  Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
             LinkContents, DirFid->Volume, DirFid->Vnode, DirFid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.Symlink++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4027,7 +4100,7 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     SetVolumeSync(Sync, volptr);
 
     /* Does the caller has insert (and write) access to the parent directory? */
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT)))
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client)))
        goto Bad_SymLink;
 
     /*
@@ -4036,7 +4109,7 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * to do this.
      */
     if ((InStatus->Mask & AFS_SETMODE) && !(InStatus->UnixModeBits & 0111)) {
-       if (readonlyServer) {
+       if (!IsWriteAllowed(client)) {
            errorCode = VREADONLY;
            goto Bad_SymLink;
        }
@@ -4059,13 +4132,13 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     }
 
     /* update the status of the parent vnode */
-    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
                             parentptr->disk.linkCount,
-                            client->InSameNetwork);
+                            client->z.InSameNetwork);
 
     /* update the status of the new symbolic link file vnode */
     Update_TargetVnodeStatus(targetptr, TVS_SLINK, client, InStatus,
-                            parentptr, volptr, strlen((char *)LinkContents));
+                            parentptr, volptr, strlen((char *)LinkContents), 0);
 
     /* Write the contents of the symbolic link name into the target inode */
     fdP = IH_OPEN(targetptr->handle);
@@ -4073,8 +4146,8 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
        (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
                               parentptr, volptr, &client);
        VTakeOffline(volptr);
-       ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
-                   volptr->hashid));
+       ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                   afs_printable_VolumeId_lu(volptr->hashid)));
        return EIO;
     }
     len = strlen((char *) LinkContents);
@@ -4091,12 +4164,10 @@ 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);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
-
-    rx_KeepAliveOn(acall);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* break call back on the parent dir */
-    BreakCallBack(client->host, DirFid, 0);
+    BreakCallBack(client->z.host, DirFid, 0);
 
   Bad_SymLink:
     /* Write the all modified vnodes (parent, new files) and volume back */
@@ -4128,7 +4199,7 @@ SRXAFS_Symlink(struct rx_call *acall,     /* Rx call */
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SYMLINK);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
        goto Bad_Symlink;
 
     code =
@@ -4143,8 +4214,8 @@ SRXAFS_Symlink(struct rx_call *acall,     /* Rx call */
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, SymlinkEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, DirFid, AUD_STR, Name,
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, DirFid, AUD_STR, Name,
               AUD_FID, OutFid, AUD_STR, LinkContents, AUD_END);
     return code;
 
@@ -4181,7 +4252,7 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
            ("SAFS_Link %s,     Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
             Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique,
             ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.Link++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4209,7 +4280,7 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     SetVolumeSync(Sync, volptr);
 
     /* Can the caller insert into the parent directory? */
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))) {
        goto Bad_Link;
     }
 
@@ -4253,12 +4324,12 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* update the status in the parent vnode */
     /**WARNING** --> disk.author SHOULDN'T be modified???? */
-    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
                             parentptr->disk.linkCount,
-                            client->InSameNetwork);
+                            client->z.InSameNetwork);
 
     targetptr->disk.linkCount++;
-    targetptr->disk.author = client->ViceId;
+    targetptr->disk.author = client->z.ViceId;
     targetptr->changed_newTime = 1;    /* Status change of linked-to file */
 
     /* set up return status */
@@ -4267,19 +4338,17 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
     /* convert the write locks to read locks before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
+    assert_vnode_success_or_salvaging(errorCode);
     VVnodeWriteToRead(&errorCode, parentptr);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
-
-    rx_KeepAliveOn(acall);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* break call back on DirFid */
-    BreakCallBack(client->host, DirFid, 0);
+    BreakCallBack(client->z.host, DirFid, 0);
     /*
      * 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);
+    BreakCallBack(client->z.host, ExistingFid, 0);
 
   Bad_Link:
     /* Write the all modified vnodes (parent, new files) and volume back */
@@ -4305,7 +4374,7 @@ SRXAFS_Link(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_LINK);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
        goto Bad_Link;
 
     code =
@@ -4320,8 +4389,8 @@ SRXAFS_Link(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, LinkEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, DirFid, AUD_STR, Name,
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, DirFid, AUD_STR, Name,
               AUD_FID, ExistingFid, AUD_END);
     return code;
 
@@ -4363,7 +4432,7 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     ViceLog(1,
            ("SAFS_MakeDir %s,  Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
             DirFid->Volume, DirFid->Vnode, DirFid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.MakeDir++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4395,10 +4464,11 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * implcit a access that goes with dir ownership, and proceed to
      * subvert quota in the volume.
      */
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))
-       || (errorCode = CheckWriteMode(parentptr, rights, PRSFS_WRITE))) {
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))
+       || (errorCode = CheckWriteMode(parentptr, rights, PRSFS_WRITE,
+                                      client))) {
 #else
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))) {
 #endif /* DIRCREATE_NEED_WRITE */
        goto Bad_MakeDir;
     }
@@ -4411,24 +4481,24 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     }
 
     /* Update the status for the parent dir */
-    Update_ParentVnodeStatus(parentptr, volptr, &parentdir, client->ViceId,
+    Update_ParentVnodeStatus(parentptr, volptr, &parentdir, client->z.ViceId,
                             parentptr->disk.linkCount + 1,
-                            client->InSameNetwork);
+                            client->z.InSameNetwork);
 
     /* Point to target's ACL buffer and copy the parent's ACL contents to it */
-    osi_Assert((SetAccessList
-           (&targetptr, &volptr, &newACL, &newACLSize,
-            &parentwhentargetnotdir, (AFSFid *) 0, 0)) == 0);
-    osi_Assert(parentwhentargetnotdir == 0);
+    opr_Verify((SetAccessList(&targetptr, &volptr, &newACL, &newACLSize,
+                             &parentwhentargetnotdir, NULL, 0))  == 0);
+    opr_Assert(parentwhentargetnotdir == 0);
     memcpy((char *)newACL, (char *)VVnodeACL(parentptr), VAclSize(parentptr));
 
     /* update the status for the target vnode */
     Update_TargetVnodeStatus(targetptr, TVS_MKDIR, client, InStatus,
-                            parentptr, volptr, 0);
+                            parentptr, volptr, 0, 0);
 
     /* Actually create the New directory in the directory package */
     SetDirHandle(&dir, targetptr);
-    osi_Assert(!(afs_dir_MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32 *)DirFid)));
+    opr_Verify(!(afs_dir_MakeDir(&dir, (afs_int32 *)OutFid,
+                                (afs_int32 *)DirFid)));
     DFlush();
     VN_SET_LEN(targetptr, (afs_fsize_t) afs_dir_Length(&dir));
 
@@ -4438,15 +4508,13 @@ 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);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
-
-    rx_KeepAliveOn(acall);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* break call back on DirFid */
-    BreakCallBack(client->host, DirFid, 0);
+    BreakCallBack(client->z.host, DirFid, 0);
 
     /* Return a callback promise to caller */
-    SetCallBackStruct(AddCallBack(client->host, OutFid), CallBack);
+    SetCallBackStruct(AddCallBack(client->z.host, OutFid), CallBack);
 
   Bad_MakeDir:
     /* Write the all modified vnodes (parent, new files) and volume back */
@@ -4475,7 +4543,7 @@ SRXAFS_MakeDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_MAKEDIR);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
        goto Bad_MakeDir;
 
     code =
@@ -4490,8 +4558,8 @@ SRXAFS_MakeDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, MakeDirEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, DirFid, AUD_STR, Name,
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, DirFid, AUD_STR, Name,
               AUD_FID, OutFid, AUD_END);
     return code;
 
@@ -4527,7 +4595,7 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     ViceLog(1,
            ("SAFS_RemoveDir    %s,  Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
             DirFid->Volume, DirFid->Vnode, DirFid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.RemoveDir++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4546,7 +4614,7 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     SetVolumeSync(Sync, volptr);
 
     /* Does the caller has delete (&write) access to the parent dir? */
-    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE))) {
+    if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE, client))) {
        goto Bad_RemoveDir;
     }
 
@@ -4558,9 +4626,9 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     }
 
     /* Update the status for the parent dir; link count is also adjusted */
-    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+    Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
                             parentptr->disk.linkCount - 1,
-                            client->InSameNetwork);
+                            client->z.InSameNetwork);
 
     /* Return to the caller the updated parent dir status */
     GetStatus(parentptr, OutDirStatus, rights, anyrights, NULL);
@@ -4574,12 +4642,10 @@ 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);
-    osi_Assert(!errorCode || errorCode == VSALVAGE);
-
-    rx_KeepAliveOn(acall);
+    assert_vnode_success_or_salvaging(errorCode);
 
     /* break call back on DirFid and fileFid */
-    BreakCallBack(client->host, DirFid, 0);
+    BreakCallBack(client->z.host, DirFid, 0);
 
   Bad_RemoveDir:
     /* Write the all modified vnodes (parent, new files) and volume back */
@@ -4605,7 +4671,7 @@ SRXAFS_RemoveDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEDIR);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
        goto Bad_RemoveDir;
 
     code = SAFSS_RemoveDir(acall, DirFid, Name, OutDirStatus, Sync);
@@ -4618,8 +4684,8 @@ SRXAFS_RemoveDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, RemoveDirEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, DirFid, AUD_STR, Name, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, DirFid, AUD_STR, Name, AUD_END);
     return code;
 
 }                              /*SRXAFS_RemoveDir */
@@ -4654,7 +4720,7 @@ SAFSS_SetLock(struct rx_call *acall, struct AFSFid *Fid, ViceLockType type,
     ViceLog(1,
            ("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n",
             locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->Unique,
-            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+            inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.SetLock++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4709,7 +4775,7 @@ SRXAFS_SetLock(struct rx_call * acall, struct AFSFid * Fid, ViceLockType type,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETLOCK);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_SetLock;
 
     code = SAFSS_SetLock(acall, Fid, type, Sync);
@@ -4722,8 +4788,8 @@ SRXAFS_SetLock(struct rx_call * acall, struct AFSFid * Fid, ViceLockType type,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, SetLockEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_LONG, type, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_LONG, type, AUD_END);
     return code;
 }                              /*SRXAFS_SetLock */
 
@@ -4752,7 +4818,7 @@ SAFSS_ExtendLock(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(1,
            ("SAFS_ExtendLock 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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.ExtendLock++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4807,7 +4873,7 @@ SRXAFS_ExtendLock(struct rx_call * acall, struct AFSFid * Fid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_EXTENDLOCK);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_ExtendLock;
 
     code = SAFSS_ExtendLock(acall, Fid, Sync);
@@ -4820,8 +4886,8 @@ SRXAFS_ExtendLock(struct rx_call * acall, struct AFSFid * Fid,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, ExtendLockEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_END);
     return code;
 
 }                              /*SRXAFS_ExtendLock */
@@ -4851,7 +4917,7 @@ SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
     ViceLog(1,
            ("SAFS_ReleaseLock 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));
+            ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
     FS_LOCK;
     AFSCallStats.ReleaseLock++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
@@ -4875,11 +4941,10 @@ SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
 
     /* if no more locks left, a callback would be triggered here */
     if (targetptr->disk.lock.lockCount <= 0) {
-       rx_KeepAliveOn(acall);
        /* convert the write lock to a read lock before breaking callbacks */
        VVnodeWriteToRead(&errorCode, targetptr);
-       osi_Assert(!errorCode || errorCode == VSALVAGE);
-       BreakCallBack(client->host, Fid, 0);
+       assert_vnode_success_or_salvaging(errorCode);
+       BreakCallBack(client->z.host, Fid, 0);
     }
 
   Bad_ReleaseLock:
@@ -4916,7 +4981,7 @@ SRXAFS_ReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RELEASELOCK);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
        goto Bad_ReleaseLock;
 
     code = SAFSS_ReleaseLock(acall, Fid, Sync);
@@ -4929,8 +4994,8 @@ SRXAFS_ReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, ReleaseLockEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_FID, Fid, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_FID, Fid, AUD_END);
     return code;
 
 }                              /*SRXAFS_ReleaseLock */
@@ -4941,11 +5006,8 @@ SetSystemStats(struct AFSStatistics *stats)
 {
     /* Fix this sometime soon.. */
     /* Because hey, it's not like we have a network monitoring protocol... */
-    struct timeval time;
 
-    /* this works on all system types */
-    FT_GetTimeOfDay(&time, 0);
-    stats->CurrentTime = time.tv_sec;
+    stats->CurrentTime = time(NULL);
 }                              /*SetSystemStats */
 
 void
@@ -4978,15 +5040,11 @@ SetAFSStats(struct AFSStatistics *stats)
     if (seconds <= 0)
        seconds = 1;
     stats->StoreDataRate = AFSCallStats.TotalStoredBytes / seconds;
-#ifdef AFS_NT40_ENV
-    stats->ProcessSize = -1;   /* TODO: */
-#else
-    stats->ProcessSize = (afs_int32) ((long)sbrk(0) >> 10);
-#endif
+    stats->ProcessSize = opr_procsize();
     FS_UNLOCK;
     h_GetWorkStats((int *)&(stats->WorkStations),
                   (int *)&(stats->ActiveWorkStations), (int *)0,
-                  (afs_int32) (FT_ApproxTime()) - (15 * 60));
+                  (afs_int32) (time(NULL)) - (15 * 60));
 
 }                              /*SetAFSStats */
 
@@ -5023,7 +5081,7 @@ SRXAFS_GetStatistics(struct rx_call *acall, struct ViceStatistics *Statistics)
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS);
 
-    if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GetStatistics;
 
     ViceLog(1, ("SAFS_GetStatistics Received\n"));
@@ -5043,7 +5101,7 @@ SRXAFS_GetStatistics(struct rx_call *acall, struct ViceStatistics *Statistics)
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, GetStatisticsEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0, AUD_END);
     return code;
 }                              /*SRXAFS_GetStatistics */
 
@@ -5057,17 +5115,21 @@ SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatis
     struct rx_connection *tcon = rx_ConnectionOf(acall);
     struct host *thost;
     struct client *t_client = NULL;    /* tmp ptr to client data */
-    struct timeval time;
     struct fsstats fsstats;
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS);
 
-    if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GetStatistics64;
 
+    if (statsVersion != STATS64_VERSION) {
+       code = EINVAL;
+       goto Bad_GetStatistics64;
+    }
+
     ViceLog(1, ("SAFS_GetStatistics64 Received\n"));
     Statistics->ViceStatistics64_val =
-       malloc(statsVersion*sizeof(afs_int64));
+       malloc(statsVersion*sizeof(afs_uint64));
     Statistics->ViceStatistics64_len = statsVersion;
     FS_LOCK;
     AFSCallStats.GetStatistics++, AFSCallStats.TotalCalls++;
@@ -5100,23 +5162,14 @@ SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatis
         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
+    Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] = opr_procsize();
     FS_UNLOCK;
     h_GetWorkStats64(&(Statistics->ViceStatistics64_val[STATS64_WORKSTATIONS]),
                      &(Statistics->ViceStatistics64_val[STATS64_ACTIVEWORKSTATIONS]),
                     0,
-                     (afs_int32) (FT_ApproxTime()) - (15 * 60));
-
-
+                     (afs_int32) (time(NULL)) - (15 * 60));
 
-    /* this works on all system types */
-    FT_GetTimeOfDay(&time, 0);
-    Statistics->ViceStatistics64_val[STATS64_CURRENTTIME] = time.tv_sec;
+    Statistics->ViceStatistics64_val[STATS64_CURRENTTIME] = time(NULL);
 
   Bad_GetStatistics64:
     code = CallPostamble(tcon, code, thost);
@@ -5126,7 +5179,7 @@ SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatis
     fsstats_FinishOp(&fsstats, code);
 
     osi_auditU(acall, GetStatisticsEvent, code,
-               AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0, AUD_END);
     return code;
 }                              /*SRXAFS_GetStatistics */
 
@@ -5168,7 +5221,7 @@ SRXAFS_XStatsVersion(struct rx_call * a_call, afs_int32 * a_versionP)
     fsstats_FinishOp(&fsstats, 0);
 
     osi_auditU(a_call, XStatsVersionEvent, 0,
-               AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0, AUD_END);
     return (0);
 }                              /*SRXAFS_XStatsVersion */
 
@@ -5333,82 +5386,54 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
                 afs_int32 * a_timeP, AFS_CollData * a_dataP)
 {                              /*SRXAFS_GetXStats */
 
+    struct client *t_client = NULL;    /* tmp ptr to client data */
+    struct rx_connection *tcon = rx_ConnectionOf(a_call);
     int code;          /*Return value */
     afs_int32 *dataBuffP;      /*Ptr to data to be returned */
     afs_int32 dataBytes;       /*Bytes in data buffer */
     struct fsstats fsstats;
 
-    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETXSTATS);
-
     /*
-     * Record the time of day and the server version number.
+     * Note: This function intentionally omits CallPreamble()
+     *       to avoid issuing TellMeAboutYourself() calls to
+     *       simple clients which are only gathering stats.
      */
-    *a_srvVersionNumP = AFS_XSTAT_VERSION;
-    *a_timeP = FT_ApproxTime();
 
-    /*
-     * Stuff the appropriate data in there (assume victory)
-     */
-    code = 0;
+    fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETXSTATS);
 
-    ViceLog(1,
-           ("Received GetXStats call for collection %d\n",
-            a_collectionNumber));
+    t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
 
-#if 0
-    /*
-     * We're not keeping stats, so just return successfully with
-     * no data.
-     */
-    a_dataP->AFS_CollData_len = 0;
-    a_dataP->AFS_CollData_val = NULL;
-#endif /* 0 */
+    /* Return the server's time of day and xstat version number. */
+    *a_srvVersionNumP = AFS_XSTAT_VERSION;
+    *a_timeP = (afs_int32) time(NULL);
+    code = 0;
+
+    osi_auditU(a_call, GetXStatsEvent,
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_INT, a_clientVersionNum,
+              AUD_INT, a_collectionNumber, AUD_END);
 
     switch (a_collectionNumber) {
     case AFS_XSTATSCOLL_CALL_INFO:
-       /*
-        * Pass back all the call-count-related data.
-        *
-        * >>> We are forced to allocate a separate area in which to
-        * >>> put this stuff in by the RPC stub generator, since it
-        * >>> will be freed at the tail end of the server stub code.
-        */
-#if 0
-       /*
-        * I don't think call-level stats are being collected yet
-        * for the File Server.
-        */
-       dataBytes = sizeof(struct afs_Stats);
-       dataBuffP = (afs_int32 *) malloc(dataBytes);
-       memcpy(dataBuffP, &afs_cmstats, dataBytes);
-       a_dataP->AFS_CollData_len = dataBytes >> 2;
-       a_dataP->AFS_CollData_val = dataBuffP;
-#else
+       /*  The call info collection type is not implemented. */
        a_dataP->AFS_CollData_len = 0;
        a_dataP->AFS_CollData_val = NULL;
-#endif /* 0 */
        break;
 
     case AFS_XSTATSCOLL_PERF_INFO:
        /*
         * Pass back all the regular performance-related data.
         *
-        * >>> We are forced to allocate a separate area in which to
-        * >>> put this stuff in by the RPC stub generator, since it
-        * >>> will be freed at the tail end of the server stub code.
+        * Allocate a separate area in which to put this stuff in
+        * by the RPC stub generator, since it will be freed at the
+        * tail end of the server stub code.
         */
-
        afs_perfstats.numPerfCalls++;
        FillPerfValues(&afs_perfstats);
-
-       /*
-        * Don't overwrite the spares at the end.
-        */
-
        dataBytes = sizeof(struct afs_PerfStats);
-       dataBuffP = (afs_int32 *) malloc(dataBytes);
+       dataBuffP = calloc(1, dataBytes);
        memcpy(dataBuffP, &afs_perfstats, dataBytes);
-       a_dataP->AFS_CollData_len = dataBytes >> 2;
+       a_dataP->AFS_CollData_len = dataBytes / sizeof(afs_int32);
        a_dataP->AFS_CollData_val = dataBuffP;
        break;
 
@@ -5418,23 +5443,17 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
         * We have to stuff the basic, overall numbers in, but the
         * detailed numbers are kept in the structure already.
         *
-        * >>> We are forced to allocate a separate area in which to
-        * >>> put this stuff in by the RPC stub generator, since it
-        * >>> will be freed at the tail end of the server stub code.
+        * Allocate a separate area in which to put this stuff in
+        * by the RPC stub generator, since it will be freed at the
+        * tail end of the server stub code.
         */
-
        afs_perfstats.numPerfCalls++;
        afs_FullPerfStats.overall.numPerfCalls = afs_perfstats.numPerfCalls;
        FillPerfValues(&afs_FullPerfStats.overall);
-
-       /*
-        * Don't overwrite the spares at the end.
-        */
-
        dataBytes = sizeof(struct fs_stats_FullPerfStats);
-       dataBuffP = (afs_int32 *) malloc(dataBytes);
+       dataBuffP = calloc(1, dataBytes);
        memcpy(dataBuffP, &afs_FullPerfStats, dataBytes);
-       a_dataP->AFS_CollData_len = dataBytes >> 2;
+       a_dataP->AFS_CollData_len = dataBytes / sizeof(afs_int32);
        a_dataP->AFS_CollData_val = dataBuffP;
        break;
 
@@ -5442,7 +5461,7 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
        afs_perfstats.numPerfCalls++;
 
        dataBytes = sizeof(struct cbcounters);
-       dataBuffP = (afs_int32 *) malloc(dataBytes);
+       dataBuffP = calloc(1, dataBytes);
        {
            extern struct cbcounters cbstuff;
            dataBuffP[0]=cbstuff.DeleteFiles;
@@ -5463,15 +5482,12 @@ SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
            dataBuffP[15]=cbstuff.GSS5;
        }
 
-       a_dataP->AFS_CollData_len = dataBytes >> 2;
+       a_dataP->AFS_CollData_len = dataBytes / sizeof(afs_int32);
        a_dataP->AFS_CollData_val = dataBuffP;
        break;
 
-
     default:
-       /*
-        * Illegal collection number.
-        */
+       /* Illegal collection number. */
        a_dataP->AFS_CollData_len = 0;
        a_dataP->AFS_CollData_val = NULL;
        code = 1;
@@ -5505,7 +5521,7 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
     FS_LOCK;
     AFSCallStats.GiveUpCallBacks++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GiveUpCallBacks;
 
     if (!FidArray && !CallBackArray) {
@@ -5515,7 +5531,7 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
        errorCode = GetClient(tcon, &client);
        if (!errorCode) {
            H_LOCK;
-           DeleteAllCallBacks_r(client->host, 1);
+           DeleteAllCallBacks_r(client->z.host, 1);
            H_UNLOCK;
            PutClient(&client);
        }
@@ -5533,7 +5549,7 @@ common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
        if (!errorCode) {
            for (i = 0; i < FidArray->AFSCBFids_len; i++) {
                struct AFSFid *fid = &(FidArray->AFSCBFids_val[i]);
-               DeleteCallBack(client->host, fid);
+               DeleteCallBack(client->z.host, fid);
            }
            PutClient(&client);
        }
@@ -5604,11 +5620,11 @@ SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
     FS_UNLOCK;
     ViceLog(2, ("SAFS_GetCapabilties\n"));
 
-    if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GetCaps;
 
     dataBytes = 1 * sizeof(afs_int32);
-    dataBuffP = (afs_uint32 *) malloc(dataBytes);
+    dataBuffP = malloc(dataBytes);
     dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS | VICED_CAPABILITY_WRITELOCKACL;
     dataBuffP[0] |= VICED_CAPABILITY_64BITFILES;
     if (saneacls)
@@ -5621,6 +5637,25 @@ SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
     code = CallPostamble(tcon, code, thost);
 
 
+    return code;
+}
+
+/* client is held, but not locked */
+static int
+FlushClientCPS(struct client *client, void *arock)
+{
+    ObtainWriteLock(&client->lock);
+
+    client->z.prfail = 2;      /* Means re-eval client's cps */
+
+    if ((client->z.ViceId != ANONYMOUSID) && client->z.CPS.prlist_val) {
+       free(client->z.CPS.prlist_val);
+       client->z.CPS.prlist_val = NULL;
+       client->z.CPS.prlist_len = 0;
+    }
+
+    ReleaseWriteLock(&client->lock);
+
     return 0;
 }
 
@@ -5633,12 +5668,17 @@ SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids,
     afs_int32 nids, naddrs;
     afs_int32 *vd, *addr;
     Error errorCode = 0;               /* return code to caller */
-    struct client *client = 0;
 
     ViceLog(1, ("SRXAFS_FlushCPS\n"));
     FS_LOCK;
     AFSCallStats.TotalCalls++;
     FS_UNLOCK;
+
+    if (!viced_SuperUser(acall)) {
+       errorCode = EPERM;
+       goto Bad_FlushCPS;
+    }
+
     nids = vids->ViceIds_len;  /* # of users in here */
     naddrs = addrs->IPAddrs_len;       /* # of hosts in here */
     if (nids < 0 || naddrs < 0) {
@@ -5650,23 +5690,7 @@ SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids,
     for (i = 0; i < nids; i++, vd++) {
        if (!*vd)
            continue;
-       client = h_ID2Client(*vd);      /* returns write locked and refCounted, or NULL */
-       if (!client)
-           continue;
-
-       client->prfail = 2;     /* Means re-eval client's cps */
-#ifdef notdef
-       if (client->tcon) {
-           rx_SetRock(((struct rx_connection *)client->tcon), 0);
-       }
-#endif
-       if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) {
-           free(client->CPS.prlist_val);
-           client->CPS.prlist_val = NULL;
-           client->CPS.prlist_len = 0;
-       }
-       ReleaseWriteLock(&client->lock);
-       PutClient(&client);
+       h_EnumerateClients(*vd, FlushClientCPS, NULL);
     }
 
     addr = addrs->IPAddrs_val;
@@ -5778,7 +5802,7 @@ TryLocalVLServer(char *avolid, struct VolumeInfo *avolinfo)
            rx_NewConnection(htonl(0x7f000001), htons(7003), 52, vlSec, 0);
        rx_SetConnDeadTime(vlConn, 15); /* don't wait long */
     }
-    if (down && (FT_ApproxTime() < lastDownTime + 180)) {
+    if (down && (time(NULL) < lastDownTime + 180)) {
        return 1;               /* failure */
     }
 
@@ -5787,7 +5811,7 @@ TryLocalVLServer(char *avolid, struct VolumeInfo *avolinfo)
        down = 0;               /* call worked */
     if (code) {
        if (code < 0) {
-           lastDownTime = FT_ApproxTime();     /* last time we tried an RPC */
+           lastDownTime = time(NULL);  /* last time we tried an RPC */
            down = 1;
        }
        return code;
@@ -5814,7 +5838,7 @@ SRXAFS_GetVolumeInfo(struct rx_call * acall, char *avolid,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMEINFO);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GetVolumeInfo;
 
     FS_LOCK;
@@ -5857,7 +5881,7 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMESTATUS);
 
     ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GetVolumeStatus;
 
     FS_LOCK;
@@ -5876,10 +5900,6 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
                          &rights, &anyrights)))
        goto Bad_GetVolumeStatus;
 
-    if ((VanillaUser(client)) && (!(rights & PRSFS_READ))) {
-       errorCode = EACCES;
-       goto Bad_GetVolumeStatus;
-    }
     (void)RXGetVolumeStatus(FetchVolStatus, Name, OfflineMsg, Motd, volptr);
 
   Bad_GetVolumeStatus:
@@ -5888,15 +5908,15 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     ViceLog(2, ("SAFS_GetVolumeStatus returns %d\n", errorCode));
     /* next is to guarantee out strings exist for stub */
     if (*Name == 0) {
-       *Name = (char *)malloc(1);
+       *Name = malloc(1);
        **Name = 0;
     }
     if (*Motd == 0) {
-       *Motd = (char *)malloc(1);
+       *Motd = malloc(1);
        **Motd = 0;
     }
     if (*OfflineMsg == 0) {
-       *OfflineMsg = (char *)malloc(1);
+       *OfflineMsg = malloc(1);
        **OfflineMsg = 0;
     }
     errorCode = CallPostamble(tcon, errorCode, thost);
@@ -5906,8 +5926,8 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     fsstats_FinishOp(&fsstats, errorCode);
 
     osi_auditU(acall, GetVolumeStatusEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_LONG, avolid, AUD_STR, *Name, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_LONG, avolid, AUD_STR, *Name, AUD_END);
     return (errorCode);
 
 }                              /*SRXAFS_GetVolumeStatus */
@@ -5933,7 +5953,7 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETVOLUMESTATUS);
 
     ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_SetVolumeStatus;
 
     FS_LOCK;
@@ -5952,7 +5972,7 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
                          &rights, &anyrights)))
        goto Bad_SetVolumeStatus;
 
-    if (readonlyServer) {
+    if (!IsWriteAllowed(client)) {
        errorCode = VREADONLY;
        goto Bad_SetVolumeStatus;
     }
@@ -5975,8 +5995,8 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     fsstats_FinishOp(&fsstats, errorCode);
 
     osi_auditU(acall, SetVolumeStatusEvent, errorCode,
-               AUD_ID, t_client ? t_client->ViceId : 0,
-               AUD_LONG, avolid, AUD_STR, Name, AUD_END);
+              AUD_ID, t_client ? t_client->z.ViceId : 0,
+              AUD_LONG, avolid, AUD_STR, Name, AUD_END);
     return (errorCode);
 }                              /*SRXAFS_SetVolumeStatus */
 
@@ -5985,14 +6005,6 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
 afs_int32
 SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
 {
-#ifdef notdef
-    int fd;
-    int len;
-    char *temp;
-    struct rx_connection *tcon;
-    struct host *thost;
-    Error errorCode = 0;
-#endif
     struct fsstats fsstats;
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETROOTVOLUME);
@@ -6000,7 +6012,7 @@ SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
     return FSERR_EOPNOTSUPP;
 
 #ifdef notdef
-    if (errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost))
+    if (errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost))
        goto Bad_GetRootVolume;
     FS_LOCK;
     AFSCallStats.GetRootVolume++, AFSCallStats.TotalCalls++;
@@ -6039,7 +6051,6 @@ SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
 }                              /*SRXAFS_GetRootVolume */
 
 
-/* still works because a struct CBS is the same as a struct AFSOpaque */
 afs_int32
 SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
                  struct AFSOpaque * Token)
@@ -6051,7 +6062,7 @@ SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_CHECKTOKEN);
 
-    if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_CheckToken;
 
     code = FSERR_ECONNREFUSED;
@@ -6077,13 +6088,13 @@ SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
 
     fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETTIME);
 
-    if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+    if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
        goto Bad_GetTime;
 
     FS_LOCK;
     AFSCallStats.GetTime++, AFSCallStats.TotalCalls++;
     FS_UNLOCK;
-    FT_GetTimeOfDay(&tpl, 0);
+    gettimeofday(&tpl, 0);
     *Seconds = tpl.tv_sec;
     *USeconds = tpl.tv_usec;
 
@@ -6157,13 +6168,13 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
        rx_Write(Call, (char *)&zero, sizeof(afs_int32));       /* send 0-length  */
        return (0);
     }
-    FT_GetTimeOfDay(&StartTime, 0);
+    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));
+       ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                   afs_printable_VolumeId_lu(volptr->hashid)));
        return EIO;
     }
     optSize = sendBufSize;
@@ -6173,8 +6184,8 @@ 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));
+       ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                   afs_printable_VolumeId_lu(volptr->hashid)));
        return EIO;
     }
     if (CheckLength(volptr, targetptr, tlen)) {
@@ -6192,7 +6203,7 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     {
        afs_int32 high, low;
        SplitOffsetOrSize(Len, high, low);
-       osi_Assert(Int64Mode || (Len >= 0 && high == 0) || Len < 0);
+       opr_Assert(Int64Mode || (Len >= 0 && high == 0) || Len < 0);
        if (Int64Mode) {
            high = htonl(high);
            rx_Write(Call, (char *)&high, sizeof(afs_int32));   /* High order bits */
@@ -6217,8 +6228,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));
+           ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                       afs_printable_VolumeId_lu(volptr->hashid)));
            return EIO;
        }
        nBytes = rx_Write(Call, tbuffer, wlen);
@@ -6233,8 +6244,8 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
        if (nBytes != wlen) {
            FDH_CLOSE(fdP);
            VTakeOffline(volptr);
-           ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
-                       volptr->hashid));
+           ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                       afs_printable_VolumeId_lu(volptr->hashid)));
            return EIO;
        }
        nBytes = rx_Writev(Call, tiov, tnio, wlen);
@@ -6263,7 +6274,7 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
     FreeSendBuffer((struct afs_buffer *)tbuffer);
 #endif /* HAVE_PIOV */
     FDH_CLOSE(fdP);
-    FT_GetTimeOfDay(&StopTime, 0);
+    gettimeofday(&StopTime, 0);
 
     /* Adjust all Fetch Data related stats */
     FS_LOCK;
@@ -6304,7 +6315,7 @@ GetLinkCountAndSize(Volume * vp, FdHandle_t * fdP, int *lc,
     FDH_CLOSE(lhp);
     if (*lc < 0)
        return -1;
-    *size = OS_SIZE(fdP->fd_fd);
+    *size = FDH_SIZE(fdP);
     return (*size == -1) ? -1 : 0;
 #else
     struct afs_stat status;
@@ -6345,7 +6356,6 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
                  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 */
     Error errorCode = 0;               /* Returned error code to caller */
 #ifndef HAVE_PIOV
     char *tbuffer;     /* data copying buffer */
@@ -6376,7 +6386,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
      * We break the callbacks here so that the following signal will not
      * leave a window.
      */
-    BreakCallBack(client->host, Fid, 0);
+    BreakCallBack(client->z.host, Fid, 0);
 
     if (Pos == -1 || VN_GET_INO(targetptr) == 0) {
        /* the inode should have been created in Alloc_NewVnode */
@@ -6388,7 +6398,6 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
                 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(rx_ConnectionOf(Call)))));
        return ENOENT;          /* is this proper error code? */
     } else {
-       rx_KeepAliveOff(Call);
        /*
         * See if the file has several links (from other volumes).  If it
         * does, then we have to make a copy before changing it to avoid
@@ -6403,8 +6412,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));
+           ViceLog(0, ("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                       afs_printable_VolumeId_lu(volptr->hashid)));
            return EIO;
        }
        if (CheckLength(volptr, targetptr, DataLength)) {
@@ -6455,8 +6464,8 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     }
     if (!VALID_INO(tinode)) {
        VTakeOffline(volptr);
-       ViceLog(0,("Volume %u now offline, must be salvaged.\n",
-                  volptr->hashid));
+       ViceLog(0,("Volume %" AFS_VOLID_FMT " now offline, must be salvaged.\n",
+                  afs_printable_VolumeId_lu(volptr->hashid)));
        return EIO;
     }
 
@@ -6486,21 +6495,23 @@ 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);
 
-    FT_GetTimeOfDay(&StartTime, 0);
-
     optSize = sendBufSize;
     ViceLog(25,
            ("StoreData_RXStyle: Pos %llu, DataLength %llu, FileLength %llu, Length %llu\n",
             (afs_uintmax_t) Pos, (afs_uintmax_t) DataLength,
             (afs_uintmax_t) FileLength, (afs_uintmax_t) Length));
 
-    /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
-    if (FileLength < DataLength)
-       FDH_TRUNC(fdP, FileLength);
     bytesTransfered = 0;
 #ifndef HAVE_PIOV
     tbuffer = AllocSendBuffer();
 #endif /* HAVE_PIOV */
+    /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
+    if (FileLength < DataLength) {
+       errorCode = FDH_TRUNC(fdP, FileLength);
+       if (errorCode)
+           goto done;
+    }
+
     /* 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
@@ -6512,6 +6523,7 @@ 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.
         */
+       tlen = 0; /* Just a source of data for the write */
        nBytes = FDH_PWRITE(fdP, &tlen, 1, Pos);
        if (nBytes != 1) {
            errorCode = -1;
@@ -6566,7 +6578,7 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     if (errorCode) {
        Error tmp_errorCode = 0;
        afs_sfsize_t nfSize = FDH_SIZE(fdP);
-       osi_Assert(nfSize >= 0);
+       opr_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
@@ -6585,8 +6597,6 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
     }
     FDH_CLOSE(fdP);
 
-    FT_GetTimeOfDay(&StopTime, 0);
-
     VN_SET_LEN(targetptr, NewLength);
 
     /* Update all StoreData related stats */
@@ -6745,6 +6755,13 @@ init_sys_error_to_et(void)
     sys2et[EDQUOT] = UAEDQUOT;
     sys2et[ENOMEDIUM] = UAENOMEDIUM;
     sys2et[EMEDIUMTYPE] = UAEMEDIUMTYPE;
+    sys2et[ECANCELED] = UAECANCELED;
+    sys2et[ENOTRECOVERABLE] = UAENOTRECOVERABLE;
+    sys2et[ENOTSUP] = UAENOTSUP;
+    sys2et[EOTHER] = UAEOTHER;
+    sys2et[EOWNERDEAD] = UAEOWNERDEAD;
+    sys2et[EPROCLIM] = UAEPROCLIM;
+    sys2et[EDISCON] = UAEDISCON;
 
     sys2et[EIO] = UAEIO;
 }
@@ -6774,59 +6791,61 @@ SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
     static struct rx_securityClass *sc = 0;
     int i,j;
     struct rx_connection *conn;
+    afs_int32 viceid = -1;
 #endif
 
-    if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &tcallhost)))
+    if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &tcallhost)))
            goto Bad_CallBackRxConnAddr1;
 
 #ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
     errorCode = 1;
 #else
     H_LOCK;
-    tclient = h_FindClient_r(tcon);
+    tclient = h_FindClient_r(tcon, &viceid);
     if (!tclient) {
        errorCode = VBUSY;
+       LogClientError("Client host too busy (CallBackRxConnAddr)", tcon, viceid, NULL);
        goto Bad_CallBackRxConnAddr;
     }
-    thost = tclient->host;
+    thost = tclient->z.host;
 
     /* nothing more can be done */
-    if ( !thost->interface )
+    if ( !thost->z.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->z.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++)
+    for ( i=0; i < thost->z.interface->numberOfInterfaces; i++)
     {
-           if ( *addr == thost->interface->addr[i] ) {
+           if ( *addr == thost->z.interface->addr[i] ) {
                    break;
            }
     }
 
-    if ( *addr != thost->interface->addr[i] )
+    if ( *addr != thost->z.interface->addr[i] )
        goto Bad_CallBackRxConnAddr;
 
-    conn = rx_NewConnection (thost->interface->addr[i],
-                            thost->port, 1, sc, 0);
+    conn = rx_NewConnection (thost->z.interface->addr[i],
+                            thost->z.port, 1, sc, 0);
     rx_SetConnDeadTime(conn, 2);
     rx_SetConnHardDeadTime(conn, AFS_HARDDEADTIME);
     H_UNLOCK;
     errorCode = RXAFSCB_Probe(conn);
     H_LOCK;
     if (!errorCode) {
-       if ( thost->callback_rxcon )
-           rx_DestroyConnection(thost->callback_rxcon);
-       thost->callback_rxcon = conn;
-       thost->host           = addr;
-       rx_SetConnDeadTime(thost->callback_rxcon, 50);
-       rx_SetConnHardDeadTime(thost->callback_rxcon, AFS_HARDDEADTIME);
+       if ( thost->z.callback_rxcon )
+           rx_DestroyConnection(thost->z.callback_rxcon);
+       thost->z.callback_rxcon = conn;
+       thost->z.host           = addr;
+       rx_SetConnDeadTime(thost->z.callback_rxcon, 50);
+       rx_SetConnHardDeadTime(thost->z.callback_rxcon, AFS_HARDDEADTIME);
        h_ReleaseClient_r(tclient);
        /* The hold on thost will be released by CallPostamble */
        H_UNLOCK;