summaryrefslogtreecommitdiff
path: root/c_src
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-04-03 17:48:48 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-04-13 10:03:06 -0400
commit24f9bd29a6755d4114e061c4162854d6f8a910a2 (patch)
treed66885832700eaed1ee1bc0e9db74160d5346108 /c_src
parentbf44ffca509227fd753d67a0eb57c95f3fee6631 (diff)
posix_to_bcachefs: Process dirents in sorted order
This improves reproducability when producing images. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'c_src')
-rw-r--r--c_src/posix_to_bcachefs.c23
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);
}