From 862e29a98aee72918fc25e960556f732ba80522c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 2 Nov 2010 16:16:20 -0400 Subject: [PATCH] Windows: Do not leak cm_volume_t objects from the LRU queue During cm_volume_t object recycling the object is removed from the LRU to ensure that a single object is not recycled by multiple threads at the same time. Before cm_FindVolumeByName() exits the object must be re-inserted into the LRU if it is not present. LICENSE MIT Change-Id: I3feb3fb55beddffdbbf52a79efcc8d44af39b891 Reviewed-on: http://gerrit.openafs.org/3220 Reviewed-by: Derrick Brashear Tested-by: BuildBot Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- src/WINNT/afsd/cm_volume.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index 6a85c05ccd..23ee84d2ed 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -900,6 +900,11 @@ long cm_FindVolumeByName(struct cm_cell *cellp, char *volumeNamep, osi_Log2(afsd_logp, "Recycling Volume %s:%s", volp->cellp->name, volp->namep); + /* The volp is removed from the LRU queue in order to + * prevent two threads from attempting to recycle the + * same object. This volp must be re-inserted back into + * the LRU queue before this function exits. + */ if (volp->flags & CM_VOLUMEFLAG_IN_LRU_QUEUE) cm_RemoveVolumeFromLRU(volp); if (volp->flags & CM_VOLUMEFLAG_IN_HASH) @@ -968,12 +973,11 @@ long cm_FindVolumeByName(struct cm_cell *cellp, char *volumeNamep, if (code == 0) { *outVolpp = volp; - if ((volp->flags & CM_VOLUMEFLAG_IN_LRU_QUEUE) && - !(flags & CM_GETVOL_FLAG_NO_LRU_UPDATE)) { - lock_ObtainWrite(&cm_volumeLock); + lock_ObtainRead(&cm_volumeLock); + if (!(volp->flags & CM_VOLUMEFLAG_IN_LRU_QUEUE) || + (flags & CM_GETVOL_FLAG_NO_LRU_UPDATE)) cm_AdjustVolumeLRU(volp); - lock_ReleaseWrite(&cm_volumeLock); - } + lock_ReleaseRead(&cm_volumeLock); } else { /* * do not return it to the caller but do insert it in the LRU