]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
viced: disable rx keepalives during disk io
authorDerrick Brashear <shadow@dementix.org>
Thu, 5 Jan 2012 22:19:45 +0000 (17:19 -0500)
committerDerrick Brashear <shadow@dementix.org>
Tue, 24 Jan 2012 02:49:54 +0000 (18:49 -0800)
when we are going to hit the backend storage, disable keepalives.
the net effect of this is that no idle dead time is needed; instead,
the normal dead time will result in a connection with no activity
simply dying naturally if i/o blocks forever.

it's important that keepalives be enabled during callback breaks,
so that is done.

(cherry picked from commit 05f3a0d1e0359f604cc6162708f3f381eabcd1d7)
Reviewed-on: http://gerrit.openafs.org/6515
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Change-Id: If2ee7f3ad7f2dc835dd350bb9558fde0aa179240
Reviewed-on: http://gerrit.openafs.org/6613
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
src/viced/afsfileprocs.c

index 314b3df6eb8f8a17619f13ecd9ee7e22cbd9aef0..bc78fc3994a555661a7e275cfcbb3fe090a8a399 100644 (file)
 /*                                                                      */
 /* ********************************************************************** */
 
+/*
+ * GetVolumePackage disables Rx keepalives; PutVolumePackage re-enables.
+ * If callbacks are to be broken, keepalives should be enabled in the
+ * stub while that occurs; disabled while disk I/O is in process.
+ */
+
 /*
  * in Check_PermissionRights, certain privileges are afforded to the owner
  * of the volume, or the owner of a file.  Are these considered "use of
@@ -811,13 +817,39 @@ VanillaUser(struct client *client)
 }                              /*VanillaUser */
 
 
-/*
- * This unusual afs_int32-parameter routine encapsulates all volume package related
- * operations together in a single function; it's called by almost all AFS
- * interface calls.
- */
+/*------------------------------------------------------------------------
+ * GetVolumePackage
+ *
+ * Description:
+ *      This unusual afs_int32-parameter routine encapsulates all volume
+ *      package related operations together in a single function; it's
+ *      called by almost all AFS interface calls.
+ *
+ * Arguments:
+ *      acall               : Ptr to Rx call on which this request came in.
+ *      Fid                 : the AFS fid the caller is acting on
+ *      volptr              : returns a pointer to the volume struct
+ *      targetptr           : returns a pointer to the vnode struct
+ *      chkforDir           : whether to check for if vnode is a dir
+ *      parent              : returns a pointer to the parent of this vnode
+ *      client              : returns a pointer to the calling client
+ *      locktype            : indicates what kind of lock to take on vnodes
+ *      rights              : returns a pointer to caller's rights
+ *      anyrights           : returns a pointer to anonymous' rights
+ *
+ * Returns:
+ *      0 on success
+ *      appropriate error based on permission or invalid operation.
+ *
+ * Environment:
+ *      Nothing interesting.
+ *
+ * Side Effects:
+ *      On success, disables keepalives on the call. Caller should re-enable
+ *      after completing disk I/O.
+ *------------------------------------------------------------------------*/
 static afs_int32
-GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
+GetVolumePackage(struct rx_call *acall, AFSFid * Fid, Volume ** volptr,
                 Vnode ** targetptr, int chkforDir, Vnode ** parent,
                 struct client **client, int locktype, afs_int32 * rights,
                 afs_int32 * anyrights)
