mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-31 22:11:51 +00:00
lib/model: Properly handle deleting multiple files when doing scans with subs (fixes #2851)
This commit is contained in:
parent
7a81c27cc6
commit
8fea354b74
@ -236,14 +236,11 @@ func (db *Instance) updateFiles(folder, device []byte, fs []protocol.FileInfo, l
|
||||
return maxLocalVer
|
||||
}
|
||||
|
||||
func (db *Instance) withHave(folder, device []byte, truncate bool, fn Iterator) {
|
||||
start := db.deviceKey(folder, device, nil) // before all folder/device files
|
||||
limit := db.deviceKey(folder, device, []byte{0xff, 0xff, 0xff, 0xff}) // after all folder/device files
|
||||
|
||||
func (db *Instance) withHave(folder, device, prefix []byte, truncate bool, fn Iterator) {
|
||||
t := db.newReadOnlyTransaction()
|
||||
defer t.close()
|
||||
|
||||
dbi := t.NewIterator(&util.Range{Start: start, Limit: limit}, nil)
|
||||
dbi := t.NewIterator(util.BytesPrefix(db.deviceKey(folder, device, prefix)[:1+64+32+len(prefix)]), nil)
|
||||
defer dbi.Release()
|
||||
|
||||
for dbi.Next() {
|
||||
|
@ -171,14 +171,18 @@ func (s *FileSet) WithNeedTruncated(device protocol.DeviceID, fn Iterator) {
|
||||
|
||||
func (s *FileSet) WithHave(device protocol.DeviceID, fn Iterator) {
|
||||
l.Debugf("%s WithHave(%v)", s.folder, device)
|
||||
s.db.withHave([]byte(s.folder), device[:], false, nativeFileIterator(fn))
|
||||
s.db.withHave([]byte(s.folder), device[:], nil, false, nativeFileIterator(fn))
|
||||
}
|
||||
|
||||
func (s *FileSet) WithHaveTruncated(device protocol.DeviceID, fn Iterator) {
|
||||
l.Debugf("%s WithHaveTruncated(%v)", s.folder, device)
|
||||
s.db.withHave([]byte(s.folder), device[:], true, nativeFileIterator(fn))
|
||||
s.db.withHave([]byte(s.folder), device[:], nil, true, nativeFileIterator(fn))
|
||||
}
|
||||
|
||||
func (s *FileSet) WithPrefixedHaveTruncated(device protocol.DeviceID, prefix string, fn Iterator) {
|
||||
l.Debugf("%s WithPrefixedHaveTruncated(%v)", s.folder, device)
|
||||
s.db.withHave([]byte(s.folder), device[:], []byte(prefix), true, nativeFileIterator(fn))
|
||||
}
|
||||
func (s *FileSet) WithGlobal(fn Iterator) {
|
||||
l.Debugf("%s WithGlobal()", s.folder)
|
||||
s.db.withGlobal([]byte(s.folder), nil, false, nativeFileIterator(fn))
|
||||
|
@ -1391,27 +1391,19 @@ func (m *Model) internalScanFolderSubs(folder string, subs []string) error {
|
||||
m.updateLocals(folder, batch)
|
||||
}
|
||||
|
||||
batch = batch[:0]
|
||||
// TODO: We should limit the Have scanning to start at sub
|
||||
seenPrefix := false
|
||||
var iterError error
|
||||
fs.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
||||
f := fi.(db.FileInfoTruncated)
|
||||
hasPrefix := len(subs) == 0
|
||||
for _, sub := range subs {
|
||||
if strings.HasPrefix(f.Name, sub) {
|
||||
hasPrefix = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// Return true so that we keep iterating, until we get to the part
|
||||
// of the tree we are interested in. Then return false so we stop
|
||||
// iterating when we've passed the end of the subtree.
|
||||
if !hasPrefix {
|
||||
return !seenPrefix
|
||||
if len(subs) == 0 {
|
||||
// If we have no specific subdirectories to traverse, set it to one
|
||||
// empty prefix so we traverse the entire folder contents once.
|
||||
subs = []string{""}
|
||||
}
|
||||
|
||||
seenPrefix = true
|
||||
// Do a scan of the database for each prefix, to check for deleted files.
|
||||
batch = batch[:0]
|
||||
for _, sub := range subs {
|
||||
var iterError error
|
||||
|
||||
fs.WithPrefixedHaveTruncated(protocol.LocalDeviceID, sub, func(fi db.FileIntf) bool {
|
||||
f := fi.(db.FileInfoTruncated)
|
||||
if !f.IsDeleted() {
|
||||
if f.IsInvalid() {
|
||||
return true
|
||||
@ -1462,6 +1454,7 @@ func (m *Model) internalScanFolderSubs(folder string, subs []string) error {
|
||||
l.Infof("Stopping folder %s mid-scan due to folder error: %s", folder, iterError)
|
||||
return iterError
|
||||
}
|
||||
}
|
||||
|
||||
if err := m.CheckFolderHealth(folder); err != nil {
|
||||
l.Infof("Stopping folder %s mid-scan due to folder error: %s", folder, err)
|
||||
|
Loading…
Reference in New Issue
Block a user