]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
getsomespace-r-rewrite-20060201
authorJeffrey Altman <jaltman@secure-endpoints.com>
Wed, 1 Feb 2006 15:58:30 +0000 (15:58 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 1 Feb 2006 15:58:30 +0000 (15:58 +0000)
rewrite of GetSomeSpace_r to get rid of the brokenness we had before.

also make GetCapabilities work like other rpc stubs which don't need callbacks

src/viced/afsfileprocs.c
src/viced/callback.c
src/viced/fs_stats.h
src/viced/host.h
src/viced/viced.h

index 98369607cbf3b11f475b5d17630efe55be22517a..c1e2ffa0c8e53cb5c008dec9017768db9bb1fc18 100644 (file)
@@ -344,7 +344,7 @@ CallPreamble(register struct rx_call *acall, int activecall,
 
     thost = tclient->host;
     tclient->LastCall = thost->LastCall = FT_ApproxTime();
-    if (activecall)            /* For all but "GetTime" calls */
+    if (activecall)            /* For all but "GetTime", "GetStats", and "GetCaps" calls */
        thost->ActiveCall = thost->LastCall;
 
     h_Lock_r(thost);
@@ -6039,9 +6039,32 @@ SRXAFS_Lookup(struct rx_call * call_p, struct AFSFid * afs_dfid_p,
 afs_int32
 SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
 {
+    afs_int32 code;
+    struct rx_connection *tcon;
     afs_int32 *dataBuffP;
     afs_int32 dataBytes;
+#if FS_STATS_DETAILED
+    struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
+    struct timeval opStartTime, opStopTime;    /* Start/stop times for RPC op */
+    struct timeval elapsedTime;        /* Transfer time */
+
+    /*
+     * Set our stats pointer, remember when the RPC operation started, and
+     * tally the operation.
+     */
+    opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETCAPABILITIES]);
+    FS_LOCK;
+    (opP->numOps)++;
+    FS_UNLOCK;
+    TM_GetTimeOfDay(&opStartTime, 0);
+#endif /* FS_STATS_DETAILED */
+
+    if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon)))
+       goto Bad_GetCaps;
 
+    FS_LOCK;
+    AFSCallStats.GetCapabilities++, AFSCallStats.TotalCalls++;
+    FS_UNLOCK;
     dataBytes = 1 * sizeof(afs_int32);
     dataBuffP = (afs_int32 *) malloc(dataBytes);
     dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS;
@@ -6052,6 +6075,28 @@ SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
     capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
     capabilities->Capabilities_val = dataBuffP;
 
+    ViceLog(2, ("SAFS_GetCapabilties\n"));
+
+  Bad_GetCaps:
+    code = CallPostamble(tcon, code);
+
+#if FS_STATS_DETAILED
+    TM_GetTimeOfDay(&opStopTime, 0);
+    fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
+    if (code == 0) {
+       FS_LOCK;
+       (opP->numSuccesses)++;
+       fs_stats_AddTo((opP->sumTime), elapsedTime);
+       fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
+       if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
+           fs_stats_TimeAssign((opP->minTime), elapsedTime);
+       }
+       if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
+           fs_stats_TimeAssign((opP->maxTime), elapsedTime);
+       }
+       FS_UNLOCK;
+    }
+#endif /* FS_STATS_DETAILED */
     return 0;
 }
 
index 4ad97f45c88e03ea5b5c6ecc7e49ee71efcc2d4c..fbc06fc625d808272d7bbf5d2025cbd63e24984e 100644 (file)
@@ -1575,15 +1575,69 @@ lih_r(register struct host *host, register int held,
     return held;
 }
 
+/* This version does not allow 'host' to be selected unless its ActiveCall 
+ * is newer than 'hostp' which is the host with the oldest ActiveCall from
+ * the last pass (if it is provided).  We filter out any hosts that are
+ * are held by other threads.
+ */
+static int
+lih0_r(register struct host *host, register int held,
+      register struct host *hostp)
+{
+    if (host->cblist
+       && (hostp && host != hostp) 
+       && (!held && !h_OtherHolds_r(host))
+       && (!lih_host || host->ActiveCall < lih_host->ActiveCall) 
+       && (!hostp || host->ActiveCall > hostp->ActiveCall)) {
+       if (lih_host != NULL && lih_host_held) {
+           h_Release_r(lih_host);
+       }
+       lih_host = host;
+       lih_host_held = !held;
+       held = 1;
+    }
+    return held;
+}
+
+/* This version does not allow 'host' to be selected unless its ActiveCall 
+ * is newer than 'hostp' which is the host with the oldest ActiveCall from
+ * the last pass (if it is provided).  In this second varient, we do not 
+ * prevent held hosts from being selected.
+ */
+static int
+lih1_r(register struct host *host, register int held,
+      register struct host *hostp)
+{
+    if (host->cblist
+       && (hostp && host != hostp) 
+       && (!lih_host || host->ActiveCall < lih_host->ActiveCall) 
+       && (!hostp || host->ActiveCall > hostp->ActiveCall)) {
+       if (lih_host != NULL && lih_host_held) {
+           h_Release_r(lih_host);
+       }
+       lih_host = host;
+       lih_host_held = !held;
+       held = 1;
+    }
+    return held;
+}
+
 /* This could be upgraded to get more space each time */