@@ -825,29 +857,39 @@ GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
     struct acl_accessList *aCL;        /* 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 = CheckVnode(Fid, volptr, targetptr, locktype)))
-       return (errorCode);
+       goto gvpdone;
+
     if (chkforDir) {
        if (chkforDir == MustNOTBeDIR
-           && ((*targetptr)->disk.type == vDirectory))
-           return (EISDIR);
+           && ((*targetptr)->disk.type == vDirectory)) {
+           errorCode = EISDIR;
+           goto gvpdone;
+       }
        else if (chkforDir == MustBeDIR
-                && ((*targetptr)->disk.type != vDirectory))
-           return (ENOTDIR);
+                && ((*targetptr)->disk.type != vDirectory)) {
+           errorCode = ENOTDIR;
+           goto gvpdone;
+       }
     }
     if ((errorCode =
         SetAccessList(targetptr, volptr, &aCL, &aCLSize, parent,
                       (chkforDir == MustBeDIR ? (AFSFid *) 0 : Fid),
                       (chkforDir == MustBeDIR ? 0 : locktype))) != 0)
-       return (errorCode);
+       goto gvpdone;
     if (chkforDir == MustBeDIR)
        osi_Assert((*parent) == 0);
     if (!(*client)) {
        if ((errorCode = GetClient(tcon, client)) != 0)
-           return (errorCode);
-       if (!(*client))
-           return (EINVAL);
+           goto gvpdone;
+       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 */
@@ -863,21 +905,47 @@ GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
     if (!VanillaUser(*client))
        (*rights) |= PRSFS_LOOKUP;
 #endif /* ADMIN_IMPLICIT_LOOKUP */
+gvpdone:
+    if (errorCode)
+       rx_KeepAliveOn(acall);
     return errorCode;
 
 }                              /*GetVolumePackage */
 
-
-/*
- * This is the opposite of GetVolumePackage(), and is always used at the end of
- * AFS calls to put back all used vnodes and the volume in the proper order!
- */
+/*------------------------------------------------------------------------
+ * PutVolumePackage
+ *
+ * Description:
+ *      This is the opposite of GetVolumePackage(), and is always used at
+ *      the end of AFS calls to put back all used vnodes and the volume
+ *      in the proper order!
+ *
+ * Arguments:
+ *      acall               : Ptr to Rx call on which this request came in.
+ *      parentwhentargetnotdir : a pointer to the parent when the target isn't
+ *                            a directory vnode
+ *      targetptr           : a pointer to the vnode struct
+ *      parentptr           : a pointer to the parent of this vnode
+ *      volptr              : a pointer to the volume structure
+ *      client              : a pointer to the calling client
+ *
+ * Returns:
+ *      Nothing
+ *
+ * Environment:
+ *      Nothing interesting.
+ *
+ * Side Effects:
+ *      Enables keepalives on the call.
+ *------------------------------------------------------------------------*/
 static void
-PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
-                Vnode * parentptr, Volume * volptr, struct client **client)
+PutVolumePackage(struct rx_call *acall, Vnode * parentwhentargetnotdir,
+                Vnode * targetptr, Vnode * parentptr, Volume * volptr,
+                struct client **client)
 {
     Error fileCode = 0;                /* Error code returned by the volume package */
 
+    rx_KeepAliveOff(acall);
     if (parentwhentargetnotdir) {
        VPutVnode(&fileCode, parentwhentargetnotdir);
        osi_Assert(!fileCode || (fileCode == VSALVAGE));
@@ -893,6 +961,8 @@ PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
     if (volptr) {
        VPutVolume(volptr);
     }
+    rx_KeepAliveOn(acall);
+
     if (*client) {
        PutClient(client);
     }
@@ -2156,8 +2226,7 @@ GetStatus(Vnode * targetptr, AFSFetchStatus * status, afs_int32 rights,
 
 }                              /*GetStatus */
 
-static
-  afs_int32
+static afs_int32
 common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
                   afs_sfsize_t Pos, afs_sfsize_t Len,
                   struct AFSFetchStatus *OutStatus,
@@ -2220,7 +2289,7 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
      * it are also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, READ_LOCK,
                          &rights, &anyrights)))
        goto Bad_FetchData;
@@ -2346,6 +2415,8 @@ 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);
@@ -2358,8 +2429,8 @@ common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_FetchData:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode));
     errorCode = CallPostamble(tcon, errorCode, thost);
 
