fix(delete): keep the empty-scan safety guard file-only
Adding every traversed directory to the per-directory plan keep set must not make an I/O-errored partial scan look non-empty. Count only transmitted file entries for delete_plan_sender_empty(), so a scan that hit an unreadable directory and found no files still refuses to delete.
This commit is contained in:
@@ -48,6 +48,10 @@ struct DeletePlanSender {
|
|||||||
const ArrayList* size_skipped;
|
const ArrayList* size_skipped;
|
||||||
const ArrayList* missing_args;
|
const ArrayList* missing_args;
|
||||||
size_t entries;
|
size_t entries;
|
||||||
|
/* Transmitted FILE entries only. The caller's "empty scan" safety guard keys
|
||||||
|
off this (an I/O error that hid every file must refuse to delete even when
|
||||||
|
some directories were traversed), so directory keep entries do not count. */
|
||||||
|
size_t file_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t plan_hash(const char* key) {
|
static size_t plan_hash(const char* key) {
|
||||||
@@ -254,8 +258,11 @@ bool delete_plan_sender_add(DeletePlanSender* sender, const char* path, bool is_
|
|||||||
}
|
}
|
||||||
if (ok)
|
if (ok)
|
||||||
ok = plan_ensure_ancestors(sender, parent);
|
ok = plan_ensure_ancestors(sender, parent);
|
||||||
if (ok)
|
if (ok) {
|
||||||
sender->entries++;
|
sender->entries++;
|
||||||
|
if (!is_dir)
|
||||||
|
sender->file_entries++;
|
||||||
|
}
|
||||||
free(clean);
|
free(clean);
|
||||||
free(parent);
|
free(parent);
|
||||||
free(base);
|
free(base);
|
||||||
@@ -272,7 +279,7 @@ void delete_plan_sender_finalize(DeletePlanSender* sender, const ArrayList* sync
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool delete_plan_sender_empty(const DeletePlanSender* sender) {
|
bool delete_plan_sender_empty(const DeletePlanSender* sender) {
|
||||||
return !sender || sender->entries == 0;
|
return !sender || sender->file_entries == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_plan_sender_set_config(DeletePlanSender* sender, const ArrayList* protected_prefixes,
|
void delete_plan_sender_set_config(DeletePlanSender* sender, const ArrayList* protected_prefixes,
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ bool delete_plan_sender_add(DeletePlanSender* sender, const char* path, bool is_
|
|||||||
* recursive transfer and for --files-from. */
|
* recursive transfer and for --files-from. */
|
||||||
void delete_plan_sender_finalize(DeletePlanSender* sender, const ArrayList* synced_dirs,
|
void delete_plan_sender_finalize(DeletePlanSender* sender, const ArrayList* synced_dirs,
|
||||||
const char* walk_root);
|
const char* walk_root);
|
||||||
/* True when no transmitted entry was recorded (an ambiguous empty scan). */
|
/* True when no transmitted FILE entry was recorded (an ambiguous empty scan).
|
||||||
|
Directory keep entries do not count, so an I/O error that hid every file
|
||||||
|
still refuses to delete. */
|
||||||
bool delete_plan_sender_empty(const DeletePlanSender* sender);
|
bool delete_plan_sender_empty(const DeletePlanSender* sender);
|
||||||
/* Attach the global config sections advertised on the first plan frame. */
|
/* Attach the global config sections advertised on the first plan frame. */
|
||||||
void delete_plan_sender_set_config(DeletePlanSender* sender, const ArrayList* protected_prefixes,
|
void delete_plan_sender_set_config(DeletePlanSender* sender, const ArrayList* protected_prefixes,
|
||||||
|
|||||||
Reference in New Issue
Block a user