From ebead944b5d55c1d74fd7e787c047a26e95684eb Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Wed, 22 Jul 2020 22:10:24 +0200 Subject: [PATCH] lib/fs: Pass infinite recursion error on instead of warning (#6846) Prompted by https://forum.syncthing.net/t/infinite-filesystem-recursion-detected/15285. In my opinion the filesystem shouldn't throw warnings but pass on errors for the caller to decide what's to be happening with it. Right now in this PR an infinite recursion is a normal scan error, i.e. folder is in failed state and displays failed items, but no warning. I think that's appropriate but if deemed appropriate an additional warning can be thrown in the scanner. --- lib/fs/walkfs.go | 6 ++++-- lib/fs/walkfs_test.go | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/fs/walkfs.go b/lib/fs/walkfs.go index 6582e1ff0..d883a7e50 100644 --- a/lib/fs/walkfs.go +++ b/lib/fs/walkfs.go @@ -11,9 +11,12 @@ package fs import ( + "errors" "path/filepath" ) +var ErrInfiniteRecursion = errors.New("infinite filesystem recursion detected") + type ancestorDirList struct { list []FileInfo fs Filesystem @@ -90,8 +93,7 @@ func (f *walkFilesystem) walk(path string, info FileInfo, walkFn WalkFunc, ances ancestors.Push(info) defer ancestors.Pop() } else { - l.Warnf("Infinite filesystem recursion detected on path '%s', not walking further down", path) - return nil + return walkFn(path, info, ErrInfiniteRecursion) } names, err := f.DirNames(path) diff --git a/lib/fs/walkfs_test.go b/lib/fs/walkfs_test.go index 7ec0a01c8..934d96c42 100644 --- a/lib/fs/walkfs_test.go +++ b/lib/fs/walkfs_test.go @@ -7,6 +7,7 @@ package fs import ( + "errors" "fmt" osexec "os/exec" "path/filepath" @@ -105,8 +106,16 @@ func testWalkInfiniteRecursion(t *testing.T, fsType FilesystemType, uri string) } dirjunctCnt := 0 fooCnt := 0 + found := false if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error { if err != nil { + if errors.Is(err, ErrInfiniteRecursion) { + if found { + t.Fatal("second infinite recursion detected at", path) + } + found = true + return nil + } t.Fatal(err) } if info.Name() == "dirjunct" { @@ -118,7 +127,7 @@ func testWalkInfiniteRecursion(t *testing.T, fsType FilesystemType, uri string) }); err != nil { t.Fatal(err) } - if dirjunctCnt != 2 || fooCnt != 1 { + if dirjunctCnt != 2 || fooCnt != 1 || !found { t.Fatal("Infinite recursion not detected correctly") } }