From 773f4a446f03da62d88e6d17be49fdc0a3e38465 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 12 Oct 2023 15:13:02 -0400 Subject: bftw: Fix to_close list corruption with !BFS_USE_UNWRAPDIR It's possible for pincount to drop to zero, then get incremented and drop back to zero again. If this happens, we shouldn't add it to the to_close list twice. This should fix the intermittent hang on the macOS CI. Fixes: 815798e1eea7fc8dacd5acab40202ec4d251d517 --- src/bftw.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/bftw.c') diff --git a/src/bftw.c b/src/bftw.c index c0bff75..1995e12 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -546,6 +546,17 @@ static int bftw_state_init(struct bftw_state *state, const struct bftw_args *arg return 0; } +/** Unpin a directory, and possibly queue it for unwrapping. */ +static void bftw_unpin_dir(struct bftw_state *state, struct bftw_file *file, bool force) { + bftw_cache_unpin(&state->cache, file); + + if (file->dir && (force || file->pincount == 0)) { + if (!SLIST_ATTACHED(&state->to_close, file)) { + SLIST_APPEND(&state->to_close, file); + } + } +} + /** Pop a response from the I/O queue. */ static int bftw_ioq_pop(struct bftw_state *state, bool block) { struct ioq *ioq = state->ioq; @@ -582,10 +593,7 @@ static int bftw_ioq_pop(struct bftw_state *state, bool block) { ++cache->capacity; parent = file->parent; if (parent) { - bftw_cache_unpin(cache, parent); - if (parent->pincount == 0 && parent->dir) { - SLIST_APPEND(&state->to_close, parent); - } + bftw_unpin_dir(state, parent, false); } dir = ent->opendir.dir; @@ -1285,8 +1293,7 @@ static int bftw_gc(struct bftw_state *state, enum bftw_gc_flags flags) { struct bftw_file *file = state->file; if (file && file->dir) { - bftw_cache_unpin(&state->cache, file); - SLIST_APPEND(&state->to_close, file); + bftw_unpin_dir(state, file, true); } state->dir = NULL; state->de = NULL; -- cgit v1.2.3