diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-04-03 17:48:48 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-04-13 10:03:06 -0400 |
commit | 24f9bd29a6755d4114e061c4162854d6f8a910a2 (patch) | |
tree | d66885832700eaed1ee1bc0e9db74160d5346108 | |
parent | bf44ffca509227fd753d67a0eb57c95f3fee6631 (diff) |
posix_to_bcachefs: Process dirents in sorted order
This improves reproducability when producing images.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | c_src/posix_to_bcachefs.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/c_src/posix_to_bcachefs.c b/c_src/posix_to_bcachefs.c index 72ea11b8..15455a66 100644 --- a/c_src/posix_to_bcachefs.c +++ b/c_src/posix_to_bcachefs.c @@ -1,6 +1,7 @@ #include <dirent.h> #include <sys/xattr.h> #include <linux/dcache.h> +#include <linux/sort.h> #include <linux/xattr.h> #include "posix_to_bcachefs.h" @@ -313,6 +314,14 @@ static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst, fiemap_iter_exit(&iter); } +static int dirent_cmp(const void *_l, const void *_r) +{ + const struct dirent *l = _l; + const struct dirent *r = _r; + + return strcmp(l->d_name, r->d_name); +} + static void copy_dir(struct copy_fs_state *s, struct bch_fs *c, struct bch_inode_unpacked *dst, @@ -321,8 +330,17 @@ static void copy_dir(struct copy_fs_state *s, { DIR *dir = fdopendir(src_fd); struct dirent *d; + DARRAY(struct dirent) dirents = {}; + + while ((errno = 0), (d = readdir(dir))) + darray_push(&dirents, *d); - while ((errno = 0), (d = readdir(dir))) { + if (errno) + die("readdir error: %m"); + + sort(dirents.data, dirents.nr, sizeof(dirents.data[0]), dirent_cmp, NULL); + + darray_for_each(dirents, d) { struct bch_inode_unpacked inode; int fd; @@ -401,8 +419,7 @@ next: free(child_path); } - if (errno) - die("readdir error: %m"); + darray_exit(&dirents); closedir(dir); } |