vol, volser, and viced type fixes
[openafs.git] / src / volser / volprocs.c
index 5dc071f..b55af40 100644 (file)
@@ -12,8 +12,6 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -62,19 +60,21 @@ RCSID
 #include <afs/acl.h>
 #include "afs/audit.h"
 #include <afs/dir.h>
+#include <afs/afsutil.h>
+#include <afs/vol_prototypes.h>
+#include <afs/errors.h>
 
 #include "volser.h"
+#include "voltrans_inline.h"
 #include "volint.h"
 
-#include "volser_prototypes.h"
+#include "volser_internal.h"
+#include "physio.h"
+#include "dumpstuff.h"
 
 extern int DoLogging;
-extern struct volser_trans *FindTrans(), *NewTrans(), *TransList();
 extern struct afsconf_dir *tdir;
 
-/* Needed by Irix. Leave, or include a header */
-extern char *volutil_PartitionName();
-
 extern void LogError(afs_int32 errcode);
 
 /* Forward declarations */
@@ -87,20 +87,54 @@ static int GetPartName(afs_int32 partid, char *pname);
 #endif
 
 afs_int32 localTid = 1;
-afs_int32 VolPartitionInfo(), VolNukeVolume(), VolCreateVolume(),
-VolDeleteVolume(), VolClone();
-afs_int32 VolReClone(), VolTransCreate(), VolGetNthVolume(), VolGetFlags(),
-VolForward(), VolDump();
-afs_int32 VolRestore(), VolEndTrans(), VolSetForwarding(), VolGetStatus(),
-VolSetInfo(), VolGetName();
-afs_int32 VolListPartitions(), VolListOneVolume(),
-VolXListOneVolume(), VolXListVolumes();
-afs_int32 VolListVolumes(), XVolListPartitions(), VolMonitor(),
-VolSetIdsTypes(), VolSetDate(), VolSetFlags();
+static afs_int32 VolPartitionInfo(struct rx_call *, char *pname,
+                                 struct diskPartition64 *);
+static afs_int32 VolNukeVolume(struct rx_call *, afs_int32, afs_uint32);
+static afs_int32 VolCreateVolume(struct rx_call *, afs_int32, char *,
+                                afs_int32, afs_uint32, afs_uint32 *,
+                                afs_int32 *);
+static afs_int32 VolDeleteVolume(struct rx_call *, afs_int32);
+static afs_int32 VolClone(struct rx_call *, afs_int32, afs_uint32,
+                         afs_int32, char *, afs_uint32 *);
+static afs_int32 VolReClone(struct rx_call *, afs_int32, afs_int32);
+static afs_int32 VolTransCreate(struct rx_call *, afs_uint32, afs_int32,
+                               afs_int32, afs_int32 *);
+static afs_int32 VolGetNthVolume(struct rx_call *, afs_int32, afs_uint32 *,
+                                afs_int32 *);
+static afs_int32 VolGetFlags(struct rx_call *, afs_int32, afs_int32 *);
+static afs_int32 VolSetFlags(struct rx_call *, afs_int32, afs_int32 );
+static afs_int32 VolForward(struct rx_call *, afs_int32, afs_int32,
+                           struct destServer *destination, afs_int32,
+                           struct restoreCookie *cookie);
+static afs_int32 VolDump(struct rx_call *, afs_int32, afs_int32, afs_int32);
+static afs_int32 VolRestore(struct rx_call *, afs_int32, afs_int32,
+                           struct restoreCookie *);
+static afs_int32 VolEndTrans(struct rx_call *, afs_int32, afs_int32 *);
+static afs_int32 VolSetForwarding(struct rx_call *, afs_int32, afs_int32);
+static afs_int32 VolGetStatus(struct rx_call *, afs_int32,
+                             struct volser_status *);
+static afs_int32 VolSetInfo(struct rx_call *, afs_int32, struct volintInfo *);
+static afs_int32 VolGetName(struct rx_call *, afs_int32, char **);
+static afs_int32 VolListPartitions(struct rx_call *, struct pIDs *);
+static afs_int32 XVolListPartitions(struct rx_call *, struct partEntries *);
+static afs_int32 VolListOneVolume(struct rx_call *, afs_int32, afs_uint32,
+                                 volEntries *);
+static afs_int32 VolXListOneVolume(struct rx_call *, afs_int32, afs_uint32,
+                                  volXEntries *);
+static afs_int32 VolListVolumes(struct rx_call *, afs_int32, afs_int32,
+                               volEntries *);
+static afs_int32 VolXListVolumes(struct rx_call *, afs_int32, afs_int32,
+                               volXEntries *);
+static afs_int32 VolMonitor(struct rx_call *, transDebugEntries *);
+static afs_int32 VolSetIdsTypes(struct rx_call *, afs_int32, char [],
+                               afs_int32, afs_uint32, afs_uint32,
+                               afs_uint32);
+static afs_int32 VolSetDate(struct rx_call *, afs_int32, afs_int32);
 
 /* this call unlocks all of the partition locks we've set */
 int 
-VPFullUnlock()
+VPFullUnlock_r(void)
 {
     register struct DiskPartition64 *tp;
     for (tp = DiskPartitionList; tp; tp = tp->next) {
@@ -112,6 +146,16 @@ VPFullUnlock()
     return 0;
 }
 
+int
+VPFullUnlock(void)
+{
+    int code;
+    VOL_LOCK;
+    code = VPFullUnlock_r();
+    VOL_UNLOCK;
+    return code;
+}
+
 /* get partition id from a name */
 afs_int32
 PartitionID(char *aname)
@@ -180,12 +224,70 @@ ConvertPartition(int apartno, char *aname, int asize)
     return 0;
 }
 
