Пример #1
0
/**
 * @brief Deep-free a duplicate request cache entry.
 *
 * If the entry has processed request data, the corresponding free
 * function is called on the result.  The cache entry is then returned
 * to the dupreq_pool.
 */
static inline void nfs_dupreq_free_dupreq(dupreq_entry_t *dv)
{
	const nfs_function_desc_t *func;

	if (dv->res) {
		func = nfs_dupreq_func(dv);
		func->free_function(dv->res);
		free_nfs_res(dv->res);
	}
	PTHREAD_MUTEX_destroy(&dv->mtx);
	pool_free(dupreq_pool, dv);
}
Пример #2
0
/**
 * @brief Decrement the call path refcnt on a cache entry.
 *
 * We assert req->rq_u1 now points to the corresonding duplicate request
 * cache entry (dv).
 *
 * In the common case, a refcnt of 0 indicates that dv is cached.  If
 * also dv->state == DUPREQ_DELETED, the request entry has been discarded
 * and should be destroyed here.
 *
 * @param[in] req  The svc_req structure.
 * @param[in] func The function descriptor for this request type
 */
void nfs_dupreq_rele(struct svc_req *req, const nfs_function_desc_t *func)
{
	dupreq_entry_t *dv = (dupreq_entry_t *) req->rq_u1;

	/* no-cache cleanup */
	if (dv == (void *)DUPREQ_NOCACHE) {
		LogFullDebug(COMPONENT_DUPREQ, "releasing no-cache res %p",
			     req->rq_u2);
		func->free_function(req->rq_u2);
		free_nfs_res(req->rq_u2);
		goto out;
	}

	pthread_mutex_lock(&dv->mtx);

	LogFullDebug(COMPONENT_DUPREQ,
		     "releasing dv=%p xid=%u on DRC=%p state=%s, " "refcnt=%d",
		     dv, dv->hin.tcp.rq_xid, dv->hin.drc,
		     dupreq_state_table[dv->state], dv->refcnt);

	(dv->refcnt)--;
	if (dv->refcnt == 0) {
		if (dv->state == DUPREQ_DELETED) {
			pthread_mutex_unlock(&dv->mtx);
			/* deep free */
			nfs_dupreq_free_dupreq(dv);
			return;
		}
	}
	pthread_mutex_unlock(&dv->mtx);

 out:
	/* dispose RPC header */
	if (req->rq_auth)
		SVCAUTH_RELEASE(req->rq_auth, req);

	/* XXX */
	if (req->rq_rtaddr.len)
		mem_free(req->rq_rtaddr.buf, req->rq_rtaddr.len);

	(void)free_rpc_msg(req->rq_msg);

	return;
}