@@ -2481,7 +2552,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
      * are also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, READ_LOCK,
                          &rights, &anyrights)))
        goto Bad_FetchACL;
@@ -2504,8 +2575,8 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
 
   Bad_FetchACL:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     ViceLog(2,
            ("SAFS_FetchACL returns %d (ACL=%s)\n", errorCode,
             AccessList->AFSOpaque_val));
@@ -2541,8 +2612,7 @@ SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
  * This routine is called exclusively by SRXAFS_FetchStatus(), and should be
  * merged into it when possible.
  */
-static
-  afs_int32
+static afs_int32
 SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
                  struct AFSFetchStatus *OutStatus,
                  struct AFSCallBack *CallBack, struct AFSVolSync *Sync)
@@ -2572,11 +2642,13 @@ SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
      * also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, READ_LOCK,
                          &rights, &anyrights)))
        goto Bad_FetchStatus;
 
+    rx_KeepAliveOn(acall);
+
     /* set volume synchronization information */
     SetVolumeSync(Sync, volptr);
 
@@ -2607,8 +2679,8 @@ SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_FetchStatus:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     ViceLog(2, ("SAFS_FetchStatus returns %d\n", errorCode));
     return errorCode;
 
@@ -2684,10 +2756,13 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
         * are also returned
         */
        if ((errorCode =
-            GetVolumePackage(tcon, tfid, &volptr, &targetptr, DONTCHECK,
+            GetVolumePackage(acall, tfid, &volptr, &targetptr, DONTCHECK,
                              &parentwhentargetnotdir, &client, READ_LOCK,
                              &rights, &anyrights)))
            goto Bad_BulkStatus;
+
+       rx_KeepAliveOn(acall);
+
        /* set volume synchronization information, but only once per call */
        if (i == 0)
            SetVolumeSync(Sync, volptr);
@@ -2720,8 +2795,8 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
        }
 
        /* put back the file ID and volume */
-       (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                              volptr, &client);
+       (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                              (Vnode *) 0, volptr, &client);
        parentwhentargetnotdir = (Vnode *) 0;
        targetptr = (Vnode *) 0;
        volptr = (Volume *) 0;
@@ -2730,8 +2805,8 @@ SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
 
   Bad_BulkStatus:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     errorCode = CallPostamble(tcon, errorCode, thost);
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
@@ -2841,13 +2916,13 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
         * are also returned
         */
        if ((errorCode =
-            GetVolumePackage(tcon, tfid, &volptr, &targetptr, DONTCHECK,
+            GetVolumePackage(acall, tfid, &volptr, &targetptr, DONTCHECK,
                              &parentwhentargetnotdir, &client, READ_LOCK,
                              &rights, &anyrights))) {
            tstatus = &OutStats->AFSBulkStats_val[i];
            tstatus->errorCode = errorCode;
-           PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                            volptr, &client);
+           PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                            (Vnode *) 0, volptr, &client);
            parentwhentargetnotdir = (Vnode *) 0;
            targetptr = (Vnode *) 0;
            volptr = (Volume *) 0;
@@ -2855,6 +2930,8 @@ 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);
@@ -2868,8 +2945,9 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
                                        CHK_FETCHSTATUS, 0))) {
                tstatus = &OutStats->AFSBulkStats_val[i];
                tstatus->errorCode = errorCode;
-               (void)PutVolumePackage(parentwhentargetnotdir, targetptr,
-                                      (Vnode *) 0, volptr, &client);
+               (void)PutVolumePackage(acall, parentwhentargetnotdir,
+                                      targetptr, (Vnode *) 0, volptr,
+                                      &client);
                parentwhentargetnotdir = (Vnode *) 0;
                targetptr = (Vnode *) 0;
                volptr = (Volume *) 0;
@@ -2896,8 +2974,8 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
        }
 
        /* put back the file ID and volume */
