feat(delete): per-directory delete plans for --delete-during/--delete-delay (protocol 2.24.0)
Stream one delete plan per source directory from sender to receiver instead of a single whole-tree keep-set manifest: - --delete-during applies each directory's extras as its plan arrives, before that directory's data (rsync's generator-order deletion). - --delete-delay snapshots each directory's extras while the plan arrives and commits the removals only after a fully-successful transfer, so files created after the scan survive (matching rsync's delete-delay, not delete-after). - Type conflicts (a destination file blocking a source directory, or vice versa) are cleared immediately in both modes, so the nested write succeeds. The plan carries the destination-relative directory, its kept child directory names and its kept child file names; the first frame also carries the global protected prefixes, size-skipped prefixes and --delete-missing-args paths. --delete-before keeps the existing whole-tree early manifest; plain --delete and --delete-after keep the end-of-transfer manifest commit. Preserves the existing safety surface: protected/size-skipped prefixes and the --delay-updates/basis skips are honored at any depth, deletion is scoped to the synchronized directories (--files-from), MAX_SERVER_DELETE_COUNT and --max-delete (partial + exit 25) are shared across plans, symlinks are never followed, and paths are confined to the receive root.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define RECEIVER_H
|
||||
|
||||
#include "config.h"
|
||||
#include "delete_plan.h"
|
||||
#include "file.h"
|
||||
#include "file_receive.h"
|
||||
#include "protocol.h"
|
||||
@@ -53,10 +54,12 @@ int receiver_process(Config* config, int file_descriptor, const ReceiverSink* si
|
||||
when `pending_manifest` is non-NULL the receiver does NOT delete at
|
||||
STATUS_FINISHED itself; instead it stores the owned keep-set manifest there
|
||||
(leaving *pending_manifest untouched on early modes/errors) so the caller can
|
||||
commit the deletion only after its disk writer has fully drained. Pass NULL
|
||||
to keep the default behaviour (delete before the success frame). */
|
||||
commit the deletion only after its disk writer has fully drained. Likewise,
|
||||
when `pending_plans` is non-NULL the --delete-delay per-directory session is
|
||||
handed to the caller instead of being committed at STATUS_FINISHED. Pass NULL
|
||||
for either to keep the default behaviour (delete before the success frame). */
|
||||
int receiver_process_pending(Config* config, int file_descriptor, const ReceiverSink* sink,
|
||||
DeleteManifest** pending_manifest);
|
||||
DeleteManifest** pending_manifest, DeletePlanSession** pending_plans);
|
||||
int receiver_receive_files(Config* config, int file_descriptor);
|
||||
|
||||
/* ---- Connection time bounds (anti-slowloris) ----
|
||||
|
||||
Reference in New Issue
Block a user