+static struct Volume *
+VAttachVolumeByName_retry(Error *ec, char *partition, char *name, int mode)
+{
+    struct Volume *vp;
+
+    *ec = 0;
+    vp = VAttachVolumeByName(ec, partition, name, mode);
+
+#ifdef AFS_DEMAND_ATTACH_FS
+    {
+        int i;
+        /*
+         * The fileserver will take care of keeping track of how many
+         * demand-salvages have been performed, and will force the volume to
+         * ERROR if we've done too many. The limit on This loop is just a
+         * failsafe to prevent trying to salvage forever. We want to attempt
+         * attachment at least SALVAGE_COUNT_MAX times, since we want to
+         * avoid prematurely exiting this loop, if we can.
+         */
+        for (i = 0; i < SALVAGE_COUNT_MAX*2 && *ec == VSALVAGING; i++) {
+            sleep(SALVAGE_PRIO_UPDATE_INTERVAL);
+            vp = VAttachVolumeByName(ec, partition, name, mode);
+        }
+
+        if (*ec == VSALVAGING) {
+            *ec = VSALVAGE;
+        }
+    }
+#endif /* AFS_DEMAND_ATTACH_FS */
+
+    return vp;
+}
+
+static struct Volume *
+VAttachVolume_retry(Error *ec, afs_uint32 avolid, int amode)
+{
+    struct Volume *vp;
+
+    *ec = 0;
+    vp = VAttachVolume(ec, avolid, amode);
+
+#ifdef AFS_DEMAND_ATTACH_FS
+    {
+        int i;
+        /* see comment above in VAttachVolumeByName_retry */
+        for (i = 0; i < SALVAGE_COUNT_MAX*2 && *ec == VSALVAGING; i++) {
+            sleep(SALVAGE_PRIO_UPDATE_INTERVAL);
+            vp = VAttachVolume(ec, avolid, amode);
+        }
+
+        if (*ec == VSALVAGING) {
+            *ec = VSALVAGE;
+        }
+    }
+#endif /* AFS_DEMAND_ATTACH_FS */
+
+    return vp;
+}
+
 /* the only attach function that takes a partition is "...ByName", so we use it */
-struct Volume *
+static struct Volume *
 XAttachVolume(afs_int32 *error, afs_uint32 avolid, afs_int32 apartid, int amode)
 {
     char pbuf[30], vbuf[20];
-    register struct Volume *tv;
 
     if (ConvertPartition(apartid, pbuf, sizeof(pbuf))) {
        *error = EINVAL;
@@ -195,8 +297,8 @@ XAttachVolume(afs_int32 *error, afs_uint32 avolid, afs_int32 apartid, int amode)
        *error = EINVAL;
        return NULL;
     }
-    tv = VAttachVolumeByName((Error *)error, pbuf, vbuf, amode);
-    return tv;
+
+    return VAttachVolumeByName_retry((Error *)error, pbuf, vbuf, amode);
 }
 
 /* Adapted from the file server; create a root directory for this volume */
@@ -205,14 +307,15 @@ ViceCreateRoot(Volume *vp)
 {
     DirHandle dir;
     struct acl_accessList *ACL;
-    ViceFid did;
+    AFSFid did;
     Inode inodeNumber, nearInode;
     struct VnodeDiskObject *vnode;
     struct VnodeClassInfo *vcp = &VnodeClassInfo[vLarge];
     IHandle_t *h;
     FdHandle_t *fdP;
-    int code;
     afs_fsize_t length;
+    ssize_t nBytes;
+    afs_foff_t off;
 
     vnode = (struct VnodeDiskObject *)malloc(SIZEOF_LARGEDISKVNODE);
     if (!vnode)
@@ -272,10 +375,10 @@ ViceCreateRoot(Volume *vp)
            vp->vnodeIndex[vLarge].handle->ih_ino);
     fdP = IH_OPEN(h);
     assert(fdP != NULL);
-    code = FDH_SEEK(fdP, vnodeIndexOffset(vcp, 1), SEEK_SET);
-    assert(code >= 0);
-    code = FDH_WRITE(fdP, vnode, SIZEOF_LARGEDISKVNODE);
-    assert(code == SIZEOF_LARGEDISKVNODE);
+    off = FDH_SEEK(fdP, vnodeIndexOffset(vcp, 1), SEEK_SET);
+    assert(off >= 0);
+    nBytes = FDH_WRITE(fdP, vnode, SIZEOF_LARGEDISKVNODE);
+    assert(nBytes == SIZEOF_LARGEDISKVNODE);
     FDH_REALLYCLOSE(fdP);
     IH_RELEASE(h);
     VNDISK_GET_LEN(length, vnode);
@@ -350,11 +453,12 @@ SAFSVolNukeVolume(struct rx_call *acid, afs_int32 apartID, afs_uint32 avolID)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolNukeVolume(struct rx_call *acid, afs_int32 apartID, afs_uint32 avolID)
 {
     char partName[50];
     afs_int32 error;
+    Error verror;
     register afs_int32 code;
     struct Volume *tvp;
     char caller[MAXKTCNAMELEN];
@@ -374,7 +478,7 @@ VolNukeVolume(struct rx_call *acid, afs_int32 apartID, afs_uint32 avolID)
     tvp = XAttachVolume(&error, avolID, apartID, V_VOLUPD);
     code = nuke(partName, avolID);
     if (tvp)
-       VDetachVolume(&error, tvp);
+       VDetachVolume(&verror, tvp);
     return code;
 }
 