-       (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                              volptr, &client);
+       (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                              (Vnode *) 0, volptr, &client);
        parentwhentargetnotdir = (Vnode *) 0;
        targetptr = (Vnode *) 0;
        volptr = (Volume *) 0;
@@ -2906,8 +2984,8 @@ SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
 
   Bad_InlineBulkStatus:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     errorCode = CallPostamble(tcon, errorCode, thost);
 
     t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
@@ -3063,12 +3141,14 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
      * are also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, MustNOTBeDIR,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, MustNOTBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_StoreData;
     }
 
+    rx_KeepAliveOn(acall);
+
     /* set volume synchronization information */
     SetVolumeSync(Sync, volptr);
 
@@ -3091,7 +3171,9 @@ 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));
        parentwhentargetnotdir = NULL;
     }
@@ -3182,9 +3264,11 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
        goto Bad_StoreData;
 #endif /* FS_STATS_DETAILED */
 
+    rx_KeepAliveOff(acall);
     /* Update the status of the target's vnode */
     Update_TargetVnodeStatus(targetptr, TVS_SDATA, client, InStatus,
                             targetptr, volptr, 0);
+    rx_KeepAliveOn(acall);
 
     /* Get the updated File's status back to the caller */
     GetStatus(targetptr, OutStatus, rights, anyrights,
@@ -3192,8 +3276,8 @@ common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_StoreData:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     ViceLog(2, ("SAFS_StoreData        returns %d\n", errorCode));
 
     errorCode = CallPostamble(tcon, errorCode, thost);
@@ -3316,7 +3400,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
      * are also returned.
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, MustBeDIR,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_StoreACL;
@@ -3343,6 +3427,8 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
     VVnodeWriteToRead(&errorCode, targetptr);
     osi_Assert(!errorCode || errorCode == VSALVAGE);
 
+    rx_KeepAliveOn(acall);
+
     /* break call backs on the directory  */
     BreakCallBack(client->host, Fid, 0);
 
@@ -3351,7 +3437,7 @@ SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
 
   Bad_StoreACL:
     /* Update and store volume/vnode and parent vnodes back */
-    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+    PutVolumePackage(acall, parentwhentargetnotdir, targetptr, (Vnode *) 0,
                     volptr, &client);
     ViceLog(2, ("SAFS_StoreACL returns %d\n", errorCode));
     errorCode = CallPostamble(tcon, errorCode, thost);
@@ -3416,7 +3502,7 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
      * also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_StoreStatus;
@@ -3445,6 +3531,8 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
                             (parentwhentargetnotdir ? parentwhentargetnotdir
                              : targetptr), volptr, 0);
 
+    rx_KeepAliveOn(acall);
+
     /* convert the write lock to a read lock before breaking callbacks */
     VVnodeWriteToRead(&errorCode, targetptr);
     osi_Assert(!errorCode || errorCode == VSALVAGE);
@@ -3458,7 +3546,7 @@ SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_StoreStatus:
     /* Update and store volume/vnode and parent vnodes back */
-    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+    PutVolumePackage(acall, parentwhentargetnotdir, targetptr, (Vnode *) 0,
                     volptr, &client);
     ViceLog(2, ("SAFS_StoreStatus returns %d\n", errorCode));
     return errorCode;
@@ -3565,7 +3653,7 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR,
+        GetVolumePackage(acall, DirFid, &volptr, &parentptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_RemoveFile;
@@ -3595,6 +3683,8 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
                             parentptr->disk.linkCount);
 #endif /* FS_STATS_DETAILED */
 
+    rx_KeepAliveOn(acall);
+
     /* Return the updated parent dir's status back to caller */
     GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
 
@@ -3621,7 +3711,7 @@ SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
   Bad_RemoveFile:
     /* Update and store volume/vnode and parent vnodes back */
-    PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+    PutVolumePackage(acall, parentwhentargetnotdir, targetptr, parentptr,
                     volptr, &client);
     FidZap(&dir);
     ViceLog(2, ("SAFS_RemoveFile returns %d\n", errorCode));
