From bbd2a7fbc5029dd48bfd5b26f255028c2f7304da Mon Sep 17 00:00:00 2001 From: Luke Hamburg <1992842+luckman212@users.noreply.github.com> Date: Sat, 2 Mar 2024 09:55:18 -0500 Subject: [PATCH] lib/model: Ignore difference in extended attributes & ownership when deleting (fixes #9371) (#9430) Adds a bool flag to `scanIfItemChanged()` to indicate when the scan was initiated from a delete function, and if so, tell `IsEquivalentOptional()` to ignore Xattrs and Ownership regardless of the global setting. I tested this with my sledgehammer and it seems to pass. --- lib/model/folder_sendrecv.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index 95badd1c8..2b77b67f0 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -596,7 +596,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo, snap *db.Snapshot, case err == nil && !info.IsDir(): // Check that it is what we have in the database. curFile, hasCurFile := snap.Get(protocol.LocalDeviceID, file.Name) - if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, scanChan); err != nil { + if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, false, scanChan); err != nil { f.newPullError(file.Name, fmt.Errorf("handling dir: %w", err)) return } @@ -787,7 +787,7 @@ func (f *sendReceiveFolder) handleSymlinkCheckExisting(file protocol.FileInfo, s } // Check that it is what we have in the database. curFile, hasCurFile := snap.Get(protocol.LocalDeviceID, file.Name) - if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, scanChan); err != nil { + if err := f.scanIfItemChanged(file.Name, info, curFile, hasCurFile, false, scanChan); err != nil { return err } // Remove it to replace with the symlink. This also handles the @@ -1629,7 +1629,7 @@ func (f *sendReceiveFolder) performFinish(file, curFile protocol.FileInfo, hasCu // There is an old file or directory already in place. We need to // handle that. - if err := f.scanIfItemChanged(file.Name, stat, curFile, hasCurFile, scanChan); err != nil { + if err := f.scanIfItemChanged(file.Name, stat, curFile, hasCurFile, false, scanChan); err != nil { return fmt.Errorf("checking existing file: %w", err) } @@ -1967,7 +1967,6 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, snap *db.S var dirsToDelete []string var hasIgnored, hasKnown, hasToBeScanned, hasReceiveOnlyChanged bool var delErr error - err := f.mtimefs.Walk(dir, func(path string, info fs.FileInfo, err error) error { if path == dir { return nil @@ -2066,7 +2065,7 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, snap *db.S // scanIfItemChanged schedules the given file for scanning and returns errModified // if it differs from the information in the database. Returns nil if the file has // not changed. -func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, scanChan chan<- string) (err error) { +func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, fromDelete bool, scanChan chan<- string) (err error) { defer func() { if err == errModified { scanChan <- name @@ -2086,14 +2085,13 @@ func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, ite if err != nil { return fmt.Errorf("comparing item on disk to db: %w", err) } - if !statItem.IsEquivalentOptional(item, protocol.FileInfoComparison{ ModTimeWindow: f.modTimeWindow, IgnorePerms: f.IgnorePerms, IgnoreBlocks: true, IgnoreFlags: protocol.LocalAllFlags, - IgnoreOwnership: !f.SyncOwnership, - IgnoreXattrs: !f.SyncXattrs, + IgnoreOwnership: fromDelete || !f.SyncOwnership, + IgnoreXattrs: fromDelete || !f.SyncXattrs, }) { return errModified } @@ -2124,7 +2122,7 @@ func (f *sendReceiveFolder) checkToBeDeleted(file, cur protocol.FileInfo, hasCur return err } - return f.scanIfItemChanged(file.Name, stat, cur, hasCur, scanChan) + return f.scanIfItemChanged(file.Name, stat, cur, hasCur, true, scanChan) } // setPlatformData makes adjustments to the metadata that should happen for