@@ -399,14 +503,14 @@ SAFSVolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname, 
                    afs_int32 atype, afs_uint32 aparent, afs_uint32 *avolid, 
                    afs_int32 *atrans)
 {
-    afs_int32 error;
+    Error error;
     register Volume *vp;
-    afs_int32 junk;            /* discardable error code */
+    Error junk;                /* discardable error code */
     afs_uint32 volumeID;
     afs_int32 doCreateRoot = 1;
     register struct volser_trans *tt;
@@ -465,12 +569,13 @@ VolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname,
        VDetachVolume(&junk, vp);       /* rather return the real error code */
        return error;
     }
+    VTRANS_OBJ_LOCK(tt);
     tt->volume = vp;
     *atrans = tt->tid;
-    strcpy(tt->lastProcName, "CreateVolume");
-    tt->rxCallPtr = acid;
+    TSetRxCall_r(tt, acid, "CreateVolume");
+    VTRANS_OBJ_UNLOCK(tt);
     Log("1 Volser: CreateVolume: volume %u (%s) created\n", volumeID, aname);
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
     return 0;
@@ -487,11 +592,11 @@ SAFSVolDeleteVolume(struct rx_call *acid, afs_int32 atrans)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolDeleteVolume(struct rx_call *acid, afs_int32 atrans)
 {
     register struct volser_trans *tt;
-    afs_int32 error;
+    Error error;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(tdir, acid, caller))
@@ -506,12 +611,13 @@ VolDeleteVolume(struct rx_call *acid, afs_int32 atrans)
     }
     if (DoLogging)
        Log("%s is executing Delete Volume %u\n", caller, tt->volid);
-    strcpy(tt->lastProcName, "DeleteVolume");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "DeleteVolume");
     VPurgeVolume(&error, tt->volume);  /* don't check error code, it is not set! */
     V_destroyMe(tt->volume) = DESTROY_ME; /* so endtrans does the right fssync opcode */
+    VTRANS_OBJ_LOCK(tt);
     tt->vflags |= VTDeleted;   /* so we know not to do anything else to it */
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall_r(tt);
+    VTRANS_OBJ_UNLOCK(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -521,12 +627,13 @@ VolDeleteVolume(struct rx_call *acid, afs_int32 atrans)
 
 /* make a clone of the volume associated with atrans, possibly giving it a new
  * number (allocate a new number if *newNumber==0, otherwise use *newNumber
- * for the clone's id).  The new clone is given the name newName.  Finally, due to
- * efficiency considerations, if purgeId is non-zero, we purge that volume when doing
- * the clone operation.  This may be useful when making new backup volumes, for instance
- * since the net result of a clone and a purge generally leaves many inode ref counts
- * the same, while doing them separately would result in far more iincs and idecs being
- * peformed (and they are slow operations).
+ * for the clone's id).  The new clone is given the name newName.  Finally,
+ * due to efficiency considerations, if purgeId is non-zero, we purge that
+ * volume when doing the clone operation.  This may be useful when making
+ * new backup volumes, for instance since the net result of a clone and a
+ * purge generally leaves many inode ref counts the same, while doing them
+ * separately would result in far more iincs and idecs being peformed
+ * (and they are slow operations).
  */
 /* for efficiency reasons, sometimes faster to piggyback a purge here */
 afs_int32
@@ -542,7 +649,7 @@ SAFSVolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId, 
             afs_int32 newType, char *newName, afs_uint32 *newNumber)
 {
@@ -583,14 +690,13 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
     ttc = NewTrans(newId, tt->partition);
     if (!ttc) {                        /* someone is messing with the clone already */
        TRELE(tt);
-       return VBUSY;
+       return VOLSERVOLBUSY;
     }
-    strcpy(tt->lastProcName, "Clone");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "Clone");
 
 
     if (purgeId) {
-       purgevp = VAttachVolume(&error, purgeId, V_VOLUPD);
+       purgevp = VAttachVolume_retry(&error, purgeId, V_VOLUPD);
        if (error) {
            Log("1 Volser: Clone: Could not attach 'purge' volume %u; clone aborted\n", purgeId);
            goto fail;
@@ -691,7 +797,7 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
        LogError(error);
        goto fail;
     }
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt)) {
        tt = (struct volser_trans *)0;
        error = VOLSERTRELE_ERROR;
@@ -706,7 +812,7 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
     if (newvp)
        VDetachVolume(&code, newvp);
     if (tt) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
     }
     if (ttc)
@@ -726,7 +832,7 @@ SAFSVolReClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 cloneId)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId)
 {
     register struct Volume *originalvp, *clonevp;
@@ -755,10 +861,9 @@ VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId)
     ttc = NewTrans(cloneId, tt->partition);
     if (!ttc) {                        /* someone is messing with the clone already */
        TRELE(tt);
-       return VBUSY;
+       return VOLSERVOLBUSY;
     }
-    strcpy(tt->lastProcName, "ReClone");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "ReClone");
 
     originalvp = tt->volume;
     if ((V_type(originalvp) == backupVolume)
@@ -774,7 +879,7 @@ VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId)
        goto fail;
     }
 
