filer.remote.sync: upload files that were never replicated (#11140)

An entry whose content is rewritten unchanged before it first reached the
remote took the metadata-only branch, and UpdateFileMetadata returns early
when the extended attributes match without checking that the object is
there. shouldSendToRemote had already reported the entry as needing to be
sent, so the effect was that it stayed local for as long as its content did
not change, with the sync reporting healthy progress over it.

Require RemoteEntry to be set before treating an update as metadata-only.
Gating at the caller covers the S3, GCS and Azure clients, which share the
same early return.

Fixes #11139
This commit is contained in:
Alex K authored and GitHub committed 2026-09-03 17:42:40 -07:00
1 parent 57a5285020
commit c9c6e6fb1d
2 files changed
+94 -5

No files matched your search

+21 -5
View File
@@ -224,11 +224,9 @@ func (option *RemoteSyncOptions) makeEventProcessor(remoteStorage *remote_pb.Rem
if message.NewEntry.IsDirectory {
return client.WriteDirectory(dest, message.NewEntry)
}
if resp.Directory == message.NewParentPath && message.OldEntry.Name == message.NewEntry.Name {
if filer.IsSameData(message.OldEntry, message.NewEntry) {
glog.V(2).Infof("update meta: %+v", resp)
return client.UpdateFileMetadata(dest, message.OldEntry, message.NewEntry)
}
if isMetadataOnlyUpdate(resp.Directory, message) {
glog.V(2).Infof("update meta: %+v", resp)
return client.UpdateFileMetadata(dest, message.OldEntry, message.NewEntry)
}
glog.V(2).Infof("update: %+v", resp)
glog.V(0).Infof("delete %s", remote_storage.FormatLocation(oldDest))
@@ -305,6 +303,24 @@ func toRemoteStorageLocation(mountDir, sourcePath util.FullPath, remoteMountLoca
}
}
// isMetadataOnlyUpdate reports whether an update to an existing entry can be
// applied to the remote by rewriting metadata alone, instead of deleting the
// old object and writing the new content.
//
// It requires the object to already be on the remote. A nil RemoteEntry means
// it never got there, and the metadata path would return without ever writing
// it, leaving the entry unreplicated for as long as its content stays the same
// -- shouldSendToRemote has already reported that this entry needs sending.
func isMetadataOnlyUpdate(dir string, message *filer_pb.EventNotification) bool {
if dir != message.NewParentPath || message.OldEntry.Name != message.NewEntry.Name {
return false
}
if !filer.IsSameData(message.OldEntry, message.NewEntry) {
return false
}
return message.NewEntry.RemoteEntry != nil
}
func shouldSendToRemote(entry *filer_pb.Entry) bool {
if entry.RemoteEntry == nil {
return true