mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 18:41:59 -07:00
Potential race between folder being added and scan (potentially fixes #1986)
This commit is contained in:
parent
986f8dfb2e
commit
31cd0b943c
@ -428,7 +428,10 @@ func folderSummary(m *model.Model, folder string) map[string]interface{} {
|
|||||||
res["error"] = err.Error()
|
res["error"] = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
res["version"] = m.CurrentLocalVersion(folder) + m.RemoteLocalVersion(folder)
|
lv, _ := m.CurrentLocalVersion(folder)
|
||||||
|
rv, _ := m.RemoteLocalVersion(folder)
|
||||||
|
|
||||||
|
res["version"] = lv + rv
|
||||||
|
|
||||||
ignorePatterns, _, _ := m.GetIgnores(folder)
|
ignorePatterns, _, _ := m.GetIgnores(folder)
|
||||||
res["ignorePatterns"] = false
|
res["ignorePatterns"] = false
|
||||||
|
@ -1554,23 +1554,23 @@ func (m *Model) Override(folder string) {
|
|||||||
// CurrentLocalVersion returns the change version for the given folder.
|
// CurrentLocalVersion returns the change version for the given folder.
|
||||||
// This is guaranteed to increment if the contents of the local folder has
|
// This is guaranteed to increment if the contents of the local folder has
|
||||||
// changed.
|
// changed.
|
||||||
func (m *Model) CurrentLocalVersion(folder string) int64 {
|
func (m *Model) CurrentLocalVersion(folder string) (int64, bool) {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
fs, ok := m.folderFiles[folder]
|
fs, ok := m.folderFiles[folder]
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
// The folder might not exist, since this can be called with a user
|
// The folder might not exist, since this can be called with a user
|
||||||
// specified folder name from the REST interface.
|
// specified folder name from the REST interface.
|
||||||
return 0
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.LocalVersion(protocol.LocalDeviceID)
|
return fs.LocalVersion(protocol.LocalDeviceID), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteLocalVersion returns the change version for the given folder, as
|
// RemoteLocalVersion returns the change version for the given folder, as
|
||||||
// sent by remote peers. This is guaranteed to increment if the contents of
|
// sent by remote peers. This is guaranteed to increment if the contents of
|
||||||
// the remote or global folder has changed.
|
// the remote or global folder has changed.
|
||||||
func (m *Model) RemoteLocalVersion(folder string) int64 {
|
func (m *Model) RemoteLocalVersion(folder string) (int64, bool) {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
defer m.fmut.RUnlock()
|
defer m.fmut.RUnlock()
|
||||||
|
|
||||||
@ -1578,7 +1578,7 @@ func (m *Model) RemoteLocalVersion(folder string) int64 {
|
|||||||
if !ok {
|
if !ok {
|
||||||
// The folder might not exist, since this can be called with a user
|
// The folder might not exist, since this can be called with a user
|
||||||
// specified folder name from the REST interface.
|
// specified folder name from the REST interface.
|
||||||
return 0
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
var ver int64
|
var ver int64
|
||||||
@ -1586,7 +1586,7 @@ func (m *Model) RemoteLocalVersion(folder string) int64 {
|
|||||||
ver += fs.LocalVersion(n)
|
ver += fs.LocalVersion(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ver
|
return ver, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) GlobalDirectoryTree(folder, prefix string, levels int, dirsonly bool) map[string]interface{} {
|
func (m *Model) GlobalDirectoryTree(folder, prefix string, levels int, dirsonly bool) map[string]interface{} {
|
||||||
@ -1695,7 +1695,7 @@ func (m *Model) CheckFolderHealth(id string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fi, err := os.Stat(folder.Path())
|
fi, err := os.Stat(folder.Path())
|
||||||
if m.CurrentLocalVersion(id) > 0 {
|
if v, ok := m.CurrentLocalVersion(id); ok && v > 0 {
|
||||||
// Safety check. If the cached index contains files but the
|
// Safety check. If the cached index contains files but the
|
||||||
// folder doesn't exist, we have a problem. We would assume
|
// folder doesn't exist, we have a problem. We would assume
|
||||||
// that all files have been deleted which might not be the case,
|
// that all files have been deleted which might not be the case,
|
||||||
|
@ -204,10 +204,10 @@ func (p *rwFolder) Serve() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoteLocalVersion() is a fast call, doesn't touch the database.
|
// RemoteLocalVersion() is a fast call, doesn't touch the database.
|
||||||
curVer := p.model.RemoteLocalVersion(p.folder)
|
curVer, ok := p.model.RemoteLocalVersion(p.folder)
|
||||||
if curVer == prevVer {
|
if !ok || curVer == prevVer {
|
||||||
if debug {
|
if debug {
|
||||||
l.Debugln(p, "skip (curVer == prevVer)", prevVer)
|
l.Debugln(p, "skip (curVer == prevVer)", prevVer, ok)
|
||||||
}
|
}
|
||||||
p.pullTimer.Reset(nextPullIntv)
|
p.pullTimer.Reset(nextPullIntv)
|
||||||
continue
|
continue
|
||||||
@ -231,7 +231,7 @@ func (p *rwFolder) Serve() {
|
|||||||
// sync. Remember the local version number and
|
// sync. Remember the local version number and
|
||||||
// schedule a resync a little bit into the future.
|
// schedule a resync a little bit into the future.
|
||||||
|
|
||||||
if lv := p.model.RemoteLocalVersion(p.folder); lv < curVer {
|
if lv, ok := p.model.RemoteLocalVersion(p.folder); ok && lv < curVer {
|
||||||
// There's a corner case where the device we needed
|
// There's a corner case where the device we needed
|
||||||
// files from disconnected during the puller
|
// files from disconnected during the puller
|
||||||
// iteration. The files will have been removed from
|
// iteration. The files will have been removed from
|
||||||
|
Loading…
Reference in New Issue
Block a user