metadata times: -U/--atimes, -N/--crtimes, --open-noatime, -O/-J
CI / lint (pull_request) Successful in 52s
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
CI / build-and-test (pull_request) Successful in 1m19s

Capture+transmit source atime (pre-read stat; O_NOATIME sender guard) and birth
time (statx STATX_BTIME); receiver restores atime with mtime (crtime not settable
portably -> transmitted, explicitly not applied). --open-noatime is client-only.
-O/-J documented as accepted no-ops (FastSync never preserves dir/symlink times).
Wire: metadata frame gains atime/crtime val+sec+nsec; PROTOCOL_VERSION
2.11.0->2.12.0. Review fixes: gate atime capture to Linux (no epoch clobber on
non-Linux), close fd on fdopen failure, honest -O/-J status (Compat no-op).
This commit is contained in:
2026-09-08 20:58:56 +02:00
parent cbb09e41ab
commit e80888ce7b
21 changed files with 767 additions and 28 deletions
+10 -4
View File
@@ -320,6 +320,8 @@ DirectoryScanner* directory_scanner_create_with_options(const char* root_directo
scanner->current_dir = NULL;
scanner->current_path = NULL;
scanner->use_metadata = options->use_metadata;
scanner->preserve_atimes = options->preserve_atimes;
scanner->preserve_crtimes = options->preserve_crtimes;
scanner->chunk_size = options->chunk_size > 0 ? options->chunk_size : DESIRED_CHUNK_SIZE;
scanner->exclude_patterns = options->exclude_patterns;
scanner->exclude_count = options->exclude_count;
@@ -564,7 +566,8 @@ static File* dirs_root_dir_file(DirectoryScanner* scanner) {
}
file->is_dir = true;
if (scanner->use_metadata) {
file->metadata = file_metadata_create(&st);
file->metadata = file_metadata_create(scanner->root_path, &st, scanner->preserve_atimes,
scanner->preserve_crtimes);
if (!file->metadata) {
file_destroy(file);
scanner->failed = true;
@@ -641,7 +644,8 @@ static File* dirs_file_for_entry(DirectoryScanner* scanner, const char* entry) {
}
}
if (scanner->use_metadata) {
file->metadata = file_metadata_create(&effective);
file->metadata = file_metadata_create(file->path, &effective, scanner->preserve_atimes,
scanner->preserve_crtimes);
if (!file->metadata) {
file_destroy(file);
scanner->failed = true;
@@ -893,7 +897,8 @@ Chunk* directory_scanner_next(DirectoryScanner* scanner) {
rel_copy = NULL;
}
if (scanner->use_metadata)
file->metadata = file_metadata_create(&stats);
file->metadata = file_metadata_create(file->path, &stats, scanner->preserve_atimes,
scanner->preserve_crtimes);
if (scanner->use_metadata && !file->metadata) {
free(rel_copy);
file_destroy(file);
@@ -1208,7 +1213,8 @@ static void scan_root_entry(const ScannerOptions* options, const FilterNode* roo
rel = NULL;
}
if (options->use_metadata)
file->metadata = file_metadata_create(&st);
file->metadata =
file_metadata_create(file->path, &st, options->preserve_atimes, options->preserve_crtimes);
if (options->use_metadata && !file->metadata) {
free(rel);
file_destroy(file);