]> Sergey Matveev's repositories - bfs.git/commitdiff
dir: New flag to control whiteout visibility
authorTavian Barnes <tavianator@tavianator.com>
Tue, 17 Oct 2023 15:43:43 +0000 (11:43 -0400)
committerTavian Barnes <tavianator@tavianator.com>
Tue, 17 Oct 2023 16:33:39 +0000 (12:33 -0400)
src/dir.c
src/dir.h

index 371696f34bb2fa0acf74c15e2809fb362a07e7a2..98518f2e164330ca492b5223406225a9e4cbfbfb 100644 (file)
--- 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'));
index 7e0cbba8f5898d5d6b929730d56c49793e9f32fc..b11d454f01c6f89054e0b10b4b5134b1c0799aec 100644 (file)
--- 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,
 };
 
 /**