diff --git a/lib/fs/basicfs.go b/lib/fs/basicfs.go index 098769870..4ed60d10e 100644 --- a/lib/fs/basicfs.go +++ b/lib/fs/basicfs.go @@ -379,12 +379,12 @@ func longFilenameSupport(path string) string { return path } -type ErrWatchEventOutsideRoot struct{ msg string } +type WatchEventOutsideRootError struct{ msg string } -func (e *ErrWatchEventOutsideRoot) Error() string { +func (e *WatchEventOutsideRootError) Error() string { return e.msg } -func (f *BasicFilesystem) newErrWatchEventOutsideRoot(absPath string, roots []string) *ErrWatchEventOutsideRoot { - return &ErrWatchEventOutsideRoot{fmt.Sprintf("Watching for changes encountered an event outside of the filesystem root: f.root==%v, roots==%v, path==%v. This should never happen, please report this message to forum.syncthing.net.", f.root, roots, absPath)} +func (f *BasicFilesystem) newErrWatchEventOutsideRoot(absPath string, roots []string) *WatchEventOutsideRootError { + return &WatchEventOutsideRootError{fmt.Sprintf("Watching for changes encountered an event outside of the filesystem root: f.root==%v, roots==%v, path==%v. This should never happen, please report this message to forum.syncthing.net.", f.root, roots, absPath)} } diff --git a/lib/fs/basicfs_fileinfo_bsdish.go b/lib/fs/basicfs_fileinfo_bsdish.go index b8e60f329..10061ebfb 100644 --- a/lib/fs/basicfs_fileinfo_bsdish.go +++ b/lib/fs/basicfs_fileinfo_bsdish.go @@ -15,7 +15,7 @@ import ( ) func (fi basicFileInfo) InodeChangeTime() time.Time { - if sys, ok := fi.FileInfo.Sys().(*syscall.Stat_t); ok { + if sys, ok := fi.Sys().(*syscall.Stat_t); ok { return time.Unix(0, sys.Ctimespec.Nano()) } return time.Time{} diff --git a/lib/fs/basicfs_unix.go b/lib/fs/basicfs_unix.go index e1b3967eb..1a54b2652 100644 --- a/lib/fs/basicfs_unix.go +++ b/lib/fs/basicfs_unix.go @@ -86,7 +86,7 @@ func (f *BasicFilesystem) Remove(name string) error { // unrooted) or an error if the given path is not a subpath and handles the // special case when the given path is the folder root without a trailing // pathseparator. -func (f *BasicFilesystem) unrootedChecked(absPath string, roots []string) (string, *ErrWatchEventOutsideRoot) { +func (f *BasicFilesystem) unrootedChecked(absPath string, roots []string) (string, *WatchEventOutsideRootError) { for _, root := range roots { // Make sure the root ends with precisely one path separator, to // ease prefix comparisons. diff --git a/lib/fs/basicfs_xattr_unix.go b/lib/fs/basicfs_xattr_unix.go index f43445c87..f32929708 100644 --- a/lib/fs/basicfs_xattr_unix.go +++ b/lib/fs/basicfs_xattr_unix.go @@ -69,7 +69,7 @@ var xattrBufPool = sync.Pool{ } func getXattr(path, name string) ([]byte, error) { - buf := xattrBufPool.Get().([]byte) + buf := xattrBufPool.Get().([]byte) //nolint:forcetypeassert defer func() { // Put the buffer back in the pool, or not if we're not supposed to // (we returned it to the caller). diff --git a/lib/fs/casefs.go b/lib/fs/casefs.go index d88ccc0a4..bf8ecb63b 100644 --- a/lib/fs/casefs.go +++ b/lib/fs/casefs.go @@ -24,16 +24,16 @@ const ( caseCacheItemLimit = 4 << 10 ) -type ErrCaseConflict struct { +type CaseConflictError struct { Given, Real string } -func (e *ErrCaseConflict) Error() string { +func (e *CaseConflictError) Error() string { return fmt.Sprintf(`remote "%v" uses different upper or lowercase characters than local "%v"; change the casing on either side to match the other`, e.Given, e.Real) } func IsErrCaseConflict(err error) bool { - e := &ErrCaseConflict{} + e := &CaseConflictError{} return errors.As(err, &e) } @@ -239,7 +239,7 @@ func (f *caseFilesystem) Rename(oldpath, newpath string) error { } if err := f.checkCase(newpath); err != nil { // Case-only rename is ok - e := &ErrCaseConflict{} + e := &CaseConflictError{} if !errors.As(err, &e) || e.Real != oldpath { return err } @@ -389,7 +389,7 @@ func (f *caseFilesystem) checkCaseExisting(name string) error { // comparing, as we don't want to treat a normalization difference as a // case conflict. if norm.NFC.String(realName) != norm.NFC.String(name) { - return &ErrCaseConflict{name, realName} + return &CaseConflictError{name, realName} } return nil } diff --git a/lib/fs/fakefs.go b/lib/fs/fakefs.go index af508f18c..3c056eab6 100644 --- a/lib/fs/fakefs.go +++ b/lib/fs/fakefs.go @@ -147,29 +147,29 @@ func newFakeFilesystem(rootURI string, _ ...Option) *fakeFS { // *look* like file I/O, but they are not. Do not worry that they // might fail. - rng := rand.New(rand.NewSource(int64(seed))) + rng := rand.New(rand.NewSource(int64(seed))) //nolint:gosec var createdFiles int var writtenData int64 for (files == 0 || createdFiles < files) && (maxsize == 0 || writtenData>>20 < int64(maxsize)) { dir := filepath.Join(fmt.Sprintf("%02x", rng.Intn(255)), fmt.Sprintf("%02x", rng.Intn(255))) file := fmt.Sprintf("%016x", rng.Int63()) - fs.MkdirAll(dir, 0o755) + _ = fs.MkdirAll(dir, 0o755) fd, _ := fs.Create(filepath.Join(dir, file)) createdFiles++ fsize := int64(sizeavg/2 + rng.Intn(sizeavg)) - fd.Truncate(fsize) + _ = fd.Truncate(fsize) writtenData += fsize ftime := time.Unix(1000000000+rng.Int63n(10*365*86400), 0) - fs.Chtimes(filepath.Join(dir, file), ftime, ftime) + _ = fs.Chtimes(filepath.Join(dir, file), ftime, ftime) } } if !nostfolder { // Also create a default folder marker for good measure - fs.Mkdir(".stfolder", 0o700) + _ = fs.Mkdir(".stfolder", 0o700) } // We only set the latency after doing the operations required to create @@ -284,9 +284,10 @@ func (fs *fakeFS) create(name string) (*fakeEntry, error) { time.Sleep(fs.latency) if entry := fs.entryForName(name); entry != nil { - if entry.entryType == fakeEntryTypeDir { + switch entry.entryType { + case fakeEntryTypeDir: return nil, os.ErrExist - } else if entry.entryType == fakeEntryTypeSymlink { + case fakeEntryTypeSymlink: return nil, errors.New("following symlink not supported") } entry.size = 0 @@ -731,6 +732,7 @@ func (fs *fakeFS) resetCounters() { } func (fs *fakeFS) reportMetricsPerOp(b *testing.B) { + b.Helper() fs.reportMetricsPer(b, 1, "op") } @@ -829,7 +831,7 @@ func (f *fakeFile) readShortAt(p []byte, offs int64) (int, error) { if f.seed == 0 { hf := fnv.New64() hf.Write([]byte(f.name)) - f.seed = int64(hf.Sum64()) + f.seed = int64(hf.Sum64()) //nolint:gosec } // Check whether the read is a continuation of an RNG we already have or @@ -839,14 +841,14 @@ func (f *fakeFile) readShortAt(p []byte, offs int64) (int, error) { nextBlockOffs := (seedNo + 1) << randomBlockShift if f.rng == nil || f.offset != offs || seedNo != f.seedOffs { // This is not a straight read continuing from a previous one - f.rng = rand.New(rand.NewSource(f.seed + seedNo)) + f.rng = rand.New(rand.NewSource(f.seed + seedNo)) //nolint:gosec // If the read is not at the start of the block, discard data // accordingly. diff := offs - minOffs if diff > 0 { lr := io.LimitReader(f.rng, diff) - io.Copy(io.Discard, lr) + _, _ = io.Copy(io.Discard, lr) } f.offset = offs diff --git a/lib/fs/filesystem.go b/lib/fs/filesystem.go index fa34fe9fd..368ba1ca5 100644 --- a/lib/fs/filesystem.go +++ b/lib/fs/filesystem.go @@ -180,7 +180,7 @@ const ( // SkipDir is used as a return value from WalkFuncs to indicate that // the directory named in the call is to be skipped. It is not returned // as an error by any function. -var SkipDir = filepath.SkipDir +var SkipDir = filepath.SkipDir //nolint:errname func IsExist(err error) bool { return errors.Is(err, ErrExist) @@ -259,15 +259,16 @@ func NewFilesystem(fsType FilesystemType, uri string, opts ...Option) Filesystem // attributed to the calling function. layersAboveWalkFilesystem++ } - if l.ShouldDebug("walkfs") { + switch { + case l.ShouldDebug("walkfs"): // A walkFilesystem is not a layer to skip, it embeds the underlying // filesystem, passing calls directly trough. Except for calls made // during walking, however those are truly originating in the walk // filesystem. fs = NewWalkFilesystem(newLogFilesystem(fs, layersAboveWalkFilesystem)) - } else if l.ShouldDebug("fs") { + case l.ShouldDebug("fs"): fs = newLogFilesystem(NewWalkFilesystem(fs), layersAboveWalkFilesystem) - } else { + default: fs = NewWalkFilesystem(fs) } diff --git a/lib/fs/filesystem_copy_range_standard.go b/lib/fs/filesystem_copy_range_standard.go index cd49fafe0..f59e0fd64 100644 --- a/lib/fs/filesystem_copy_range_standard.go +++ b/lib/fs/filesystem_copy_range_standard.go @@ -7,6 +7,7 @@ package fs import ( + "errors" "io" ) @@ -28,7 +29,7 @@ func copyRangeStandard(src, dst File, srcOffset, dstOffset, size int64) error { } n, err := src.ReadAt(buf, srcOffset) if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { return io.ErrUnexpectedEOF } return err diff --git a/lib/fs/mtimefs.go b/lib/fs/mtimefs.go index 3264e510c..523652d77 100644 --- a/lib/fs/mtimefs.go +++ b/lib/fs/mtimefs.go @@ -68,7 +68,7 @@ func (*optionMtime) String() string { func (f *mtimeFS) Chtimes(name string, atime, mtime time.Time) error { // Do a normal Chtimes call, don't care if it succeeds or not. - f.chtimes(name, atime, mtime) + _ = f.chtimes(name, atime, mtime) // Stat the file to see what happened. Here we *do* return an error, // because it might be "does not exist" or similar. diff --git a/lib/fs/types.go b/lib/fs/types.go index 7dc86c9fb..224e24389 100644 --- a/lib/fs/types.go +++ b/lib/fs/types.go @@ -26,8 +26,10 @@ type Option interface { type FilesystemFactory func(string, ...Option) (Filesystem, error) // For each registered file system type, a function to construct a file system. -var filesystemFactories map[FilesystemType]FilesystemFactory = make(map[FilesystemType]FilesystemFactory) -var filesystemFactoriesMutex sync.Mutex = sync.Mutex{} +var ( + filesystemFactories map[FilesystemType]FilesystemFactory = make(map[FilesystemType]FilesystemFactory) + filesystemFactoriesMutex sync.Mutex = sync.Mutex{} +) // Register a function to be called when a filesystem is to be constructed with // the specified fsType. The function will receive the URI for the file system as well diff --git a/lib/fs/util.go b/lib/fs/util.go index 41ee39300..94a0a5416 100644 --- a/lib/fs/util.go +++ b/lib/fs/util.go @@ -192,7 +192,7 @@ func CommonPrefix(first, second string) string { } common := make([]string, 0, count) - for i := 0; i < count; i++ { + for i := range count { if firstParts[i] != secondParts[i] { break } diff --git a/lib/fs/walkfs.go b/lib/fs/walkfs.go index 36bce97a7..a6c8613bb 100644 --- a/lib/fs/walkfs.go +++ b/lib/fs/walkfs.go @@ -89,7 +89,7 @@ func (f *walkFilesystem) walk(path string, info FileInfo, walkFn WalkFunc, ances err = walkFn(path, info, nil) if err != nil { - if info.IsDir() && err == SkipDir { + if info.IsDir() && errors.Is(err, SkipDir) { return nil } return err @@ -117,13 +117,13 @@ func (f *walkFilesystem) walk(path string, info FileInfo, walkFn WalkFunc, ances filename := filepath.Join(path, name) fileInfo, err := f.Lstat(filename) if err != nil { - if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir { + if err := walkFn(filename, fileInfo, err); err != nil && !errors.Is(err, SkipDir) { return err } } else { err = f.walk(filename, fileInfo, walkFn, ancestors) if err != nil { - if !fileInfo.IsDir() || err != SkipDir { + if !fileInfo.IsDir() || !errors.Is(err, SkipDir) { return err } } diff --git a/lib/model/folder.go b/lib/model/folder.go index 0ebe3db3d..8d98e8495 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -1077,7 +1077,7 @@ func (f *folder) monitorWatch(ctx context.Context) { f.setWatchError(err, next) // This error was previously a panic and should never occur, so generate // a warning, but don't do it repetitively. - var errOutside *fs.ErrWatchEventOutsideRoot + var errOutside *fs.WatchEventOutsideRootError if errors.As(err, &errOutside) { if !warnedOutside { l.Warnln(err) diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index 2f659c2f0..ac84fd832 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -977,7 +977,7 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, db } switch stat, serr := f.mtimefs.Lstat(target.Name); { case serr != nil: - var caseErr *fs.ErrCaseConflict + var caseErr *fs.CaseConflictError switch { case errors.As(serr, &caseErr): if caseErr.Real != source.Name { @@ -1149,7 +1149,7 @@ func (f *sendReceiveFolder) reuseBlocks(blocks []protocol.BlockInfo, reused []in // reuse. tempBlocks, err := scanner.HashFile(f.ctx, f.ID, f.mtimefs, tempName, file.BlockSize(), nil) if err != nil { - var caseErr *fs.ErrCaseConflict + var caseErr *fs.CaseConflictError if errors.As(err, &caseErr) { if rerr := f.mtimefs.Rename(caseErr.Real, tempName); rerr == nil { tempBlocks, err = scanner.HashFile(f.ctx, f.ID, f.mtimefs, tempName, file.BlockSize(), nil) diff --git a/lib/model/folder_sendrecv_test.go b/lib/model/folder_sendrecv_test.go index 822a567a4..5eff7a19c 100644 --- a/lib/model/folder_sendrecv_test.go +++ b/lib/model/folder_sendrecv_test.go @@ -1014,7 +1014,7 @@ func TestPullCaseOnlyPerformFinish(t *testing.T) { default: } - var caseErr *fs.ErrCaseConflict + var caseErr *fs.CaseConflictError if !errors.As(err, &caseErr) { t.Error("Expected case conflict error, got", err) }