-    clonevp = VAttachVolume(&error, cloneId, V_VOLUPD);
+    clonevp = VAttachVolume_retry(&error, cloneId, V_VOLUPD);
     if (error) {
        Log("1 Volser: can't attach clone %d\n", cloneId);
        goto fail;
@@ -858,7 +963,7 @@ VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId)
        LogError(error);
        goto fail;
     }
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt)) {
        tt = (struct volser_trans *)0;
        error = VOLSERTRELE_ERROR;
@@ -877,7 +982,7 @@ VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId)
     if (clonevp)
        VDetachVolume(&code, clonevp);
     if (tt) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
     }
     if (ttc)
@@ -901,13 +1006,14 @@ SAFSVolTransCreate(struct rx_call *acid, afs_uint32 volume, afs_int32 partition,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolTransCreate(struct rx_call *acid, afs_uint32 volume, afs_int32 partition,
                   afs_int32 iflags, afs_int32 *ttid)
 {
     register struct volser_trans *tt;
     register Volume *tv;
-    afs_int32 error, code;
+    afs_int32 error;
+    Error code;
     afs_int32 mode;
     char caller[MAXKTCNAMELEN];
 
@@ -941,11 +1047,13 @@ VolTransCreate(struct rx_call *acid, afs_uint32 volume, afs_int32 partition,
        DeleteTrans(tt, 1);
        return error;
     }
+    VTRANS_OBJ_LOCK(tt);
     tt->volume = tv;
     *ttid = tt->tid;
     tt->iflags = iflags;
     tt->vflags = 0;
-    strcpy(tt->lastProcName, "TransCreate");
+    TSetRxCall_r(tt, NULL, "TransCreate");
+    VTRANS_OBJ_UNLOCK(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -966,8 +1074,8 @@ SAFSVolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_uint32 *avolume,
     return code;
 }
 
-afs_int32
-VolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_int32 *avolume,
+static afs_int32
+VolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_uint32 *avolume,
                    afs_int32 *apart)
 {
     Log("1 Volser: GetNthVolume: Not yet implemented\n");
@@ -987,7 +1095,7 @@ SAFSVolGetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 *aflags)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolGetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 *aflags)
 {
     register struct volser_trans *tt;
@@ -1001,10 +1109,9 @@ VolGetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 *aflags)
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "GetFlags");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "GetFlags");
     *aflags = tt->vflags;
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -1026,12 +1133,12 @@ SAFSVolSetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 aflags)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolSetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 aflags)
 {
     register struct volser_trans *tt;
     register struct Volume *vp;
-    afs_int32 error;
+    Error error;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(tdir, acid, caller))
@@ -1046,8 +1153,7 @@ VolSetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 aflags)
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "SetFlags");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "SetFlags");
     vp = tt->volume;           /* pull volume out of transaction */
 
     /* check if we're allowed to make any updates */
@@ -1069,8 +1175,10 @@ VolSetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 aflags)
        V_inService(vp) = 1;
     }
     VUpdateVolume(&error, vp);
+    VTRANS_OBJ_LOCK(tt);
     tt->vflags = aflags;
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall_r(tt);
+    VTRANS_OBJ_UNLOCK(tt);
     if (TRELE(tt) && !error)
        return VOLSERTRELE_ERROR;
 
@@ -1095,7 +1203,7 @@ SAFSVolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
               struct destServer *destination, afs_int32 destTrans, 
               struct restoreCookie *cookie)
@@ -1125,7 +1233,7 @@ VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
        return ENOENT;
     }
     vp = tt->volume;
-    strcpy(tt->lastProcName, "Forward");
+    TSetRxCall(tt, NULL, "Forward");
 
     /* get auth info for the this connection (uses afs from ticket file) */
     code = afsconf_ClientAuth(tdir, &securityObject, &securityIndex);
@@ -1140,12 +1248,12 @@ VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
                         htons(destination->destPort), VOLSERVICE_ID,
                         securityObject, securityIndex);
     if (!tcon) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
        return ENOTCONN;
     }
     tcall = rx_NewCall(tcon);
-    tt->rxCallPtr = tcall;
+    TSetRxCall(tt, tcall, "Forward");
     /* start restore going.  fromdate == 0 --> doing an incremental dump/restore */
     code = StartAFSVolRestore(tcall, destTrans, (fromDate ? 1 : 0), cookie);
     if (code) {
@@ -1157,7 +1265,7 @@ VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
     if (code)
        goto fail;
     EndAFSVolRestore(tcall);   /* probably doesn't do much */
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     code = rx_EndCall(tcall, 0);
     rx_DestroyConnection(tcon);        /* done with the connection */
     tcon = NULL;
@@ -1174,7 +1282,7 @@ VolForward(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
        rx_DestroyConnection(tcon);
     }
     if (tt) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
     }
     return code;
@@ -1225,7 +1333,7 @@ SAFSVolForwardMultiple(struct rx_call *acid, afs_int32 fromTrans, afs_int32
        return ENOENT;
     }
     vp = tt->volume;
-    strcpy(tt->lastProcName, "ForwardMulti");
+    TSetRxCall(tt, NULL, "ForwardMulti");
 
     /* (fromDate == 0) ==> full dump */
     is_incremental = (fromDate ? 1 : 0);
