From 68949cf1b9cb5336ea06ad7f87db8e28b620f2ac Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 17 Oct 2023 11:55:19 -0400 Subject: bftw: New flag to control whiteout visibility --- src/bftw.c | 18 ++++++++++++++++-- src/bftw.h | 2 ++ src/eval.c | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bftw.c b/src/bftw.c index e2f1a66..dff949f 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -41,6 +41,13 @@ static const struct bfs_stat *bftw_stat_impl(struct BFTW *ftwbuf, struct bftw_st errno = cache->error; } else if (bfs_stat(ftwbuf->at_fd, ftwbuf->at_path, flags, &cache->storage) == 0) { cache->buf = &cache->storage; +#ifdef S_IFWHT + } else if (errno == ENOENT && ftwbuf->type == BFS_WHT) { + // This matches the behavior of FTS_WHITEOUT on BSD + memset(&cache->storage, 0, sizeof(cache->storage)); + cache->storage.mode = S_IFWHT; + cache->buf = &cache->storage; +#endif } else { cache->error = errno; } @@ -410,6 +417,8 @@ struct bftw_state { enum bftw_strategy strategy; /** The mount table. */ const struct bfs_mtab *mtab; + /** bfs_opendir() flags. */ + enum bfs_dir_flags dir_flags; /** The appropriate errno value, if any. */ int error; @@ -492,6 +501,7 @@ static int bftw_state_init(struct bftw_state *state, const struct bftw_args *arg state->flags = args->flags; state->strategy = args->strategy; state->mtab = args->mtab; + state->dir_flags = 0; state->error = 0; if (args->nopenfd < 2) { @@ -527,6 +537,10 @@ static int bftw_state_init(struct bftw_state *state, const struct bftw_args *arg state->flags |= BFTW_BUFFER; } + if (state->flags & BFTW_WHITEOUTS) { + state->dir_flags |= BFS_DIR_WHITEOUTS; + } + SLIST_INIT(&state->dir_batch); SLIST_INIT(&state->to_open); SLIST_INIT(&state->to_read); @@ -856,7 +870,7 @@ static int bftw_ioq_opendir(struct bftw_state *state, struct bftw_file *file) { goto unpin; } - if (ioq_opendir(state->ioq, dir, dfd, file->name, 0, file) != 0) { + if (ioq_opendir(state->ioq, dir, dfd, file->name, state->dir_flags, file) != 0) { goto free; } @@ -1018,7 +1032,7 @@ static struct bfs_dir *bftw_file_opendir(struct bftw_state *state, struct bftw_f return NULL; } - if (bfs_opendir(dir, fd, NULL, 0) != 0) { + if (bfs_opendir(dir, fd, NULL, state->dir_flags) != 0) { bftw_freedir(cache, dir); return NULL; } diff --git a/src/bftw.h b/src/bftw.h index 940532c..2b36b8b 100644 --- a/src/bftw.h +++ b/src/bftw.h @@ -156,6 +156,8 @@ enum bftw_flags { BFTW_SORT = 1 << 8, /** Read each directory into memory before processing its children. */ BFTW_BUFFER = 1 << 9, + /** Include whiteouts in the search results. */ + BFTW_WHITEOUTS = 1 << 10, }; /** diff --git a/src/eval.c b/src/eval.c index adf7a0b..3d396fa 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1572,6 +1572,7 @@ static void dump_bftw_flags(enum bftw_flags flags) { DEBUG_FLAG(flags, BFTW_PRUNE_MOUNTS); DEBUG_FLAG(flags, BFTW_SORT); DEBUG_FLAG(flags, BFTW_BUFFER); + DEBUG_FLAG(flags, BFTW_WHITEOUTS); bfs_assert(flags == 0, "Missing bftw flag 0x%X", flags); } -- cgit v1.2.3