remote.sync: keep a changed object even with no entry at its path

Deleting a changed object when no entry holds the path also deletes a
copy a directory rename has written but not yet made visible, while a
delete of that path waits in the sync; the rename then removes the old
key and the content is gone. Keep any object whose ETag changed since
the delete, as before. An upload that finishes after the delete leaks
its object instead, which is the cheaper failure.
This commit is contained in:
Alex Russell committed 2026-10-12 05:36:15 +02:00
1 parent a76ed8dd7a
commit bc6f528d97
2 files changed
+11 -9

No files matched your search

+5 -3
View File
@@ -247,9 +247,11 @@ func processDeleteEvent(
// The object at the key may have been replaced since the delete: a
// rename copies another entry's content onto it, a rewrite uploads
// over it. Match the recorded etag before deleting so only the
// object the delete meant goes away. A changed object with no entry
// at the path is an upload that finished after the delete, and goes.
if oldETag := message.OldEntry.GetRemoteEntry().GetRemoteETag(); oldETag != "" && current != nil {
// object the delete meant goes away. That holds with no entry at the
// path too: a rename copies before its new entry becomes visible. An
// upload that finished after the delete is kept the same way, which
// leaks that object rather than risking the only copy of a rename.
if oldETag := message.OldEntry.GetRemoteEntry().GetRemoteETag(); oldETag != "" {
if live, err := client.StatFile(dest); err == nil {
if live.RemoteETag != "" && live.RemoteETag != oldETag {
glog.V(0).Infof("keep %s: the object changed since the delete", remote_storage.FormatLocation(dest))