@@ -3736,7 +3826,7 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * also returned
      */
     if ((errorCode =
-        GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR,
+        GetVolumePackage(acall, DirFid, &volptr, &parentptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_CreateFile;
@@ -3749,12 +3839,12 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
        goto Bad_CreateFile;
     }
+
     /* get a new vnode for the file to be created and set it up */
     if ((errorCode =
         Alloc_NewVnode(parentptr, &dir, volptr, &targetptr, Name, OutFid,
-                       vFile, nBlocks(0)))) {
+                       vFile, nBlocks(0))))
        goto Bad_CreateFile;
-    }
 
     /* update the status of the parent vnode */
 #if FS_STATS_DETAILED
@@ -3770,6 +3860,8 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     Update_TargetVnodeStatus(targetptr, TVS_CFILE, client, InStatus,
                             parentptr, volptr, 0);
 
+    rx_KeepAliveOn(acall);
+
     /* 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);
     GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
@@ -3786,7 +3878,7 @@ SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
   Bad_CreateFile:
     /* Update and store volume/vnode and parent vnodes back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr, parentptr,
                           volptr, &client);
     FidZap(&dir);
     ViceLog(2, ("SAFS_CreateFile returns %d\n", errorCode));
@@ -3936,7 +4028,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
 
     if (OldDirFid->Vnode <= NewDirFid->Vnode) {
        if ((errorCode =
-            GetVolumePackage(tcon, OldDirFid, &volptr, &oldvptr, MustBeDIR,
+            GetVolumePackage(acall, OldDirFid, &volptr, &oldvptr, MustBeDIR,
                              &parent, &client, WRITE_LOCK, &rights,
                              &anyrights))) {
            DFlush();
@@ -3947,7 +4039,7 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
            newrights = rights, newanyrights = anyrights;
        } else
            if ((errorCode =
-                GetVolumePackage(tcon, NewDirFid, &volptr, &newvptr,
+                GetVolumePackage(acall, NewDirFid, &volptr, &newvptr,
                                  MustBeDIR, &parent, &client, WRITE_LOCK,
                                  &newrights, &newanyrights))) {
            DFlush();
@@ -3955,14 +4047,14 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
        }
     } else {
        if ((errorCode =
-            GetVolumePackage(tcon, NewDirFid, &volptr, &newvptr, MustBeDIR,
+            GetVolumePackage(acall, NewDirFid, &volptr, &newvptr, MustBeDIR,
                              &parent, &client, WRITE_LOCK, &newrights,
                              &newanyrights))) {
            DFlush();
            goto Bad_Rename;
        }
        if ((errorCode =
-            GetVolumePackage(tcon, OldDirFid, &volptr, &oldvptr, MustBeDIR,
+            GetVolumePackage(acall, OldDirFid, &volptr, &oldvptr, MustBeDIR,
                              &parent, &client, WRITE_LOCK, &rights,
                              &anyrights))) {
            DFlush();
@@ -4292,6 +4384,8 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
        osi_Assert(!errorCode || errorCode == VSALVAGE);
     }
 
+    rx_KeepAliveOn(acall);
+
     /* break call back on NewDirFid, OldDirFid, NewDirFid and newFileFid  */
     BreakCallBack(client->host, NewDirFid, 0);
     if (oldvptr != newvptr) {
@@ -4318,10 +4412,11 @@ SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
 
   Bad_Rename:
     if (newfileptr) {
+       rx_KeepAliveOff(acall);
        VPutVnode(&fileCode, newfileptr);
        osi_Assert(fileCode == 0);
     }
-    (void)PutVolumePackage(fileptr, (newvptr && newvptr != oldvptr ?
+    (void)PutVolumePackage(acall, fileptr, (newvptr && newvptr != oldvptr ?
                                     newvptr : 0), oldvptr, volptr, &client);
     FidZap(&olddir);
     FidZap(&newdir);
@@ -4446,19 +4541,17 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * rights to it
      */
     if ((errorCode =
-        GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR,
+        GetVolumePackage(acall, DirFid, &volptr, &parentptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
-                         &rights, &anyrights))) {
+                         &rights, &anyrights)))
        goto Bad_SymLink;
-    }
 
     /* set volume synchronization information */
     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)))
        goto Bad_SymLink;