@@ -1301,7 +1409,7 @@ SAFSVolForwardMultiple(struct rx_call *acid, afs_int32 fromTrans, afs_int32
     free(tcalls);
 
     if (tt) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        if (TRELE(tt) && !code) /* return the first code if it's set */
            return VOLSERTRELE_ERROR;
     }
@@ -1320,7 +1428,8 @@ SAFSVolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate)
 }
 
 afs_int32
-SAFSVolDumpV2(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
+SAFSVolDumpV2(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
+             afs_int32 flags)
 {
     afs_int32 code;
 
@@ -1329,8 +1438,9 @@ SAFSVolDumpV2(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs
     return code;
 }
 
-afs_int32
-VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32 flags)
+static afs_int32
+VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
+       afs_int32 flags)
 {
     int code = 0;
     register struct volser_trans *tt;
@@ -1346,16 +1456,15 @@ VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "Dump");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "Dump");
     code = DumpVolume(acid, tt->volume, fromDate, (flags & VOLDUMPV2_OMITDIRS)
                      ? 0 : 1); /* squirt out the volume's data, too */
     if (code) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
        return code;
     }
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
 
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
@@ -1367,7 +1476,7 @@ VolDump(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate, afs_int32
  * Ha!  No more helper process!
  */
 afs_int32
-SAFSVolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags, 
+SAFSVolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags,
               struct restoreCookie *cookie)
 {
     afs_int32 code;
@@ -1377,9 +1486,9 @@ SAFSVolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags,
     return code;
 }
 
-afs_int32
-VolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags, 
-              struct restoreCookie *cookie)
+static afs_int32
+VolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags,
+          struct restoreCookie *cookie)
 {
     register struct volser_trans *tt;
     register afs_int32 code, tcode;
@@ -1395,14 +1504,13 @@ VolRestore(struct rx_call *acid, afs_int32 atrans, afs_int32 aflags,
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "Restore");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "Restore");
 
     DFlushVolume(V_parentId(tt->volume)); /* Ensure dir buffers get dropped */
 
     code = RestoreVolume(acid, tt->volume, (aflags & 1), cookie);      /* last is incrementalp */
     FSYNC_VolOp(tt->volid, NULL, FSYNC_VOL_BREAKCBKS, 0l, NULL);
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     tcode = TRELE(tt);
 
     return (code ? code : tcode);
@@ -1419,7 +1527,7 @@ SAFSVolEndTrans(struct rx_call *acid, afs_int32 destTrans, afs_int32 *rcode)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolEndTrans(struct rx_call *acid, afs_int32 destTrans, afs_int32 *rcode)
 {
     register struct volser_trans *tt;
@@ -1448,7 +1556,7 @@ SAFSVolSetForwarding(struct rx_call *acid, afs_int32 atid, afs_int32 anewsite)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolSetForwarding(struct rx_call *acid, afs_int32 atid, afs_int32 anewsite)
 {
     register struct volser_trans *tt;
@@ -1466,13 +1574,12 @@ VolSetForwarding(struct rx_call *acid, afs_int32 atid, afs_int32 anewsite)
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "SetForwarding");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "SetForwarding");
     if (volutil_PartitionName2_r(tt->partition, partName, sizeof(partName)) != 0) {
        partName[0] = '\0';
     }
     FSYNC_VolOp(tt->volid, partName, FSYNC_VOL_MOVE, anewsite, NULL);
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -1480,7 +1587,7 @@ VolSetForwarding(struct rx_call *acid, afs_int32 atid, afs_int32 anewsite)
 }
 
 afs_int32
