From 332f38aff0e6b7bc1a3a648eb66437d2d043ad21 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 17 Oct 2023 11:43:43 -0400 Subject: dir: New flag to control whiteout visibility --- src/dir.c | 12 ++++++++++-- src/dir.h | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dir.c b/src/dir.c index 371696f..98518f2 100644 --- a/src/dir.c +++ b/src/dir.c @@ -259,7 +259,8 @@ static int bfs_getdent(struct bfs_dir *dir, const sys_dirent **de) { /** Skip ".", "..", and deleted/empty dirents. */ static int bfs_skipdent(struct bfs_dir *dir, const sys_dirent *de) { -#if BFS_USE_GETDENTS && __FreeBSD__ +#if BFS_USE_GETDENTS +# if __FreeBSD__ // Union mounts on FreeBSD have to be de-duplicated in userspace if (dir->flags & BFS_DIR_UNION) { struct trie_leaf *leaf = trie_insert_str(&dir->trie, de->d_name); @@ -276,7 +277,14 @@ static int bfs_skipdent(struct bfs_dir *dir, const sys_dirent *de) { if (de->d_ino == 0) { return 1; } -#endif +# endif + +# ifdef DT_WHT + if (de->d_type == DT_WHT && !(dir->flags & BFS_DIR_WHITEOUTS)) { + return 1; + } +# endif +#endif // BFS_USE_GETDENTS const char *name = de->d_name; return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')); diff --git a/src/dir.h b/src/dir.h index 7e0cbba..b11d454 100644 --- a/src/dir.h +++ b/src/dir.h @@ -90,8 +90,10 @@ void bfs_dir_arena(struct arena *arena); * bfs_opendir() flags. */ enum bfs_dir_flags { + /** Include whiteouts in the results. */ + BFS_DIR_WHITEOUTS = 1 << 0, /** @internal Start of private flags. */ - BFS_DIR_PRIVATE = 1 << 0, + BFS_DIR_PRIVATE = 1 << 1, }; /** -- cgit v1.2.3