فهرست منبع

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.
Simon Frei 5 سال پیش
والد
کامیت
ebead944b5
2فایلهای تغییر یافته به همراه14 افزوده شده و 3 حذف شده
  1. 4 2
      lib/fs/walkfs.go
  2. 10 1
      lib/fs/walkfs_test.go

+ 4 - 2
lib/fs/walkfs.go

@@ -11,9 +11,12 @@
 package fs
 package fs
 
 
 import (
 import (
+	"errors"
 	"path/filepath"
 	"path/filepath"
 )
 )
 
 
+var ErrInfiniteRecursion = errors.New("infinite filesystem recursion detected")
+
 type ancestorDirList struct {
 type ancestorDirList struct {
 	list []FileInfo
 	list []FileInfo
 	fs   Filesystem
 	fs   Filesystem
@@ -90,8 +93,7 @@ func (f *walkFilesystem) walk(path string, info FileInfo, walkFn WalkFunc, ances
 		ancestors.Push(info)
 		ancestors.Push(info)
 		defer ancestors.Pop()
 		defer ancestors.Pop()
 	} else {
 	} 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)
 	names, err := f.DirNames(path)

+ 10 - 1
lib/fs/walkfs_test.go

@@ -7,6 +7,7 @@
 package fs
 package fs
 
 
 import (
 import (
+	"errors"
 	"fmt"
 	"fmt"
 	osexec "os/exec"
 	osexec "os/exec"
 	"path/filepath"
 	"path/filepath"
@@ -105,8 +106,16 @@ func testWalkInfiniteRecursion(t *testing.T, fsType FilesystemType, uri string)
 	}
 	}
 	dirjunctCnt := 0
 	dirjunctCnt := 0
 	fooCnt := 0
 	fooCnt := 0
+	found := false
 	if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
 	if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
 		if err != nil {
 		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)
 			t.Fatal(err)
 		}
 		}
 		if info.Name() == "dirjunct" {
 		if info.Name() == "dirjunct" {
@@ -118,7 +127,7 @@ func testWalkInfiniteRecursion(t *testing.T, fsType FilesystemType, uri string)
 	}); err != nil {
 	}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if dirjunctCnt != 2 || fooCnt != 1 {
+	if dirjunctCnt != 2 || fooCnt != 1 || !found {
 		t.Fatal("Infinite recursion not detected correctly")
 		t.Fatal("Infinite recursion not detected correctly")
 	}
 	}
 }
 }