]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: cache: do not retain imcomplete or stripped secondary entry
authorRémi Tricot-Le Breton <rlebreton@haproxy.com>
Mon, 10 Aug 2026 15:22:43 +0000 (17:22 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 12 Aug 2026 07:17:56 +0000 (09:17 +0200)
Skip retaining secondary entries altogether if its row was recycled
while we were looking it up, which CACHE_EF_COMPLETE having been cleared
tells us. Such an entry was already treated as a miss, only further down
and after having been detached.

This patch does not need to be backported.

src/cache.c

index 4019d5f2f8eda3a20f5b249918470abf929db898..0d517efe1027bd1ef1d74b3e7dbf38e756dd96ab 100644 (file)
@@ -2699,13 +2699,21 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
                                        shctx_wrlock(shctx);
                                        if (detached)
                                                cache_row_reattach(cache, entry_block);
-                                       entry_block = block_ptr(sec_entry);
                                        /* Same as for the primary entry above: retain
                                         * this one under the lock that detaches its
-                                        * row.
+                                        * row, and only if that row was not recycled
+                                        * while we were looking the entry up. An
+                                        * incomplete or stripped entry is a miss
+                                        * anyway, it was just detected further down.
                                         */
-                                       retain_entry(sec_entry);
-                                       shctx_row_detach(shctx, entry_block);
+                                       if ((sec_entry->flags & CACHE_EF_COMPLETE) &&
+                                           !(sec_entry->flags & CACHE_EF_STRIPPED)) {
+                                               entry_block = block_ptr(sec_entry);
+                                               retain_entry(sec_entry);
+                                               shctx_row_detach(shctx, entry_block);
+                                       }
+                                       else
+                                               sec_entry = NULL;
                                        shctx_wrunlock(shctx);
                                }
                                res = sec_entry;