lib/scanner: Use fs.Filesystem for all operations
One more step on the path of the great refactoring. Touches rwfolder a little bit since it uses the Lstat from fs as well, but mostly this is just on the scanner as rwfolder is scheduled for a later refactor. There are a couple of usages of fs.DefaultFilesystem that will in the end become a filesystem injected from the top, but that comes later. GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4070 LGTM: AudriusButkevicius, imsodin
This commit is contained in:
@@ -32,7 +32,7 @@ func (f *BasicFilesystem) Mkdir(name string, perm FileMode) error {
|
||||
}
|
||||
|
||||
func (f *BasicFilesystem) Lstat(name string) (FileInfo, error) {
|
||||
fi, err := os.Lstat(name)
|
||||
fi, err := underlyingLstat(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -71,11 +71,32 @@ func (f *BasicFilesystem) DirNames(name string) ([]string, error) {
|
||||
}
|
||||
|
||||
func (f *BasicFilesystem) Open(name string) (File, error) {
|
||||
return os.Open(name)
|
||||
fd, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fsFile{fd}, err
|
||||
}
|
||||
|
||||
func (f *BasicFilesystem) Create(name string) (File, error) {
|
||||
return os.Create(name)
|
||||
fd, err := os.Create(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fsFile{fd}, err
|
||||
}
|
||||
|
||||
// fsFile implements the fs.File interface on top of an os.File
|
||||
type fsFile struct {
|
||||
*os.File
|
||||
}
|
||||
|
||||
func (f fsFile) Stat() (FileInfo, error) {
|
||||
info, err := f.File.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fsFileInfo{info}, nil
|
||||
}
|
||||
|
||||
// fsFileInfo implements the fs.FileInfo interface on top of an os.FileInfo.
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -37,6 +38,7 @@ type File interface {
|
||||
io.WriterAt
|
||||
io.Closer
|
||||
Truncate(size int64) error
|
||||
Stat() (FileInfo, error)
|
||||
}
|
||||
|
||||
// The FileInfo interface is almost the same as os.FileInfo, but with the
|
||||
@@ -57,12 +59,20 @@ type FileInfo interface {
|
||||
// FileMode is similar to os.FileMode
|
||||
type FileMode uint32
|
||||
|
||||
// ModePerm is the equivalent of os.ModePerm
|
||||
const ModePerm = FileMode(os.ModePerm)
|
||||
|
||||
// DefaultFilesystem is the fallback to use when nothing explicitly has
|
||||
// been passed.
|
||||
var DefaultFilesystem Filesystem = new(BasicFilesystem)
|
||||
var DefaultFilesystem Filesystem = NewBasicFilesystem()
|
||||
|
||||
// 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 errSkipDir = errors.New("skip this directory")
|
||||
var SkipDir = errSkipDir // silences the lint warning...
|
||||
var SkipDir = filepath.SkipDir
|
||||
|
||||
// IsExist is the equivalent of os.IsExist
|
||||
var IsExist = os.IsExist
|
||||
|
||||
// IsNotExist is the equivalent of os.IsNotExist
|
||||
var IsNotExist = os.IsNotExist
|
||||
|
||||
29
lib/fs/lstat_broken.go
Normal file
29
lib/fs/lstat_broken.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2015 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build linux android
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Lstat is like os.Lstat, except lobotomized for Android. See
|
||||
// https://forum.syncthing.net/t/2395
|
||||
func underlyingLstat(name string) (fi os.FileInfo, err error) {
|
||||
for i := 0; i < 10; i++ { // We have to draw the line somewhere
|
||||
fi, err = os.Lstat(name)
|
||||
if err, ok := err.(*os.PathError); ok && err.Err == syscall.EINTR {
|
||||
time.Sleep(time.Duration(i+1) * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
15
lib/fs/lstat_regular.go
Normal file
15
lib/fs/lstat_regular.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2015 The Syncthing Authors.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build !linux,!android
|
||||
|
||||
package fs
|
||||
|
||||
import "os"
|
||||
|
||||
func underlyingLstat(name string) (fi os.FileInfo, err error) {
|
||||
return os.Lstat(name)
|
||||
}
|
||||
@@ -27,12 +27,14 @@ var osChtimes = os.Chtimes
|
||||
// of what shenanigans the underlying filesystem gets up to. A nil MtimeFS
|
||||
// just does the underlying operations with no additions.
|
||||
type MtimeFS struct {
|
||||
Filesystem
|
||||
db database
|
||||
}
|
||||
|
||||
func NewMtimeFS(db database) *MtimeFS {
|
||||
func NewMtimeFS(underlying Filesystem, db database) *MtimeFS {
|
||||
return &MtimeFS{
|
||||
db: db,
|
||||
Filesystem: underlying,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,12 +58,8 @@ func (f *MtimeFS) Chtimes(name string, atime, mtime time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *MtimeFS) Lstat(name string) (os.FileInfo, error) {
|
||||
if f == nil {
|
||||
return osutil.Lstat(name)
|
||||
}
|
||||
|
||||
info, err := osutil.Lstat(name)
|
||||
func (f *MtimeFS) Lstat(name string) (FileInfo, error) {
|
||||
info, err := f.Filesystem.Lstat(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -113,7 +111,7 @@ func (f *MtimeFS) load(name string) (real, virtual time.Time) {
|
||||
// The mtimeFileInfo is an os.FileInfo that lies about the ModTime().
|
||||
|
||||
type mtimeFileInfo struct {
|
||||
os.FileInfo
|
||||
FileInfo
|
||||
mtime time.Time
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestMtimeFS(t *testing.T) {
|
||||
// a random time with nanosecond precision
|
||||
testTime := time.Unix(1234567890, 123456789)
|
||||
|
||||
mtimefs := NewMtimeFS(make(mapStore))
|
||||
mtimefs := NewMtimeFS(DefaultFilesystem, make(mapStore))
|
||||
|
||||
// Do one Chtimes call that will go through to the normal filesystem
|
||||
osChtimes = os.Chtimes
|
||||
|
||||
Reference in New Issue
Block a user