mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
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:
parent
d7c79cec82
commit
581aafaa69
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user