-SAFSVolGetStatus(struct rx_call *acid, afs_int32 atrans, 
+SAFSVolGetStatus(struct rx_call *acid, afs_int32 atrans,
                 register struct volser_status *astatus)
 {
     afs_int32 code;
@@ -1490,9 +1597,9 @@ SAFSVolGetStatus(struct rx_call *acid, afs_int32 atrans,
     return code;
 }
 
-afs_int32
-VolGetStatus(struct rx_call *acid, afs_int32 atrans, 
-                register struct volser_status *astatus)
+static afs_int32
+VolGetStatus(struct rx_call *acid, afs_int32 atrans,
+            register struct volser_status *astatus)
 {
     register struct Volume *tv;
     register struct VolumeDiskData *td;
@@ -1508,11 +1615,10 @@ VolGetStatus(struct rx_call *acid, afs_int32 atrans,
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "GetStatus");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "GetStatus");
     tv = tt->volume;
     if (!tv) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
        return ENOENT;
     }
@@ -1534,7 +1640,7 @@ VolGetStatus(struct rx_call *acid, afs_int32 atrans,
     astatus->expirationDate = td->expirationDate;
     astatus->backupDate = td->backupDate;
     astatus->copyDate = td->copyDate;
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -1542,7 +1648,7 @@ VolGetStatus(struct rx_call *acid, afs_int32 atrans,
 }
 
 afs_int32
-SAFSVolSetInfo(struct rx_call *acid, afs_int32 atrans, 
+SAFSVolSetInfo(struct rx_call *acid, afs_int32 atrans,
               register struct volintInfo *astatus)
 {
     afs_int32 code;
@@ -1552,15 +1658,15 @@ SAFSVolSetInfo(struct rx_call *acid, afs_int32 atrans,
     return code;
 }
 
-afs_int32
-VolSetInfo(struct rx_call *acid, afs_int32 atrans, 
+static afs_int32
+VolSetInfo(struct rx_call *acid, afs_int32 atrans,
               register struct volintInfo *astatus)
 {
     register struct Volume *tv;
     register struct VolumeDiskData *td;
     struct volser_trans *tt;
     char caller[MAXKTCNAMELEN];
-    afs_int32 error;
+    Error error;
 
     if (!afsconf_SuperUser(tdir, acid, caller))
        return VOLSERBAD_ACCESS;        /*not a super user */
@@ -1572,11 +1678,10 @@ VolSetInfo(struct rx_call *acid, afs_int32 atrans,
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "SetStatus");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "SetStatus");
     tv = tt->volume;
     if (!tv) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
        return ENOENT;
     }
@@ -1596,7 +1701,7 @@ VolSetInfo(struct rx_call *acid, afs_int32 atrans,
     if (astatus->spare2 != -1)
        td->volUpdateCounter = (unsigned int)astatus->spare2;
     VUpdateVolume(&error, tv);
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
     return 0;
@@ -1613,7 +1718,7 @@ SAFSVolGetName(struct rx_call *acid, afs_int32 atrans, char **aname)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolGetName(struct rx_call *acid, afs_int32 atrans, char **aname)
 {
     register struct Volume *tv;
@@ -1633,11 +1738,10 @@ VolGetName(struct rx_call *acid, afs_int32 atrans, char **aname)
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "GetName");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "GetName");
     tv = tt->volume;
     if (!tv) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
        return ENOENT;
     }
@@ -1645,13 +1749,13 @@ VolGetName(struct rx_call *acid, afs_int32 atrans, char **aname)
     td = &tv->header->diskstuff;
     len = strlen(td->name) + 1;        /* don't forget the null */
     if (len >= SIZE) {
-       tt->rxCallPtr = (struct rx_call *)0;
+        TClearRxCall(tt);
        TRELE(tt);
        return E2BIG;
     }
     *aname = (char *)realloc(*aname, len);
     strcpy(*aname, td->name);
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -1661,7 +1765,7 @@ VolGetName(struct rx_call *acid, afs_int32 atrans, char **aname)
 /*this is a handshake to indicate that the next call will be SAFSVolRestore
  * - a noop now !*/
 afs_int32
-SAFSVolSignalRestore(struct rx_call *acid, char volname[], int volType, 
+SAFSVolSignalRestore(struct rx_call *acid, char volname[], int volType,
                     afs_uint32 parentId, afs_uint32 cloneId)
 {
     return 0;
@@ -1680,11 +1784,11 @@ SAFSVolListPartitions(struct rx_call *acid, struct pIDs *partIds)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolListPartitions(struct rx_call *acid, struct pIDs *partIds)
 {
     char namehead[9];
-    char i;
+    int i;
 
     strcpy(namehead, "/vicep");        /*7 including null terminator */
 
@@ -1710,13 +1814,13 @@ SAFSVolXListPartitions(struct rx_call *acid, struct partEntries *pEntries)
     return code;
 }
 
-afs_int32
+static afs_int32
 XVolListPartitions(struct rx_call *acid, struct partEntries *pEntries)
 {
     char namehead[9];
     struct partList partList;
     struct DiskPartition64 *dp;
-    int i, j = 0, k;
+    int i, j = 0;
 
     strcpy(namehead, "/vicep");        /*7 including null terminator */
 
@@ -1729,6 +1833,8 @@ XVolListPartitions(struct rx_call *acid, struct partEntries *pEntries)
            namehead[6] = i + 'a';
            namehead[7] = '\0';
        } else {
+           int k;
+
            k = i - 26;
            namehead[6] = 'a' + (k / 26);
            namehead[7] = 'a' + (k % 26);
@@ -1960,7 +2066,7 @@ FillVolInfo(Volume * vp, volint_info_handle_t * handle)
         * Copy out the stat fields in a single operation.
         */
        if ((now - hdr->dayUseDate) > OneDay) {
-           memset((char *)&(handle->volinfo_ptr.ext->stat_reads[0]),
+           memset(&(handle->volinfo_ptr.ext->stat_reads[0]),
                   0, numStatBytes);
        } else {
            memcpy((char *)&(handle->volinfo_ptr.ext->stat_reads[0]),
@@ -1973,6 +2079,8 @@ FillVolInfo(Volume * vp, volint_info_handle_t * handle)
     return 0;
 }
 
+#ifdef AFS_DEMAND_ATTACH_FS
+
 /**
  * get struct Volume out of the fileserver.
  *
@@ -2018,6 +2126,8 @@ GetVolObject(afs_uint32 volumeId, char * pname, Volume ** vp)
     return code;
 }
 
+#endif
+
 /**
  * mode of volume list operation.
  */
@@ -2051,7 +2161,7 @@ GetVolInfo(afs_uint32 partId,
           vol_info_list_mode_t mode)
 {
     int code = -1;
-    afs_int32 error;
+    Error error;
     struct volser_trans *ttc = NULL;
     struct Volume *fill_tv, *tv = NULL;
 #ifdef AFS_DEMAND_ATTACH_FS
@@ -2069,13 +2179,13 @@ GetVolInfo(afs_uint32 partId,
     ttc = NewTrans(volumeId, partId);
     if (!ttc) {
        code = -3;
-       VOLINT_INFO_STORE(handle, status, VBUSY);
+       VOLINT_INFO_STORE(handle, status, VOLSERVOLBUSY);
        VOLINT_INFO_STORE(handle, volid, volumeId);
        goto drop;
     }
 
     /* Get volume from volserver */
-    tv = VAttachVolumeByName(&error, pname, volname, V_PEEK);
+    tv = VAttachVolumeByName_retry(&error, pname, volname, V_PEEK);
     if (error) {
        Log("1 Volser: GetVolInfo: Could not attach volume %u (%s:%s) error=%d\n", 
            volumeId, pname, volname, error);
@@ -2112,7 +2222,8 @@ GetVolInfo(afs_uint32 partId,
 
 #ifdef AFS_DEMAND_ATTACH_FS
     /* If using DAFS, get volume from fsserver */
-    if (GetVolObject(volumeId, pname, &fs_tv) != SYNC_OK) {
+    if (GetVolObject(volumeId, pname, &fs_tv) != SYNC_OK || fs_tv == NULL) {
+
        goto drop;
     }
 
@@ -2174,14 +2285,13 @@ SAFSVolListOneVolume(struct rx_call *acid, afs_int32 partid,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolListOneVolume(struct rx_call *acid, afs_int32 partid, 
                  afs_uint32 volumeId, volEntries *volumeInfo)
 {
     volintInfo *pntr;
     struct DiskPartition64 *partP;
     char pname[9], volname[20];
-    afs_int32 error = 0;
     DIR *dirp;
     afs_uint32 volid;
     int found = 0;
@@ -2274,7 +2384,7 @@ SAFSVolXListOneVolume(struct rx_call *a_rxCidP, afs_int32 a_partID,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolXListOneVolume(struct rx_call *a_rxCidP, afs_int32 a_partID, 
                   afs_uint32 a_volID, volXEntries *a_volumeXInfoP)
 {                              /*SAFSVolXListOneVolume */
@@ -2386,7 +2496,7 @@ SAFSVolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, 
                   volEntries *volumeInfo)
 {
@@ -2394,7 +2504,6 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags,
     struct DiskPartition64 *partP;
     afs_int32 allocSize = 1000;        /*to be changed to a larger figure */
     char pname[9], volname[20];
-    afs_int32 error = 0;
     DIR *dirp;
     afs_uint32 volid;
     int code;
@@ -2447,7 +2556,6 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags,
            /*just volids are needed */
        }
 
-      drop:
        pntr++;
        volumeInfo->volEntries_len += 1;
        if ((allocSize - volumeInfo->volEntries_len) < 5) {
@@ -2513,7 +2621,7 @@ SAFSVolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID,
     return code;
 }
 
-afs_int32
+static afs_int32
 VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID,
                    afs_int32 a_flags, volXEntries *a_volumeXInfoP)
 {                              /*SAFSVolXListVolumes */
@@ -2522,7 +2630,6 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID,
     struct DiskPartition64 *partP;     /*Ptr to partition */
     afs_int32 allocSize = 1000;        /*To be changed to a larger figure */
     char pname[9], volname[20];        /*Partition, volume names */
-    afs_int32 error = 0;       /*Return code */
     DIR *dirp;                 /*Partition directory ptr */
     afs_uint32 volid;          /*Current volume ID */
     int code;
@@ -2601,7 +2708,6 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID,
            xInfoP->volid = volid;
        }
 
-      drop:
        /*
         * Bump the pointer in the data area we're building, along with
         * the count of the number of entries it contains.
@@ -2660,12 +2766,12 @@ SAFSVolMonitor(struct rx_call *acid, transDebugEntries *transInfo)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolMonitor(struct rx_call *acid, transDebugEntries *transInfo)
 {
     transDebugInfo *pntr;
     afs_int32 allocSize = 50;
-    struct volser_trans *tt, *allTrans;
+    struct volser_trans *tt, *nt, *allTrans;
 
     transInfo->transDebugEntries_val =
        (transDebugInfo *) malloc(allocSize * sizeof(transDebugInfo));
@@ -2673,10 +2779,14 @@ VolMonitor(struct rx_call *acid, transDebugEntries *transInfo)
        return ENOMEM;
     pntr = transInfo->transDebugEntries_val;
     transInfo->transDebugEntries_len = 0;
+
+    VTRANS_LOCK;
     allTrans = TransList();
     if (allTrans == (struct volser_trans *)0)
-       return 0;               /*no active transactions */
-    for (tt = allTrans; tt; tt = tt->next) {   /*copy relevant info into pntr */
+       goto done;              /*no active transactions */
+    for (tt = allTrans; tt; tt = nt) { /*copy relevant info into pntr */
+       nt = tt->next;
+        VTRANS_OBJ_LOCK(tt);
        pntr->tid = tt->tid;
        pntr->time = tt->time;
        pntr->creationTime = tt->creationTime;
@@ -2695,6 +2805,7 @@ VolMonitor(struct rx_call *acid, transDebugEntries *transInfo)
            pntr->lastSendTime = tt->rxCallPtr->lastSendTime;
            pntr->lastReceiveTime = tt->rxCallPtr->lastReceiveTime;
        }
+        VTRANS_OBJ_UNLOCK(tt);
        pntr++;
        transInfo->transDebugEntries_len += 1;
        if ((allocSize - transInfo->transDebugEntries_len) < 5) {       /*alloc some more space */
@@ -2712,12 +2823,16 @@ VolMonitor(struct rx_call *acid, transDebugEntries *transInfo)
        }
 
     }
+done:
+    VTRANS_UNLOCK;
 
     return 0;
 }
 
 afs_int32
-SAFSVolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32 type, afs_uint32 pId, afs_uint32 cloneId, afs_uint32 backupId)
+SAFSVolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[],
+                  afs_int32 type, afs_uint32 pId, afs_uint32 cloneId,
+                  afs_uint32 backupId)
 {
     afs_int32 code;
 
@@ -2728,11 +2843,13 @@ SAFSVolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32
     return code;
 }
 
-afs_int32
-VolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32 type, afs_uint32 pId, afs_uint32 cloneId, afs_uint32 backupId)
+static afs_int32
+VolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[],
+              afs_int32 type, afs_uint32 pId, afs_uint32 cloneId,
+              afs_uint32 backupId)
 {
     struct Volume *tv;
-    afs_int32 error = 0;
+    Error error = 0;
     register struct volser_trans *tt;
     char caller[MAXKTCNAMELEN];
 
@@ -2749,8 +2866,7 @@ VolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32 type
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "SetIdsTypes");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "SetIdsTypes");
     tv = tt->volume;
 
     V_type(tv) = type;
@@ -2764,13 +2880,13 @@ VolSetIdsTypes(struct rx_call *acid, afs_int32 atid, char name[], afs_int32 type
        LogError(error);
        goto fail;
     }
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt) && !error)
        return VOLSERTRELE_ERROR;
 
     return error;
   fail:
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt) && !error)
        return VOLSERTRELE_ERROR;
     return error;
@@ -2787,11 +2903,11 @@ SAFSVolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate)
     return code;
 }
 
-afs_int32
+static afs_int32
 VolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate)
 {
     struct Volume *tv;
-    afs_int32 error = 0;
+    Error error = 0;
     register struct volser_trans *tt;
     char caller[MAXKTCNAMELEN];
 
@@ -2806,8 +2922,7 @@ VolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate)
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "SetDate");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "SetDate");
     tv = tt->volume;
 
     V_creationDate(tv) = cdate;
