From: Jeffrey Altman Date: Wed, 1 Feb 2006 15:58:30 +0000 (+0000) Subject: getsomespace-r-rewrite-20060201 X-Git-Tag: openafs-devel-1_5_0~56 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=ecb9da5839e8e2ed0d52d87e426a728700bbd389;p=packages%2Fo%2Fopenafs.git getsomespace-r-rewrite-20060201 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 --- diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 98369607c..c1e2ffa0c 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -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; } diff --git a/src/viced/callback.c b/src/viced/callback.c index 4ad97f45c..fbc06fc62 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -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); diff --git a/src/viced/fs_stats.h b/src/viced/fs_stats.h index 1e0309e03..e69dd55a6 100644 --- a/src/viced/fs_stats.h +++ b/src/viced/fs_stats.h @@ -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 diff --git a/src/viced/host.h b/src/viced/host.h index 43c5122d8..0045a2ed6 100644 --- a/src/viced/host.h +++ b/src/viced/host.h @@ -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 */ diff --git a/src/viced/viced.h b/src/viced/viced.h index 2610ee97b..3b230e531 100644 --- a/src/viced/viced.h +++ b/src/viced/viced.h @@ -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;