Add linientMtimes workaround for Android brokenness (ref #831)

This commit is contained in:
Jakob Borg 2014-10-14 08:48:35 +02:00
parent 870e3a45ef
commit 5f52e0581d
3 changed files with 40 additions and 17 deletions

View File

@ -57,6 +57,7 @@ type FolderConfiguration struct {
RescanIntervalS int `xml:"rescanIntervalS,attr" default:"60"`
IgnorePerms bool `xml:"ignorePerms,attr"`
Versioning VersioningConfiguration `xml:"versioning"`
LenientMtimes bool `xml:"lenientMtimes"`
Invalid string `xml:"-"` // Set at runtime when there is an error, not saved

View File

@ -167,11 +167,12 @@ func (m *Model) StartFolderRW(folder string) {
panic("cannot start already running folder " + folder)
}
p := &Puller{
folder: folder,
dir: cfg.Path,
scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second,
model: m,
ignorePerms: cfg.IgnorePerms,
folder: folder,
dir: cfg.Path,
scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second,
model: m,
ignorePerms: cfg.IgnorePerms,
lenientMtimes: cfg.LenientMtimes,
}
m.folderRunners[folder] = p
m.fmut.Unlock()
@ -184,6 +185,10 @@ func (m *Model) StartFolderRW(folder string) {
p.versioner = factory(folder, cfg.Path, cfg.Versioning.Params)
}
if cfg.LenientMtimes {
l.Infof("Folder %q is running with LenientMtimes workaround. Syncing may not work properly.", folder)
}
go p.Serve()
}

View File

@ -62,13 +62,14 @@ var (
)
type Puller struct {
folder string
dir string
scanIntv time.Duration
model *Model
stop chan struct{}
versioner versioner.Versioner
ignorePerms bool
folder string
dir string
scanIntv time.Duration
model *Model
stop chan struct{}
versioner versioner.Versioner
ignorePerms bool
lenientMtimes bool
}
// Serve will run scans and pulls. It will return when Stop()ed or on a
@ -528,8 +529,16 @@ func (p *Puller) shortcutFile(file protocol.FileInfo) {
t := time.Unix(file.Modified, 0)
err := os.Chtimes(realName, t, t)
if err != nil {
l.Infof("Puller (folder %q, file %q): shortcut: %v", p.folder, file.Name, err)
return
if p.lenientMtimes {
// We accept the failure with a warning here and allow the sync to
// continue. We'll sync the new mtime back to the other devices later.
// If they have the same problem & setting, we might never get in
// sync.
l.Infof("Puller (folder %q, file %q): shortcut: %v (continuing anyway as requested)", p.folder, file.Name, err)
} else {
l.Infof("Puller (folder %q, file %q): shortcut: %v", p.folder, file.Name, err)
return
}
}
p.model.updateLocal(p.folder, file)
@ -666,9 +675,17 @@ func (p *Puller) finisherRoutine(in <-chan *sharedPullerState) {
t := time.Unix(state.file.Modified, 0)
err = os.Chtimes(state.tempName, t, t)
if err != nil {
os.Remove(state.tempName)
l.Warnln("puller: final:", err)
continue
if p.lenientMtimes {
// We accept the failure with a warning here and allow the sync to
// continue. We'll sync the new mtime back to the other devices later.
// If they have the same problem & setting, we might never get in
// sync.
l.Infof("Puller (folder %q, file %q): final: %v (continuing anyway as requested)", p.folder, state.file.Name, err)
} else {
os.Remove(state.tempName)
l.Warnln("puller: final:", err)
continue
}
}
// If we should use versioning, let the versioner archive the old