@@ -2817,13 +2932,13 @@ VolSetDate(struct rx_call *acid, afs_int32 atid, afs_int32 cdate)
        LogError(error);
        goto fail;
     }
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt) && !error)
        return VOLSERTRELE_ERROR;
 
     return error;
   fail:
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt) && !error)
        return VOLSERTRELE_ERROR;
     return error;
@@ -2868,7 +2983,7 @@ SAFSVolConvertROtoRWvolume(struct rx_call *acid, afs_int32 partId,
 #endif
             ttc = NewTrans(volumeId, partId);
             if (!ttc) {
-               return VBUSY;
+               return VOLSERVOLBUSY;
             }
 #ifdef AFS_NAMEI_ENV
            ret = namei_ConvertROtoRWvolume(pname, volumeId);
@@ -2907,10 +3022,9 @@ SAFSVolGetSize(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
        TRELE(tt);
        return ENOENT;
     }
-    strcpy(tt->lastProcName, "GetSize");
-    tt->rxCallPtr = acid;
+    TSetRxCall(tt, acid, "GetSize");
     code = SizeDumpVolume(acid, tt->volume, fromDate, 1, size);        /* measure volume's data */
-    tt->rxCallPtr = (struct rx_call *)0;
+    TClearRxCall(tt);
     if (TRELE(tt))
        return VOLSERTRELE_ERROR;
 
@@ -2919,10 +3033,11 @@ SAFSVolGetSize(struct rx_call *acid, afs_int32 fromTrans, afs_int32 fromDate,
 }
 
 afs_int32
-SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 vid, afs_uint32 new, 
+SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 vid, afs_uint32 new,
                   afs_uint32 where, afs_int32 verbose)
 {
-    afs_int32 code, code2;
+#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
+    Error code, code2;
     Volume *vol=0, *newvol=0;
     struct volser_trans *tt = 0, *tt2 = 0;
     char caller[MAXKTCNAMELEN];
@@ -2971,9 +3086,11 @@ SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 vid, afs_uint32 new,
         VDetachVolume(&code2, newvol);
         return VOLSERVOLBUSY;
     } 
