diff --git a/lib/fs/basicfs_test.go b/lib/fs/basicfs_test.go index 65f2d0c5b..0fe754c36 100644 --- a/lib/fs/basicfs_test.go +++ b/lib/fs/basicfs_test.go @@ -7,14 +7,12 @@ package fs import ( - "errors" "io/ioutil" "os" "path/filepath" "runtime" "sort" "strings" - "syscall" "testing" "time" ) @@ -483,23 +481,3 @@ func TestRooted(t *testing.T) { } } } - -func TestWatchErrorLinuxInterpretation(t *testing.T) { - if runtime.GOOS != "linux" { - t.Skip("testing of linux specific error codes") - } - - var errTooManyFiles syscall.Errno = 24 - var errNoSpace syscall.Errno = 28 - - if !reachedMaxUserWatches(errTooManyFiles) { - t.Errorf("Errno %v should be recognised to be about inotify limits.", errTooManyFiles) - } - if !reachedMaxUserWatches(errNoSpace) { - t.Errorf("Errno %v should be recognised to be about inotify limits.", errNoSpace) - } - err := errors.New("Another error") - if reachedMaxUserWatches(err) { - t.Errorf("This error does not concern inotify limits: %#v", err) - } -} diff --git a/lib/fs/basicfs_watch.go b/lib/fs/basicfs_watch.go index ff924dc26..a28d18842 100644 --- a/lib/fs/basicfs_watch.go +++ b/lib/fs/basicfs_watch.go @@ -42,7 +42,7 @@ func (f *BasicFilesystem) Watch(name string, ignore Matcher, ctx context.Context if err := notify.WatchWithFilter(filepath.Join(absName, "..."), backendChan, absShouldIgnore, eventMask); err != nil { notify.Stop(backendChan) if reachedMaxUserWatches(err) { - err = errors.New("failed to install inotify handler. Please increase inotify limits, see https://github.com/syncthing/syncthing-inotify#troubleshooting-for-folders-with-many-files-on-linux for more information") + err = errors.New("failed to setup inotify handler. Please increase inotify limits, see https://docs.syncthing.net/users/faq.html#inotify-limits") } return nil, err } diff --git a/lib/fs/basicfs_watch_errors_linux.go b/lib/fs/basicfs_watch_errors_linux.go index d61587a79..b8f838661 100644 --- a/lib/fs/basicfs_watch_errors_linux.go +++ b/lib/fs/basicfs_watch_errors_linux.go @@ -8,11 +8,16 @@ package fs -import "syscall" +import ( + "os" + "syscall" +) func reachedMaxUserWatches(err error) bool { - if errno, ok := err.(syscall.Errno); ok { - return errno == 24 || errno == 28 + if pathErr, ok := err.(*os.PathError); ok { + if errno, ok := pathErr.Err.(syscall.Errno); ok { + return errno == 24 || errno == 28 + } } return false } diff --git a/lib/fs/basicfs_watch_test.go b/lib/fs/basicfs_watch_test.go index 969ac0094..5ff83ac90 100644 --- a/lib/fs/basicfs_watch_test.go +++ b/lib/fs/basicfs_watch_test.go @@ -10,11 +10,13 @@ package fs import ( "context" + "errors" "fmt" "os" "path/filepath" "runtime" "strconv" + "syscall" "testing" "time" @@ -178,6 +180,34 @@ func TestWatchOverflow(t *testing.T) { testScenario(t, name, testCase, expectedEvents, allowedEvents, "") } +func TestWatchErrorLinuxInterpretation(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skip("testing of linux specific error codes") + } + + var errTooManyFiles = &os.PathError{ + Op: "error while traversing", + Path: "foo", + Err: syscall.Errno(24), + } + var errNoSpace = &os.PathError{ + Op: "error while traversing", + Path: "bar", + Err: syscall.Errno(28), + } + + if !reachedMaxUserWatches(errTooManyFiles) { + t.Error("Underlying error syscall.Errno(24) should be recognised to be about inotify limits.") + } + if !reachedMaxUserWatches(errNoSpace) { + t.Error("Underlying error syscall.Errno(28) should be recognised to be about inotify limits.") + } + err := errors.New("Another error") + if reachedMaxUserWatches(err) { + t.Errorf("This error does not concern inotify limits: %#v", err) + } +} + // path relative to folder root, also creates parent dirs if necessary func createTestFile(name string, file string) string { joined := filepath.Join(name, file)