fs: remove os.FileInfo from fs.ExtendedFileInfo

Only the `Sys()` value from os.FileInfo is kept as field `sys` to
support Windows. The os.FileInfo removal ensures that for values like
`ModTime` that existed in both data structures there's no more confusion
which value is actually used.
This commit is contained in:
Michael Eischer
2024-11-30 16:58:04 +01:00
parent 847b2efba2
commit 9a99141a5f
17 changed files with 80 additions and 178 deletions

View File

@@ -505,7 +505,7 @@ func (arch *Archiver) save(ctx context.Context, snPath, target string, previous
}
switch {
case fi.Mode().IsRegular():
case fi.Mode.IsRegular():
debug.Log(" %v regular file", target)
// check if the file has not changed before performing a fopen operation (more expensive, specially
@@ -555,7 +555,7 @@ func (arch *Archiver) save(ctx context.Context, snPath, target string, previous
}
// make sure it's still a file
if !fi.Mode().IsRegular() {
if !fi.Mode.IsRegular() {
err = errors.Errorf("file %q changed type, refusing to archive", target)
return filterError(err)
}
@@ -571,7 +571,7 @@ func (arch *Archiver) save(ctx context.Context, snPath, target string, previous
arch.trackItem(snPath, previous, node, stats, time.Since(start))
})
case fi.IsDir():
case fi.Mode.IsDir():
debug.Log(" %v dir", target)
snItem := snPath + "/"
@@ -592,7 +592,7 @@ func (arch *Archiver) save(ctx context.Context, snPath, target string, previous
return futureNode{}, false, err
}
case fi.Mode()&os.ModeSocket > 0:
case fi.Mode&os.ModeSocket > 0:
debug.Log(" %v is a socket, ignoring", target)
return futureNode{}, true, nil

View File

@@ -2303,19 +2303,26 @@ func TestMetadataChanged(t *testing.T) {
t.Fatalf("metadata does not match:\n%v", cmp.Diff(want, node2))
}
// modify the mode by wrapping it in a new struct, uses the consts defined above
fs.overrideFI = wrapFileInfo(fi)
// modify the mode and UID/GID
modFI := *fi
modFI.Mode = mockFileInfoMode
if runtime.GOOS != "windows" {
modFI.UID = mockFileInfoUID
modFI.GID = mockFileInfoGID
}
fs.overrideFI = &modFI
rtest.Assert(t, !fileChanged(fs.overrideFI, node2, 0), "testfile must not be considered as changed")
// set the override values in the 'want' node which
want.Mode = 0400
want.Mode = mockFileInfoMode
// ignore UID and GID on Windows
if runtime.GOOS != "windows" {
want.UID = 51234
want.GID = 51235
want.UID = mockFileInfoUID
want.GID = mockFileInfoGID
}
// update mock node accordingly
fs.overrideNode.Mode = 0400
fs.overrideNode.Mode = want.Mode
fs.overrideNode.UID = want.UID
fs.overrideNode.GID = want.GID
@@ -2456,10 +2463,12 @@ func TestIrregularFile(t *testing.T) {
tempfile := filepath.Join(tempdir, "testfile")
fi := lstat(t, "testfile")
// patch mode to irregular
fi.Mode = (fi.Mode &^ os.ModeType) | os.ModeIrregular
override := &overrideFS{
FS: fs.Local{},
overrideFI: wrapIrregularFileInfo(fi),
overrideFI: fi,
overrideNode: &restic.Node{
Type: restic.NodeTypeIrregular,
},

View File

@@ -4,8 +4,6 @@
package archiver
import (
"os"
"syscall"
"testing"
"github.com/restic/restic/internal/feature"
@@ -14,48 +12,6 @@ import (
rtest "github.com/restic/restic/internal/test"
)
type wrappedFileInfo struct {
os.FileInfo
sys interface{}
mode os.FileMode
}
func (fi wrappedFileInfo) Sys() interface{} {
return fi.sys
}
func (fi wrappedFileInfo) Mode() os.FileMode {
return fi.mode
}
// wrapFileInfo returns a new os.FileInfo with the mode, owner, and group fields changed.
func wrapFileInfo(fi *fs.ExtendedFileInfo) *fs.ExtendedFileInfo {
// get the underlying stat_t and modify the values
stat := fi.Sys().(*syscall.Stat_t)
stat.Mode = mockFileInfoMode
stat.Uid = mockFileInfoUID
stat.Gid = mockFileInfoGID
// wrap the os.FileInfo so we can return a modified stat_t
return fs.ExtendedStat(wrappedFileInfo{
FileInfo: fi.FileInfo,
sys: stat,
mode: mockFileInfoMode,
})
}
// wrapIrregularFileInfo returns a new os.FileInfo with the mode changed to irregular file
func wrapIrregularFileInfo(fi *fs.ExtendedFileInfo) *fs.ExtendedFileInfo {
// wrap the os.FileInfo so we can return a modified stat_t
return &fs.ExtendedFileInfo{
FileInfo: wrappedFileInfo{
FileInfo: fi.FileInfo,
sys: fi.Sys(),
mode: (fi.Mode() &^ os.ModeType) | os.ModeIrregular,
},
}
}
func statAndSnapshot(t *testing.T, repo archiverRepo, name string) (*restic.Node, *restic.Node) {
want := nodeFromFile(t, &fs.Local{}, name)
_, node := snapshot(t, repo, &fs.Local{}, nil, name)

View File

@@ -1,38 +0,0 @@
//go:build windows
// +build windows
package archiver
import (
"os"
"github.com/restic/restic/internal/fs"
)
type wrappedFileInfo struct {
os.FileInfo
mode os.FileMode
}
func (fi wrappedFileInfo) Mode() os.FileMode {
return fi.mode
}
// wrapFileInfo returns a new os.FileInfo with the mode, owner, and group fields changed.
func wrapFileInfo(fi *fs.ExtendedFileInfo) *fs.ExtendedFileInfo {
// wrap the os.FileInfo and return the modified mode, uid and gid are ignored on Windows
return fs.ExtendedStat(wrappedFileInfo{
FileInfo: fi.FileInfo,
mode: mockFileInfoMode,
})
}
// wrapIrregularFileInfo returns a new os.FileInfo with the mode changed to irregular file
func wrapIrregularFileInfo(fi *fs.ExtendedFileInfo) *fs.ExtendedFileInfo {
return &fs.ExtendedFileInfo{
FileInfo: wrappedFileInfo{
FileInfo: fi.FileInfo,
mode: (fi.Mode() &^ os.ModeType) | os.ModeIrregular,
},
}
}

View File

@@ -267,7 +267,7 @@ func RejectByDevice(samples []string, filesystem fs.FS) (RejectFunc, error) {
}
// reject everything except directories
if !fi.IsDir() {
if !fi.Mode.IsDir() {
return true
}
@@ -303,7 +303,7 @@ func RejectByDevice(samples []string, filesystem fs.FS) (RejectFunc, error) {
func RejectBySize(maxSize int64) (RejectFunc, error) {
return func(item string, fi *fs.ExtendedFileInfo, _ fs.FS) bool {
// directory will be ignored
if fi.IsDir() {
if fi.Mode.IsDir() {
return false
}

View File

@@ -118,10 +118,10 @@ func (s *Scanner) scan(ctx context.Context, stats ScanStats, target string) (Sca
}
switch {
case fi.Mode().IsRegular():
case fi.Mode.IsRegular():
stats.Files++
stats.Bytes += uint64(fi.Size)
case fi.Mode().IsDir():
case fi.Mode.IsDir():
names, err := fs.Readdirnames(s.FS, target, fs.O_NOFOLLOW)
if err != nil {
return stats, s.Error(target, err)

View File

@@ -57,7 +57,7 @@ func TestScanner(t *testing.T) {
},
},
selFn: func(item string, fi *fs.ExtendedFileInfo, fs fs.FS) bool {
if fi.IsDir() {
if fi.Mode.IsDir() {
return true
}