-    }
 
     /*
      * If we're creating a mount point (any x bits clear), we must have
@@ -4505,8 +4598,8 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     /* Write the contents of the symbolic link name into the target inode */
     fdP = IH_OPEN(targetptr->handle);
     if (fdP == NULL) {
-       (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
-                              volptr, &client);
+       (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                              parentptr, volptr, &client);
        VTakeOffline(volptr);
        ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
                    volptr->hashid));
@@ -4528,12 +4621,14 @@ SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     VVnodeWriteToRead(&errorCode, parentptr);
     osi_Assert(!errorCode || errorCode == VSALVAGE);
 
+    rx_KeepAliveOn(acall);
+
     /* break call back on the parent dir */
     BreakCallBack(client->host, DirFid, 0);
 
   Bad_SymLink:
     /* Write the all modified vnodes (parent, new files) and volume back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr, parentptr,
                           volptr, &client);
     FidZap(&dir);
     ViceLog(2, ("SAFS_Symlink returns %d\n", errorCode));
@@ -4660,7 +4755,7 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * rights to it
      */
     if ((errorCode =
-        GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR,
+        GetVolumePackage(acall, DirFid, &volptr, &parentptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_Link;
@@ -4691,6 +4786,7 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
         CheckVnode(ExistingFid, &volptr, &targetptr, WRITE_LOCK))) {
        goto Bad_Link;
     }
+
     if (targetptr->disk.type != vFile) {
        errorCode = EISDIR;
        goto Bad_Link;
@@ -4736,6 +4832,8 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     VVnodeWriteToRead(&errorCode, parentptr);
     osi_Assert(!errorCode || errorCode == VSALVAGE);
 
+    rx_KeepAliveOn(acall);
+
     /* break call back on DirFid */
     BreakCallBack(client->host, DirFid, 0);
     /*
@@ -4746,7 +4844,7 @@ SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
   Bad_Link:
     /* Write the all modified vnodes (parent, new files) and volume back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr, parentptr,
                           volptr, &client);
     FidZap(&dir);
     ViceLog(2, ("SAFS_Link returns %d\n", errorCode));
@@ -4868,7 +4966,7 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * rights to it.
      */
     if ((errorCode =
-        GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR,
+        GetVolumePackage(acall, DirFid, &volptr, &parentptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_MakeDir;
@@ -4936,6 +5034,8 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     VVnodeWriteToRead(&errorCode, parentptr);
     osi_Assert(!errorCode || errorCode == VSALVAGE);
 
+    rx_KeepAliveOn(acall);
+
     /* break call back on DirFid */
     BreakCallBack(client->host, DirFid, 0);
 
@@ -4944,7 +5044,7 @@ SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
 
   Bad_MakeDir:
     /* Write the all modified vnodes (parent, new files) and volume back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr, parentptr,
                           volptr, &client);
     FidZap(&dir);
     FidZap(&parentdir);
@@ -5057,7 +5157,7 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
      * rights to it
      */
     if ((errorCode =
-        GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR,
+        GetVolumePackage(acall, DirFid, &volptr, &parentptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_RemoveDir;
@@ -5102,12 +5202,14 @@ SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
     VVnodeWriteToRead(&errorCode, parentptr);
     osi_Assert(!errorCode || errorCode == VSALVAGE);
 
+    rx_KeepAliveOn(acall);
+
     /* break call back on DirFid and fileFid */
     BreakCallBack(client->host, DirFid, 0);
 
   Bad_RemoveDir:
     /* Write the all modified vnodes (parent, new files) and volume back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr, parentptr,
                           volptr, &client);
     FidZap(&dir);
     ViceLog(2, ("SAFS_RemoveDir        returns %d\n", errorCode));
@@ -5215,7 +5317,7 @@ SAFSS_SetLock(struct rx_call *acall, struct AFSFid *Fid, ViceLockType type,
      * rights to it
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_SetLock;
@@ -5229,8 +5331,8 @@ SAFSS_SetLock(struct rx_call *acall, struct AFSFid *Fid, ViceLockType type,
 
   Bad_SetLock:
     /* Write the all modified vnodes (parent, new files) and volume back */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
 
     if ((errorCode == VREADONLY) && (type == LockRead))
        errorCode = 0;          /* allow read locks on RO volumes without saving state */
@@ -5341,7 +5443,7 @@ SAFSS_ExtendLock(struct rx_call *acall, struct AFSFid *Fid,
      * rights to it
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_ExtendLock;
@@ -5355,8 +5457,8 @@ SAFSS_ExtendLock(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_ExtendLock:
     /* Put back file's vnode and volume */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
 
     if ((errorCode == VREADONLY))      /* presumably, we already granted this lock */
        errorCode = 0;          /* under our generous policy re RO vols */
@@ -5468,7 +5570,7 @@ SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
      * rights to it
      */
     if ((errorCode =
-        GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK,
+        GetVolumePackage(acall, Fid, &volptr, &targetptr, DONTCHECK,
                          &parentwhentargetnotdir, &client, WRITE_LOCK,
                          &rights, &anyrights))) {
        goto Bad_ReleaseLock;
@@ -5483,6 +5585,7 @@ 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);
@@ -5491,8 +5594,8 @@ SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
 
   Bad_ReleaseLock:
     /* Put back file's vnode and volume */
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
 
     if ((errorCode == VREADONLY))      /* presumably, we already granted this lock */
        errorCode = 0;          /* under our generous policy re RO vols */
@@ -6687,7 +6790,7 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
        (afs_int32) ROOTVNODE, dummyFid.Unique = 1;
 
     if ((errorCode =
-        GetVolumePackage(tcon, &dummyFid, &volptr, &targetptr, MustBeDIR,
+        GetVolumePackage(acall, &dummyFid, &volptr, &targetptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, READ_LOCK,
                          &rights, &anyrights)))
        goto Bad_GetVolumeStatus;
@@ -6699,8 +6802,8 @@ SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
     (void)RXGetVolumeStatus(FetchVolStatus, Name, OfflineMsg, Motd, volptr);
 
   Bad_GetVolumeStatus:
-    (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
-                          volptr, &client);
+    (void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
+                          (Vnode *) 0, volptr, &client);
     ViceLog(2, ("SAFS_GetVolumeStatus returns %d\n", errorCode));
     /* next is to guarantee out strings exist for stub */
     if (*Name == 0) {
@@ -6792,7 +6895,7 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
        (afs_int32) ROOTVNODE, dummyFid.Unique = 1;
 
     if ((errorCode =
-        GetVolumePackage(tcon, &dummyFid, &volptr, &targetptr, MustBeDIR,
+        GetVolumePackage(acall, &dummyFid, &volptr, &targetptr, MustBeDIR,
                          &parentwhentargetnotdir, &client, READ_LOCK,
                          &rights, &anyrights)))
        goto Bad_SetVolumeStatus;
@@ -6810,7 +6913,7 @@ SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
        RXUpdate_VolumeStatus(volptr, StoreVolStatus, Name, OfflineMsg, Motd);
 
   Bad_SetVolumeStatus:
-    PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+    PutVolumePackage(acall, parentwhentargetnotdir, targetptr, (Vnode *) 0,
                     volptr, &client);
     ViceLog(2, ("SAFS_SetVolumeStatus returns %d\n", errorCode));
     errorCode = CallPostamble(tcon, errorCode, thost);
@@ -7350,6 +7453,7 @@ 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