+    VTRANS_OBJ_LOCK(tt);
     tt->iflags = ITBusy;
     tt->vflags = 0;
-    strcpy(tt->lastProcName, "SplitVolume");
+    TSetRxCall_r(tt, NULL, "SplitVolume");
+    VTRANS_OBJ_UNLOCK(tt);
 
     tt2 = NewTrans(new, V_device(newvol));
     if (!tt2) {
@@ -2986,9 +3103,11 @@ SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 vid, afs_uint32 new,
         VDetachVolume(&code2, newvol);
         return VOLSERVOLBUSY;
     } 
+    VTRANS_OBJ_LOCK(tt2);
     tt2->iflags = ITBusy;
     tt2->vflags = 0;
-    strcpy(tt2->lastProcName, "SplitVolume");
+    TSetRxCall_r(tt2, NULL, "SplitVolume");
+    VTRANS_OBJ_UNLOCK(tt2);
 
     code = split_volume(acall, vol, newvol, where, verbose);
 
@@ -2997,6 +3116,9 @@ SAFSVolSplitVolume(struct rx_call *acall, afs_uint32 vid, afs_uint32 new,
     VDetachVolume(&code2, newvol);
     DeleteTrans(tt2, 1);
     return code;
+#else
+    return VOLSERBADOP;
+#endif
 }
 
 /* GetPartName - map partid (a decimal number) into pname (a string)