From f66e57947b1a22a4381a5f13fbe2b3bbfe2c50ad Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Sun, 21 Jun 2020 09:28:29 +0200 Subject: [PATCH] lib/model: Use right db snap when scanning recvonly folder (#6769) --- lib/model/folder.go | 59 +++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/model/folder.go b/lib/model/folder.go index a78ac4b8f..1e9d7e150 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -418,38 +418,39 @@ func (f *folder) scanSubdirs(subDirs []string) error { EventLogger: f.evLogger, }) - batchFn := func(fs []protocol.FileInfo) error { + batch := newFileInfoBatch(func(fs []protocol.FileInfo) error { if err := f.getHealthErrorWithoutIgnores(); err != nil { l.Debugf("Stopping scan of folder %s due to: %s", f.Description(), err) return err } f.updateLocalsFromScanning(fs) return nil - } + }) + + var batchAppend func(protocol.FileInfo, *db.Snapshot) // Resolve items which are identical with the global state. - if f.localFlags&protocol.FlagLocalReceiveOnly != 0 { - oldBatchFn := batchFn // can't reference batchFn directly (recursion) - batchFn = func(fs []protocol.FileInfo) error { - for i := range fs { - switch gf, ok := snap.GetGlobal(fs[i].Name); { - case !ok: - continue - case gf.IsEquivalentOptional(fs[i], f.ModTimeWindow(), false, false, protocol.FlagLocalReceiveOnly): - // What we have locally is equivalent to the global file. - fs[i].Version = fs[i].Version.Merge(gf.Version) - fallthrough - case fs[i].IsDeleted() && gf.IsReceiveOnlyChanged(): - // Our item is deleted and the global item is our own - // receive only file. We can't delete file infos, so - // we just pretend it is a normal deleted file (nobody - // cares about that). - fs[i].LocalFlags &^= protocol.FlagLocalReceiveOnly - } + if f.localFlags&protocol.FlagLocalReceiveOnly == 0 { + batchAppend = func(fi protocol.FileInfo, _ *db.Snapshot) { + batch.append(fi) + } + } else { + batchAppend = func(fi protocol.FileInfo, snap *db.Snapshot) { + switch gf, ok := snap.GetGlobal(fi.Name); { + case !ok: + case gf.IsEquivalentOptional(fi, f.ModTimeWindow(), false, false, protocol.FlagLocalReceiveOnly): + // What we have locally is equivalent to the global file. + fi.Version = fi.Version.Merge(gf.Version) + fallthrough + case fi.IsDeleted() && gf.IsReceiveOnlyChanged(): + // Our item is deleted and the global item is our own + // receive only file. We can't delete file infos, so + // we just pretend it is a normal deleted file (nobody + // cares about that). + fi.LocalFlags &^= protocol.FlagLocalReceiveOnly } - return oldBatchFn(fs) + batch.append(fi) } } - batch := newFileInfoBatch(batchFn) // Schedule a pull after scanning, but only if we actually detected any // changes. @@ -472,12 +473,12 @@ func (f *folder) scanSubdirs(subDirs []string) error { return err } - batch.append(res.File) + batchAppend(res.File, snap) changes++ if f.localFlags&protocol.FlagLocalReceiveOnly == 0 { if nf, ok := f.findRename(snap, mtimefs, res.File, alreadyUsed); ok { - batch.append(nf) + batchAppend(nf, snap) changes++ } } @@ -523,7 +524,7 @@ func (f *folder) scanSubdirs(subDirs []string) error { for _, file := range toIgnore { l.Debugln("marking file as ignored", file) nf := file.ConvertToIgnoredFileInfo(f.shortID) - batch.append(nf) + batchAppend(nf, snap) changes++ if err := batch.flushIfFull(); err != nil { iterError = err @@ -550,7 +551,7 @@ func (f *folder) scanSubdirs(subDirs []string) error { l.Debugln("marking file as ignored", file) nf := file.ConvertToIgnoredFileInfo(f.shortID) - batch.append(nf) + batchAppend(nf, snap) changes++ case file.IsIgnored() && !ignored: @@ -579,7 +580,7 @@ func (f *folder) scanSubdirs(subDirs []string) error { nf.Version = protocol.Vector{} } - batch.append(nf) + batchAppend(nf, snap) changes++ } @@ -593,7 +594,7 @@ func (f *folder) scanSubdirs(subDirs []string) error { nf := fi.(db.FileInfoTruncated).ConvertDeletedToFileInfo() nf.LocalFlags = 0 nf.Version = protocol.Vector{} - batch.append(nf) + batchAppend(nf, snap) changes++ return true @@ -609,7 +610,7 @@ func (f *folder) scanSubdirs(subDirs []string) error { for _, file := range toIgnore { l.Debugln("marking file as ignored", f) nf := file.ConvertToIgnoredFileInfo(f.shortID) - batch.append(nf) + batchAppend(nf, snap) changes++ if iterError = batch.flushIfFull(); iterError != nil { break