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
-2
@@ -60,7 +60,7 @@ bool path_is_within_root(const char* root, const char* path) {
|
||||
* two differ in create-vs-no-create, in what path component they stop at, and
|
||||
* in the extra receiver policies they apply, so they are intentionally kept
|
||||
* separate. Both rely on the shared lexical path_is_within_root check. */
|
||||
static int open_authorized_destination(const char* dest_root) {
|
||||
int utils_open_authorized_destination(const char* dest_root) {
|
||||
int root_fd = utils_get_authorized_root_fd();
|
||||
const char* root_path = utils_get_authorized_root_path();
|
||||
if (root_fd < 0 || !root_path || !dest_root || !path_is_within_root(root_path, dest_root))
|
||||
@@ -752,7 +752,7 @@ DeleteWalkResult delete_extras_limited(const char* dest_root, const ArrayList* m
|
||||
int root_fd = utils_get_authorized_root_fd();
|
||||
if (root_fd >= 0) {
|
||||
if (utils_get_authorized_root_path())
|
||||
rootfd = open_authorized_destination(dest_root);
|
||||
rootfd = utils_open_authorized_destination(dest_root);
|
||||
else if (dest_root == NULL)
|
||||
rootfd = dup(root_fd);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user