-/* first pass: find the oldest host which isn't held by anyone */
-/* second pass: find the oldest host who isn't "me" */
+/* first pass: sequentially find the oldest host which isn't held by
+               anyone for which we can clear callbacks;
+              skipping 'hostp' */
+/* second pass: sequentially find the oldest host regardless of 
+               whether or not the host is held; skipping 'hostp' */
+/* third pass: attempt to clear callbacks from 'hostp' */
 /* always called with hostp unlocked */
+
+/* Note: hostlist is ordered most recently created host first and 
+ * its order has no relationship to the most recently used. */
 extern struct host *hostList;
 static int
 GetSomeSpace_r(struct host *hostp, int locked)
 {
-    register struct host *hp, *hp1 = (struct host *)0, *hp2 = hostList;
+    register struct host *hp, *hp1, *hp2;
     int i = 0;
 
     cbstuff.GotSomeSpaces++;
@@ -1593,29 +1647,28 @@ GetSomeSpace_r(struct host *hostp, int locked)
        cbstuff.GSS3++;
        return 0;
     }
+
+    i = 0;
+    hp1 = NULL;
+    hp2 = hostList;
     do {
        lih_host = 0;
-       h_Enumerate_r(lih_r, hp2, (char *)hp1);
+       h_Enumerate_r(i == 0 ? lih0_r : lih1_r, hp2, (char *)hp1);
        hp = lih_host;
        if (hp) {
            /* set in lih_r! private copy before giving up H_LOCK */
            int lih_host_held2=lih_host_held;   
            cbstuff.GSS4++;
-           if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ )) {
+           if ((hp != hostp) && !ClearHostCallbacks_r(hp, 0 /* not locked or held */ )) {
                if (lih_host_held2)
                    h_Release_r(hp);
                return 0;
            }
            if (lih_host_held2)
                h_Release_r(hp);
-           hp2 = hp->next;
-       } else {
+           hp1 = hp;
            hp2 = hostList;
-           hp1 = hostp;
-           cbstuff.GSS1++;
-           ViceLog(5,
-                   ("GSS: Try harder for longest inactive host cnt= %d\n",
-                    i));
+       } else {
            /*
             * Next time try getting callbacks from any host even if
             * it's deleted (that's actually great since we can freely
@@ -1624,13 +1677,16 @@ GetSomeSpace_r(struct host *hostp, int locked)
             * callback timeout arrives).
             */
            i++;
+           hp1 = NULL;
+           hp2 = hostList;
+           cbstuff.GSS1++;
+           ViceLog(5,
+                   ("GSS: Try harder for longest inactive host cnt= %d\n",
+                    i));
        }
     } while (i < 2);
-    /*
-     * No choice to clear this host's callback state
-     */
-    /* third pass: we still haven't gotten any space, so we free what we had
-     * previously passed over. */
+
+    /* Could not obtain space from other hosts, clear hostp's callback state */
     cbstuff.GSS2++;
     if (!locked) {
        h_Lock_r(hostp);
index 1e0309e0361127521d635a87dc727a8b33787e64..e69dd55a664b126ee52a9e4d1604689dcb871433 100644 (file)
@@ -164,8 +164,9 @@ struct afs_PerfStats {
 #define FS_STATS_RPCIDX_BULKSTATUS     25
 #define FS_STATS_RPCIDX_XSTATSVERSION  26
 #define FS_STATS_RPCIDX_GETXSTATS      27
+#define FS_STATS_RPCIDX_GETCAPABILITIES 28
 
-#define FS_STATS_NUM_RPC_OPS           28
+#define FS_STATS_NUM_RPC_OPS           29
 
 /*
  * Assign an index to each of the File Server's RPC interface routines
index 43c5122d8225addb5b87c744fd5910f6ea2df983..0045a2ed645f9750767a96f59d969120e7255ef6 100644 (file)
@@ -80,7 +80,8 @@ struct host {
     char hcpsfailed;           /* Retry the cps call next time */
     prlist hcps;               /* cps for hostip acls */
     afs_uint32 LastCall;       /* time of last call from host */
-    afs_uint32 ActiveCall;     /* time of any call but gettime */
+    afs_uint32 ActiveCall;     /* time of any call but gettime, 
+                                   getstats and getcaps */
     struct client *FirstClient;        /* first connection from host */
     afs_uint32 cpsCall;                /* time of last cps call from this host */
     struct Interface *interface;       /* all alternate addr for client */
index 2610ee97bf1fdc2a10455637c8ff001dc79e0600..3b230e5311941ba11507cb912e3d6c73674c152f 100644 (file)
@@ -117,6 +117,7 @@ struct AFSCallStatistics {
     afs_uint32 GetRootVolume;
     afs_uint32 CheckToken;
     afs_uint32 GetTime;
+    afs_uint32 GetCapabilities;
 
     /* General Fetch/Store Stats */
     afs_uint32 TotalCalls;