GetVolume: do not wait for offlining volumes

In non-DAFS GetVolume, previously we waited for a volume with
vp->goingOffline set to go offline before we return. However, the
fileserver afsfileprocs.c case can treat the "going offline" case and
the "is offline" case identically, so there is no reason to wait. So
make the fileserver call a new GetVolume variant that does not wait.

Without this, all of the threads in the fileserver can potentially be
tied up by waiting for a volume to go offline, if the volume is taking
a long time to go offline due to an offline request following a client
slowly accessing the volume.

Change-Id: I58ae11e585852130154389d8df0567432cd0c2df
Reviewed-on: http://gerrit.openafs.org/2124
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Tom Keiser <tkeiser@sinenomine.net>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Andrew Deason 2010-06-08 17:28:39 -05:00 committed by Derrick Brashear
parent d7c79cec82
commit 581aafaa69
3 changed files with 19 additions and 5 deletions

View File

@ -491,7 +491,7 @@ CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
;
errorCode = 0;
*volptr = VGetVolume(&local_errorCode, &errorCode, (afs_int32) fid->Volume);
*volptr = VGetVolumeNoWait(&local_errorCode, &errorCode, (afs_int32) fid->Volume);
if (!errorCode) {
assert(*volptr);
break;

View File

@ -3472,6 +3472,18 @@ VGetVolume(Error * ec, Error * client_ec, VolId volumeId)
return retVal;
}
/* same as VGetVolume, but if a volume is waiting to go offline, we return
* that it is actually offline, instead of waiting for it to go offline */
Volume *
VGetVolumeNoWait(Error * ec, Error * client_ec, VolId volumeId)
{
Volume *retVal;
VOL_LOCK;
retVal = GetVolume(ec, client_ec, volumeId, NULL, 1);
VOL_UNLOCK;
return retVal;
}
Volume *
VGetVolume_r(Error * ec, VolId volumeId)
{
@ -3493,7 +3505,8 @@ VGetVolumeByVp_r(Error * ec, Volume * vp)
* @param[out] client_ec wire error code to be given to clients
* @param[in] volumeId ID of the volume we want
* @param[in] hint optional hint for hash lookups, or NULL
* @param[in] flags unused; always 0
* @param[in] nowait 0 to wait for a 'goingOffline' volume to go offline
* before returning, 1 to return immediately
*
* @return a volume handle for the specified volume
* @retval NULL an error occurred, or the volume is in such a state that
@ -3502,7 +3515,7 @@ VGetVolumeByVp_r(Error * ec, Volume * vp)
* @note for DAFS, caller must NOT hold a ref count on 'hint'
*/
static Volume *
GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int flags)
GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int nowait)
{
Volume *vp = hint;
/* pull this profiling/debugging code out of regular builds */
@ -3755,7 +3768,7 @@ GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int flag
if (programType == fileServer) {
VGET_CTR_INC(V9);
if (vp->goingOffline) {
if (vp->goingOffline && !nowait) {
VGET_CTR_INC(V10);
#ifdef AFS_DEMAND_ATTACH_FS
/* wait for the volume to go offline */
@ -3775,7 +3788,7 @@ GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int flag
} else if (V_inService(vp) == 0 || V_blessed(vp) == 0) {
VGET_CTR_INC(V12);
*ec = VNOVOL;
} else if (V_inUse(vp) == 0) {
} else if (V_inUse(vp) == 0 || vp->goingOffline) {
VGET_CTR_INC(V13);
*ec = VOFFLINE;
} else {

View File

@ -758,6 +758,7 @@ struct volHeader {
extern char *VSalvageMessage; /* Canonical message when a volume is forced
* offline */
extern Volume *VGetVolume(Error * ec, Error * client_ec, VolId volumeId);
extern Volume *VGetVolumeNoWait(Error * ec, Error * client_ec, VolId volumeId);
extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
extern void VPutVolume(Volume *);
extern void VPutVolume_r(Volume *);