mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
afs: Prioritize removal of unlinked vcaches
On some platforms (such as LINUX), unlinked vcaches are not destroyed until the next execution of afs_ShakeLooseVCaches(). Since the hash for a given vcache is computed from its volume id and vnode number, keeping unlinked vcaches around can be a problem if files are repeatedly deleted and recreated in the same volume. In this scenario, the same vnode number will be reused several times, resulting in many vcaches with the same volume id and vnode number (but different unique ids) in the same bucket. Consequently, finding a given vcache in the bucket in question can be time consuming (and cause extra cpu processing), as we would have to traverse a long linked list. To mitigate this problem, move vcaches associated with unlinked files to the least recently used position in our VLRU, prioritizing their removal the next time afs_ShakeLooseVCaches() is executed. Introduce the QAddEnd() macro to make it easier to add a vcache to the end of the VLRU. Change-Id: Idc74da0c3c0b27bfdf2cd491b003bdd42c889a95 Reviewed-on: https://gerrit.openafs.org/14961 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Reviewed-by: Mark Vitale <mvitale@sinenomine.net> Reviewed-by: Michael Meffie <mmeffie@sinenomine.net> Reviewed-by: Andrew Deason <adeason@sinenomine.net>
This commit is contained in:
parent
1ccc87bbdc
commit
3f393cea96
@ -48,6 +48,31 @@ FetchWholeEnchilada(struct vcache *avc, struct vrequest *areq)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move vcache to the tail of our VLRU.
|
||||
*
|
||||
* Move this vcache to the 'least recently used position' in our VLRU so it can
|
||||
* be flushed the next time afs_ShakeLooseVCaches() is executed.
|
||||
*
|
||||
* @param[in] avc vcache to be moved
|
||||
*
|
||||
* @pre afs_xvcache is NOT held
|
||||
*/
|
||||
static void
|
||||
DemoteSmushedVCache(struct vcache *avc)
|
||||
{
|
||||
/*
|
||||
* Don't block on afs_xvcache. If we can't get it, let the regular flushing
|
||||
* mechanism deal with this entry later (best-effort).
|
||||
*/
|
||||
if (NBObtainWriteLock(&afs_xvcache, 1210) == 0) {
|
||||
QRemove(&avc->vlruq);
|
||||
QAddEnd(&VLRU, &avc->vlruq);
|
||||
|
||||
ReleaseWriteLock(&afs_xvcache);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
afsremove(struct vcache *adp, struct dcache *tdc,
|
||||
struct vcache *tvc, char *aname, afs_ucred_t *acred,
|
||||
@ -116,6 +141,7 @@ afsremove(struct vcache *adp, struct dcache *tdc,
|
||||
* call FindVCache instead of GetVCache since if the file's really
|
||||
* gone, we won't be able to fetch the status info anyway. */
|
||||
if (tvc) {
|
||||
int smushed = 0;
|
||||
if (afs_mariner)
|
||||
afs_MarinerLog("store$Removing", tvc);
|
||||
ObtainWriteLock(&tvc->lock, 141);
|
||||
@ -124,10 +150,20 @@ afsremove(struct vcache *adp, struct dcache *tdc,
|
||||
tvc->f.m.LinkCount--;
|
||||
tvc->f.states &= ~CUnique; /* For the dfs xlator */
|
||||
if (tvc->f.m.LinkCount == 0 && !osi_Active(tvc)) {
|
||||
if (!AFS_NFSXLATORREQ(acred))
|
||||
if (!AFS_NFSXLATORREQ(acred)) {
|
||||
afs_TryToSmush(tvc, acred, 0);
|
||||
smushed = 1;
|
||||
}
|
||||
}
|
||||
ReleaseWriteLock(&tvc->lock);
|
||||
|
||||
if (smushed) {
|
||||
/*
|
||||
* On many platforms, the VFS holds an additional reference on the
|
||||
* vcache, so we cannot flush it here. Mark it to be flushed later.
|
||||
*/
|
||||
DemoteSmushedVCache(tvc);
|
||||
}
|
||||
afs_PutVCache(tvc);
|
||||
}
|
||||
return (0);
|
||||
|
@ -239,6 +239,9 @@ struct afs_q {
|
||||
#define QInit(q) ((q)->prev = (q)->next = (q))
|
||||
#define QAdd(q,e) ((e)->next = (q)->next, (e)->prev = (q), \
|
||||
(q)->next->prev = (e), (q)->next = (e))
|
||||
/* QAddEnd adds 'e' to the end of queue 'q' */
|
||||
#define QAddEnd(q,e) ((e)->prev = (q)->prev, (e)->next = (q), \
|
||||
(q)->prev->next = (e), (q)->prev = (e))
|
||||
#define QRemove(e) ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
|
||||
#define QNext(e) ((e)->next)
|
||||
#define QPrev(e) ((e)->prev)
|
||||
|
Loading…
Reference in New Issue
Block a user