fix(p7-times): dir-time entries only record (never create dirs); bound/chunk dir-time frames; harden list add; docs+tests
Review fixes for Phase 7 Wave D. #1 (HIGH): STATUS_DIR_TIMES entries no longer create directories. A new receiver-only File.dir_time_only flag marks dir-time entries; file_save_to_disk_full short-circuits them as FILE_SAVE_SKIPPED before any device/dir branch, so the sink still accumulates metadata into the deferred DirTimeList but creates nothing. Empty source dirs stay untransferred (-a), -m/--prune-empty-dirs semantics are preserved, and a pre-existing regular file/symlink at an empty-dir mirror path no longer aborts the transfer. dir_time_list_apply fstatat()s the leaf (AT_SYMLINK_NOFOLLOW) and skips absent/non-directory paths QUIETLY; only a real existing directory is stamped. Also initialize File.dir_time_only in file_create() (uninitialised garbage otherwise). #2 (MED): send_dir_times() chunks entries into repeated STATUS_DIR_TIMES frames of at most MAX_MANIFEST_ENTRIES, matching the receiver's per-frame bound; the tautological > INT_MAX check is gone. #3 (LOW): dir_time_list_add() assigns each grown array right after its realloc (no dangling) and advances capacity only after both succeed. #4 (LOW): RSYNC_COMPAT.md -- STATUS_MKDIR carries metadata, dir times are transmitted via STATUS_DIR_TIMES and applied at the end, empty dirs are still never created; -m rationale, -O row and Wave D notes updated. Summary counts untouched. #5 (LOW): integration tests for the three #1 scenarios (empty-dir non-creation under -a and -a -m, collision non-abort), scanner test now covers empty-dir capture, and test_file_restore_symlink_metadata asserts the positive apply path when supported. PROTOCOL_VERSION stays 2.17.0; config-frame layout unchanged.
This commit is contained in:
@@ -74,11 +74,12 @@ static bool receiver_process_chunk(Chunk* chunk, const ReceiverSink* sink) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* P7 Wave D: read the single terminal STATUS_DIR_TIMES frame (a count followed
|
||||
* by that many (path, metadata) directory entries) and route every directory
|
||||
* through the regular store_file sink. The sink's write path creates each
|
||||
* directory (idempotent -- the recursive transfer already created it as a
|
||||
* parent) and accumulates its metadata for end-of-transfer application. A
|
||||
/* P7 Wave D: read one STATUS_DIR_TIMES frame (a count followed by that many
|
||||
* (path, metadata) directory entries) and route every entry through the regular
|
||||
* store_file sink. A dir-time entry is RECORD-ONLY (file->dir_time_only): the
|
||||
* sink accumulates its metadata for end-of-transfer application but creates
|
||||
* nothing, so an empty/pruned source directory is never resurrected. A large
|
||||
* tree arrives as repeated frames, each bounded by MAX_MANIFEST_ENTRIES; a
|
||||
* malformed count or entry is a hard error. */
|
||||
static bool receiver_process_dir_times(int fd, const Config* config, const ReceiverSink* sink) {
|
||||
int count;
|
||||
|
||||
Reference in New Issue
Block a user