Enhance tarerofs_dump_tree() so that it could optionally skip whiteout
files.  Rename it to erofs_rebuild_dump_tree().

Signed-off-by: Jingbo Xu <[email protected]>
---
 include/erofs/inode.h    |  2 +-
 include/erofs/internal.h |  2 ++
 lib/inode.c              | 23 ++++++++++++++++++++---
 lib/tar.c                |  2 --
 mkfs/main.c              |  2 +-
 5 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index 1c602a8..a43cb8f 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -32,7 +32,7 @@ unsigned int erofs_iput(struct erofs_inode *inode);
 erofs_nid_t erofs_lookupnid(struct erofs_inode *inode);
 struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
                                   const char *name);
-int tarerofs_dump_tree(struct erofs_inode *dir);
+int erofs_rebuild_dump_tree(struct erofs_inode *dir, bool skip_whout);
 int erofs_init_empty_dir(struct erofs_inode *dir);
 struct erofs_inode *erofs_new_inode(void);
 struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path);
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 83a2e22..be84dc1 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -415,6 +415,8 @@ static inline u32 erofs_crc32c(u32 crc, const u8 *in, 
size_t len)
        return crc;
 }
 
+#define EROFS_WHITEOUT_DEV     0
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/inode.c b/lib/inode.c
index b967aab..dae6c11 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1323,9 +1323,14 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(int 
fd, const char *name)
        return inode;
 }
 
-int tarerofs_dump_tree(struct erofs_inode *dir)
+static bool erofs_inode_is_whiteout(struct erofs_inode *inode)
 {
-       struct erofs_dentry *d;
+       return S_ISCHR(inode->i_mode) && inode->u.i_rdev == EROFS_WHITEOUT_DEV;
+}
+
+int erofs_rebuild_dump_tree(struct erofs_inode *dir, bool skip_whout)
+{
+       struct erofs_dentry *d, *n;
        unsigned int nr_subdirs;
        int ret;
 
@@ -1368,6 +1373,18 @@ int tarerofs_dump_tree(struct erofs_inode *dir)
                return 0;
        }
 
+       if (skip_whout) {
+               list_for_each_entry_safe(d, n, &dir->i_subdirs, d_child) {
+                       if (erofs_inode_is_whiteout(d->inode)) {
+                               erofs_dbg("skip whiteout %s", 
d->inode->i_srcpath);
+                               erofs_d_invalidate(d);
+                               list_del(&d->d_child);
+                               free(d);
+                               continue;
+                       }
+               }
+       }
+
        nr_subdirs = 0;
        list_for_each_entry(d, &dir->i_subdirs, d_child)
                ++nr_subdirs;
@@ -1391,7 +1408,7 @@ int tarerofs_dump_tree(struct erofs_inode *dir)
                        continue;
 
                inode = erofs_igrab(d->inode);
-               ret = tarerofs_dump_tree(inode);
+               ret = erofs_rebuild_dump_tree(inode, skip_whout);
                dir->i_nlink += (erofs_mode_to_ftype(inode->i_mode) == 
EROFS_FT_DIR);
                erofs_iput(inode);
                if (ret)
diff --git a/lib/tar.c b/lib/tar.c
index 3180ee4..5382c54 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -19,8 +19,6 @@
 #include "erofs/xattr.h"
 #include "erofs/blobchunk.h"
 
-#define EROFS_WHITEOUT_DEV     0
-
 static char erofs_libbuf[16384];
 
 struct tar_header {
diff --git a/mkfs/main.c b/mkfs/main.c
index 3809c71..b495a54 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -947,7 +947,7 @@ int main(int argc, char **argv)
                if (err < 0)
                        goto exit;
 
-               err = tarerofs_dump_tree(root_inode);
+               err = erofs_rebuild_dump_tree(root_inode, false);
                if (err < 0)
                        goto exit;
        }
-- 
2.19.1.6.gb485710b

Reply via email to