In http_action_req_cache_use() with Vary, the row of the secondary entry
matching the request is detached from the avail list for reading. Since
get_secondary_entry() only rejects expired entries, that secondary may
be incomplete (still being written by another stream), and in that case
the request was forwarded without reattaching the row, leaking its
blocks out of the avail list (refcount and nbav never restored). Over a
Vary workload this eventually prevents the cache from reserving any row.
Reattach the row before returning, as the other paths that give up on
the cache entry do.
Present since the Vary support was added in 2.4 (
1785f3dd9); to be
backported as far as 2.6.
return ACT_RET_CONT;
} else if (!res->complete) {
release_entry(cache_tree, res, 1);
+ shctx_wrlock(shctx);
+ shctx_row_reattach(shctx, entry_block);
+ shctx_wrunlock(shctx);
return ACT_RET_CONT;
}