You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2023/02/07 00:38:58 UTC
[trafficserver] branch master 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.
masaori pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 92800eb089 Issue 9274: read-while-writer readers can't find fragment inserted (#9303)
92800eb089 is described below
commit 92800eb0890e4926f7bec82565d8331e30d106d8
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>
---
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 1038c3e0a2..6baf3be842 100644
--- a/iocore/cache/CacheDir.cc
+++ b/iocore/cache/CacheDir.cc
@@ -640,8 +640,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));
@@ -717,8 +730,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);