From 0b65a616ba760437340386ad0c8fec39b4be5924 Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Mon, 8 Jun 2020 08:14:50 +0200 Subject: [PATCH] lib/scanner: Save one stat call per file (#6715) --- lib/scanner/walk.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 35d910dda..39114ac4f 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -265,7 +265,7 @@ func (w *walker) walkAndHashFiles(ctx context.Context, toHashChan chan<- protoco if ignoredParent == "" { // parent isn't ignored, nothing special - return w.handleItem(ctx, path, toHashChan, finishedChan, skip) + return w.handleItem(ctx, path, info, toHashChan, finishedChan, skip) } // Part of current path below the ignored (potential) parent @@ -274,17 +274,22 @@ func (w *walker) walkAndHashFiles(ctx context.Context, toHashChan chan<- protoco // ignored path isn't actually a parent of the current path if rel == path { ignoredParent = "" - return w.handleItem(ctx, path, toHashChan, finishedChan, skip) + return w.handleItem(ctx, path, info, toHashChan, finishedChan, skip) } // The previously ignored parent directories of the current, not // ignored path need to be handled as well. - if err = w.handleItem(ctx, ignoredParent, toHashChan, finishedChan, skip); err != nil { - return err - } - for _, name := range strings.Split(rel, string(fs.PathSeparator)) { + // Prepend an empty string to handle ignoredParent without anything + // appended in the first iteration. + for _, name := range append([]string{""}, strings.Split(rel, string(fs.PathSeparator))...) { ignoredParent = filepath.Join(ignoredParent, name) - if err = w.handleItem(ctx, ignoredParent, toHashChan, finishedChan, skip); err != nil { + info, err = w.Filesystem.Lstat(ignoredParent) + // An error here would be weird as we've already gotten to this point, but act on it nonetheless + if err != nil { + w.handleError(ctx, "scan", ignoredParent, err, finishedChan) + return skip + } + if err = w.handleItem(ctx, ignoredParent, info, toHashChan, finishedChan, skip); err != nil { return err } } @@ -294,16 +299,9 @@ func (w *walker) walkAndHashFiles(ctx context.Context, toHashChan chan<- protoco } } -func (w *walker) handleItem(ctx context.Context, path string, toHashChan chan<- protocol.FileInfo, finishedChan chan<- ScanResult, skip error) error { - info, err := w.Filesystem.Lstat(path) - // An error here would be weird as we've already gotten to this point, but act on it nonetheless - if err != nil { - w.handleError(ctx, "scan", path, err, finishedChan) - return skip - } - +func (w *walker) handleItem(ctx context.Context, path string, info fs.FileInfo, toHashChan chan<- protocol.FileInfo, finishedChan chan<- ScanResult, skip error) error { oldPath := path - path, err = w.normalizePath(path, info) + path, err := w.normalizePath(path, info) if err != nil { w.handleError(ctx, "normalizing path", oldPath, err, finishedChan) return skip