mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-08 17:24:08 +00:00
Reimplement quick startup scan
This commit is contained in:
parent
d2d32f26c7
commit
2df78a9313
@ -239,8 +239,9 @@ func main() {
|
|||||||
IgnoreFile: ".stignore",
|
IgnoreFile: ".stignore",
|
||||||
FollowSymlinks: cfg.Options.FollowSymlinks,
|
FollowSymlinks: cfg.Options.FollowSymlinks,
|
||||||
BlockSize: BlockSize,
|
BlockSize: BlockSize,
|
||||||
Suppressor: sup,
|
|
||||||
TempNamer: defTempNamer,
|
TempNamer: defTempNamer,
|
||||||
|
Suppressor: sup,
|
||||||
|
CurrentFiler: m,
|
||||||
}
|
}
|
||||||
updateLocalModel(m, w)
|
updateLocalModel(m, w)
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ func (m *Model) Request(nodeID, repo, name string, offset int64, size int) ([]by
|
|||||||
warnf("SECURITY (nonexistent file) REQ(in): %s: %q o=%d s=%d", nodeID, name, offset, size)
|
warnf("SECURITY (nonexistent file) REQ(in): %s: %q o=%d s=%d", nodeID, name, offset, size)
|
||||||
return nil, ErrNoSuchFile
|
return nil, ErrNoSuchFile
|
||||||
}
|
}
|
||||||
if lf.Flags&protocol.FlagInvalid != 0 {
|
if lf.Suppressed {
|
||||||
return nil, ErrInvalid
|
return nil, ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,6 +480,14 @@ func (m *Model) SeedLocal(fs []protocol.FileInfo) {
|
|||||||
m.recomputeNeedForGlobal()
|
m.recomputeNeedForGlobal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements scanner.CurrentFiler
|
||||||
|
func (m *Model) CurrentFile(file string) scanner.File {
|
||||||
|
m.lmut.RLock()
|
||||||
|
f := m.local[file]
|
||||||
|
m.lmut.RUnlock()
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
// ConnectedTo returns true if we are connected to the named node.
|
// ConnectedTo returns true if we are connected to the named node.
|
||||||
func (m *Model) ConnectedTo(nodeID string) bool {
|
func (m *Model) ConnectedTo(nodeID string) bool {
|
||||||
m.pmut.RLock()
|
m.pmut.RLock()
|
||||||
@ -810,7 +818,7 @@ func (m *Model) recomputeNeedForFile(gf scanner.File, toAdd []addOrder, toDelete
|
|||||||
m.lmut.RUnlock()
|
m.lmut.RUnlock()
|
||||||
|
|
||||||
if !ok || gf.NewerThan(lf) {
|
if !ok || gf.NewerThan(lf) {
|
||||||
if gf.Flags&protocol.FlagInvalid != 0 {
|
if gf.Suppressed {
|
||||||
// Never attempt to sync invalid files
|
// Never attempt to sync invalid files
|
||||||
return toAdd, toDelete
|
return toAdd, toDelete
|
||||||
}
|
}
|
||||||
@ -891,10 +899,11 @@ func fileFromFileInfo(f protocol.FileInfo) scanner.File {
|
|||||||
return scanner.File{
|
return scanner.File{
|
||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Size: offset,
|
Size: offset,
|
||||||
Flags: f.Flags,
|
Flags: f.Flags &^ protocol.FlagInvalid,
|
||||||
Modified: f.Modified,
|
Modified: f.Modified,
|
||||||
Version: f.Version,
|
Version: f.Version,
|
||||||
Blocks: blocks,
|
Blocks: blocks,
|
||||||
|
Suppressed: f.Flags&protocol.FlagInvalid != 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,11 +915,15 @@ func fileInfoFromFile(f scanner.File) protocol.FileInfo {
|
|||||||
Hash: b.Hash,
|
Hash: b.Hash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return protocol.FileInfo{
|
pf := protocol.FileInfo{
|
||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Flags: f.Flags,
|
Flags: f.Flags,
|
||||||
Modified: f.Modified,
|
Modified: f.Modified,
|
||||||
Version: f.Version,
|
Version: f.Version,
|
||||||
Blocks: blocks,
|
Blocks: blocks,
|
||||||
}
|
}
|
||||||
|
if f.Suppressed {
|
||||||
|
pf.Flags |= protocol.FlagInvalid
|
||||||
|
}
|
||||||
|
return pf
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FlagDeleted = 1 << 12
|
FlagDeleted uint32 = 1 << 12
|
||||||
FlagInvalid = 1 << 13
|
FlagInvalid = 1 << 13
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ type File struct {
|
|||||||
Version uint32
|
Version uint32
|
||||||
Size int64
|
Size int64
|
||||||
Blocks []Block
|
Blocks []Block
|
||||||
|
Suppressed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f File) String() string {
|
func (f File) String() string {
|
||||||
|
@ -9,8 +9,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/calmh/syncthing/protocol"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Walker struct {
|
type Walker struct {
|
||||||
@ -25,10 +23,13 @@ type Walker struct {
|
|||||||
IgnoreFile string
|
IgnoreFile string
|
||||||
// If TempNamer is not nil, it is used to ignore tempory files when walking.
|
// If TempNamer is not nil, it is used to ignore tempory files when walking.
|
||||||
TempNamer TempNamer
|
TempNamer TempNamer
|
||||||
|
// If CurrentFiler is not nil, it is queried for the current file before rescanning.
|
||||||
|
CurrentFiler CurrentFiler
|
||||||
// If Suppressor is not nil, it is queried for supression of modified files.
|
// If Suppressor is not nil, it is queried for supression of modified files.
|
||||||
|
// Suppressed files will be returned with empty metadata and the Suppressed flag set.
|
||||||
|
// Requires CurrentFiler to be set.
|
||||||
Suppressor Suppressor
|
Suppressor Suppressor
|
||||||
|
|
||||||
previous map[string]File // file name -> last seen file state
|
|
||||||
suppressed map[string]bool // file name -> suppression status
|
suppressed map[string]bool // file name -> suppression status
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +45,11 @@ type Suppressor interface {
|
|||||||
Suppress(name string, fi os.FileInfo) bool
|
Suppress(name string, fi os.FileInfo) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CurrentFiler interface {
|
||||||
|
// CurrentFile returns the file as seen at last scan.
|
||||||
|
CurrentFile(name string) File
|
||||||
|
}
|
||||||
|
|
||||||
// Walk returns the list of files found in the local repository by scanning the
|
// Walk returns the list of files found in the local repository by scanning the
|
||||||
// file system. Files are blockwise hashed.
|
// file system. Files are blockwise hashed.
|
||||||
func (w *Walker) Walk() (files []File, ignore map[string][]string) {
|
func (w *Walker) Walk() (files []File, ignore map[string][]string) {
|
||||||
@ -95,8 +101,7 @@ func (w *Walker) CleanTempFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Walker) lazyInit() {
|
func (w *Walker) lazyInit() {
|
||||||
if w.previous == nil {
|
if w.suppressed == nil {
|
||||||
w.previous = make(map[string]File)
|
|
||||||
w.suppressed = make(map[string]bool)
|
w.suppressed = make(map[string]bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,21 +176,13 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath
|
|||||||
}
|
}
|
||||||
|
|
||||||
if info.Mode()&os.ModeType == 0 {
|
if info.Mode()&os.ModeType == 0 {
|
||||||
modified := info.ModTime().Unix()
|
if w.CurrentFiler != nil {
|
||||||
pf := w.previous[rn]
|
cf := w.CurrentFiler.CurrentFile(rn)
|
||||||
|
if cf.Modified == info.ModTime().Unix() {
|
||||||
if pf.Modified == modified {
|
|
||||||
if nf := uint32(info.Mode()); nf != pf.Flags {
|
|
||||||
if debug {
|
if debug {
|
||||||
dlog.Println("new flags:", rn)
|
|
||||||
}
|
|
||||||
pf.Flags = nf
|
|
||||||
pf.Version++
|
|
||||||
w.previous[rn] = pf
|
|
||||||
} else if debug {
|
|
||||||
dlog.Println("unchanged:", rn)
|
dlog.Println("unchanged:", rn)
|
||||||
}
|
}
|
||||||
*res = append(*res, pf)
|
*res = append(*res, cf)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,15 +194,13 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath
|
|||||||
w.suppressed[rn] = true
|
w.suppressed[rn] = true
|
||||||
log.Printf("INFO: Changes to %q are being temporarily suppressed because it changes too frequently.", p)
|
log.Printf("INFO: Changes to %q are being temporarily suppressed because it changes too frequently.", p)
|
||||||
}
|
}
|
||||||
f := pf
|
cf.Suppressed = true
|
||||||
f.Flags = protocol.FlagInvalid
|
*res = append(*res, cf)
|
||||||
f.Blocks = nil
|
|
||||||
*res = append(*res, f)
|
|
||||||
return nil
|
|
||||||
} else if w.suppressed[rn] {
|
} else if w.suppressed[rn] {
|
||||||
log.Printf("INFO: Changes to %q are no longer suppressed.", p)
|
log.Printf("INFO: Changes to %q are no longer suppressed.", p)
|
||||||
delete(w.suppressed, rn)
|
delete(w.suppressed, rn)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fd, err := os.Open(p)
|
fd, err := os.Open(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -232,10 +227,9 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath
|
|||||||
Name: rn,
|
Name: rn,
|
||||||
Size: info.Size(),
|
Size: info.Size(),
|
||||||
Flags: uint32(info.Mode()),
|
Flags: uint32(info.Mode()),
|
||||||
Modified: modified,
|
Modified: info.ModTime().Unix(),
|
||||||
Blocks: blocks,
|
Blocks: blocks,
|
||||||
}
|
}
|
||||||
w.previous[rn] = f
|
|
||||||
*res = append(*res, f)
|
*res = append(*res, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user