Merge feat/p4-metadata-capture: atimes/crtimes/open-noatime/omit-dir-times/omit-link-times
# Conflicts: # src/shared/config.c # tests/integration/test_features.py
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"
|
||||
@@ -534,6 +535,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. */
|
||||
@@ -796,6 +802,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;
|
||||
}
|
||||
|
||||
@@ -1341,6 +1355,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();
|
||||
|
||||
@@ -87,6 +87,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
@@ -348,6 +348,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;
|
||||
@@ -593,7 +595,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;
|
||||
@@ -670,7 +673,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;
|
||||
@@ -924,7 +928,8 @@ Chunk* directory_scanner_next(DirectoryScanner* scanner) {
|
||||
if (scanner->hardlinks && S_ISREG(stats.st_mode))
|
||||
scanner_assign_hardlink(scanner, scanner->hardlinks, file, &stats);
|
||||
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);
|
||||
@@ -1257,7 +1262,8 @@ static void scan_root_entry(const ScannerOptions* options, const FilterNode* roo
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -15,6 +15,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;
|
||||
@@ -81,6 +85,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