You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2023/02/22 02:49:30 UTC
[trafficserver] branch 9.2.x updated: Issue 9274: read-while-writer readers can't find fragment inserted (#9303)
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.2.x by this push:
new 50ede0126 Issue 9274: read-while-writer readers can't find fragment inserted (#9303)
50ede0126 is described below
commit 50ede012674166578cc9273637e507800e6a7933
Author: Brett Granger <68...@users.noreply.github.com>
AuthorDate: Mon Feb 6 19:38:51 2023 -0500
Issue 9274: read-while-writer readers can't find fragment inserted (#9303)
* Issue 9274: read-while-writer readers can't find fragment inserted
When last_collision is set, dir_probe starts at the bucket head
and skips all collisions until last_collision is reached, then
continues the probe from that point. dir_insert always inserts
new entries immediately after the bucket head. So unless last_collision
is the bucket head, any new entries inserted with last_collision
set will be inserted before last_collision and will never be found
by rww readers.
Modify dir_insert to always insert new entries at the tail of the
list. This will entail walking the entire list once on each insert.
However, the lists should be entirely in memory and quite short,
so this should not present too much performance hit.
* fix regression test failure
add a loop counter to break out of infinite loop in corrupt_bucket
test. Worst case is that every directory entry could be added to
the same bucket (won't happen in real usage, but does happen in
the test), so need to set the counter to break out after maximum
number of entries in a segment.
* Fix formatting
---------
Co-authored-by: Brett Granger <bg...@synamedia.com>
(cherry picked from commit 92800eb0890e4926f7bec82565d8331e30d106d8)
---
iocore/cache/CacheDir.cc | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/iocore/cache/CacheDir.cc b/iocore/cache/CacheDir.cc
index bb029d2f2..9bc55fa93 100644
--- a/iocore/cache/CacheDir.cc
+++ b/iocore/cache/CacheDir.cc
@@ -639,8 +639,21 @@ Lagain:
goto Lagain;
}
Llink:
- dir_set_next(e, dir_next(b));
- dir_set_next(b, dir_to_offset(e, seg));
+ // dir_probe searches from head to tail of list and resumes from last_collision.
+ // Need to insert at the tail of the list so that no entries can be inserted
+ // before last_collision. This means walking the entire list on each insert,
+ // but at least the lists are completely in memory and should be quite short
+ Dir *prev, *last;
+
+ l = 0;
+ last = b;
+ do {
+ prev = last;
+ last = next_dir(last, seg);
+ } while (last && (++l <= d->buckets * DIR_DEPTH));
+
+ dir_set_next(e, 0);
+ dir_set_next(prev, dir_to_offset(e, seg));
Lfill:
dir_assign_data(e, to_part);
dir_set_tag(e, key->slice32(2));
@@ -716,8 +729,18 @@ Lagain:
}
Llink:
CACHE_INC_DIR_USED(d->mutex);
- dir_set_next(e, dir_next(b));
- dir_set_next(b, dir_to_offset(e, seg));
+ // as with dir_insert above, need to insert new entries at the tail of the linked list
+ Dir *prev, *last;
+
+ l = 0;
+ last = b;
+ do {
+ prev = last;
+ last = next_dir(last, seg);
+ } while (last && (++l <= d->buckets * DIR_DEPTH));
+
+ dir_set_next(e, 0);
+ dir_set_next(prev, dir_to_offset(e, seg));
Lfill:
dir_assign_data(e, dir);
dir_set_tag(e, t);