/* * This function returns a free (not in the LRU queue) acl cache entry. * It must be called with the cm_aclLock lock held */ static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp) { cm_aclent_t *aclp; cm_scache_t *ascp = 0; if (cm_data.aclLRUp == NULL) osi_panic("empty aclent LRU", __FILE__, __LINE__); if (cm_data.aclLRUEndp == NULL) osi_panic("inconsistent aclent LRUEndp == NULL", __FILE__, __LINE__); aclp = cm_data.aclLRUEndp; osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q); if (aclp->backp && scp != aclp->backp) { ascp = aclp->backp; lock_ReleaseWrite(&cm_aclLock); lock_ObtainWrite(&ascp->rw); lock_ObtainWrite(&cm_aclLock); } CleanupACLEnt(aclp); if (ascp) lock_ReleaseWrite(&ascp->rw); return aclp; }
/* * Get an acl cache entry for a particular user and file, or return that it doesn't exist. * Called with the scp write locked. */ long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 *rightsp) { cm_aclent_t *aclp; long retval = -1; time_t now = time(NULL); lock_AssertWrite(&scp->rw); lock_ObtainWrite(&cm_aclLock); *rightsp = 0; /* get a new acl from server if we don't find a * current entry */ for (aclp = scp->randomACLp; aclp; aclp = aclp->nextp) { if (aclp->userp == userp) { if (aclp->tgtLifetime && aclp->tgtLifetime <= now) { /* ticket expired */ osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q); CleanupACLEnt(aclp); /* move to the tail of the LRU queue */ osi_QAddT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q); } else { *rightsp = aclp->randomAccess; if (cm_data.aclLRUp != aclp) { /* move to the head of the LRU queue */ osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q); osi_QAddH((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q); } retval = 0; /* success */ } break; } } lock_ReleaseWrite(&cm_aclLock); return retval; }