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
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:
@@ -4,6 +4,7 @@
|
||||
#include "compression.h"
|
||||
#include "config.h"
|
||||
#include "delta.h"
|
||||
#include "file.h"
|
||||
#include "file_list.h"
|
||||
#include "filter.h"
|
||||
#include "identity.h"
|
||||
@@ -533,6 +534,11 @@ static const OptionEntry OPTION_TABLE[] = {
|
||||
{"--cvs-exclude", "-C", OPT_FLAG, offsetof(Config, cvs_exclude)},
|
||||
{"-F", NULL, OPT_FLAG, offsetof(Config, per_dir_filter)},
|
||||
{"--numeric-ids", NULL, OPT_FLAG, offsetof(Config, numeric_ids)},
|
||||
{"--atimes", "-U", OPT_FLAG, offsetof(Config, preserve_atimes)},
|
||||
{"--crtimes", "-N", OPT_FLAG, offsetof(Config, preserve_crtimes)},
|
||||
{"--omit-dir-times", "-O", OPT_FLAG, offsetof(Config, omit_dir_times)},
|
||||
{"--omit-link-times", "-J", OPT_FLAG, offsetof(Config, omit_link_times)},
|
||||
{"--open-noatime", NULL, OPT_FLAG, offsetof(Config, open_noatime)},
|
||||
};
|
||||
|
||||
/* Only boolean options with no required argument are safe to negate. */
|
||||
@@ -794,6 +800,14 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
||||
config. */
|
||||
if (entry->offset == offsetof(Config, delete_missing_args))
|
||||
config->ignore_missing_args = true;
|
||||
/* -U/--atimes and -N/--crtimes carry their times inside the metadata
|
||||
payload, which is only transmitted when use_metadata is set, so either
|
||||
one implies metadata transmission. This is FastSync's broad -M bundle
|
||||
(mode/mtime travel too); it does NOT enable ownership application,
|
||||
which stays opt-in via the identity flags. */
|
||||
if (entry->offset == offsetof(Config, preserve_atimes) ||
|
||||
entry->offset == offsetof(Config, preserve_crtimes))
|
||||
config->use_metadata = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1339,6 +1353,10 @@ int main(int argc, char* argv[]) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* --open-noatime is a sender-side policy: install it for every source read
|
||||
(scan + data path) without touching the receiver. */
|
||||
file_set_open_noatime(config->open_noatime);
|
||||
|
||||
/* Initialize TLS if needed */
|
||||
if (config->use_tls)
|
||||
tls_global_init();
|
||||
|
||||
@@ -82,6 +82,8 @@ static bool prepare_scanner(const Config* config, int num_threads, PreparedScann
|
||||
|
||||
ScannerOptions* options = &out->options;
|
||||
options->use_metadata = config->use_metadata;
|
||||
options->preserve_atimes = config->preserve_atimes;
|
||||
options->preserve_crtimes = config->preserve_crtimes;
|
||||
options->chunk_size = config->chunk_size;
|
||||
options->exclude_patterns = config->exclude_patterns;
|
||||
options->exclude_count = config->exclude_count;
|
||||
|
||||
+10
-4
@@ -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);
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
typedef struct {
|
||||
bool use_metadata;
|
||||
/* Phase 4 metadata capture: -U/--atimes and -N/--crtimes tell the scanner to
|
||||
* capture the source access / birth time into each entry's FileMetadata. */
|
||||
bool preserve_atimes;
|
||||
bool preserve_crtimes;
|
||||
unsigned long long chunk_size;
|
||||
char** exclude_patterns;
|
||||
int exclude_count;
|
||||
@@ -75,6 +79,8 @@ typedef struct {
|
||||
DIR* current_dir;
|
||||
char* current_path;
|
||||
bool use_metadata;
|
||||
bool preserve_atimes;
|
||||
bool preserve_crtimes;
|
||||
unsigned long long chunk_size;
|
||||
char** exclude_patterns;
|
||||
int exclude_count;
|
||||
|
||||
Reference in New Issue
Block a user