From 71e73fa46234d751a1834b15d9051b13fa2eab42 Mon Sep 17 00:00:00 2001 From: Sydonian <794346190@qq.com> Date: Tue, 15 Apr 2025 15:04:33 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=B5=8B=E8=AF=95=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/internal/mount/fuse/dir_node.go | 56 ++++++++++++++++++++----- client/internal/mount/fuse/file_node.go | 8 +++- client/internal/mount/vfs/cache/file.go | 6 +++ client/internal/mount/vfs/fuse_dir.go | 6 ++- client/internal/mount/vfs/fuse_file.go | 14 ++++++- client/internal/mount/vfstest/fs.go | 44 +++++++++---------- client/internal/mount/vfstest/write.go | 3 -- 7 files changed, 96 insertions(+), 41 deletions(-) diff --git a/client/internal/mount/fuse/dir_node.go b/client/internal/mount/fuse/dir_node.go index 459b4ba..33fc50b 100644 --- a/client/internal/mount/fuse/dir_node.go +++ b/client/internal/mount/fuse/dir_node.go @@ -60,7 +60,8 @@ const accessModeMask = (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) // Open opens an Inode (of regular file type) for reading. It // is optional but recommended to return a FileHandle. func (n *DirNode) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - logger.Tracef("DirNode.Open: %v, %#o", n.dir.Name(), flags) + log := logger.WithField("F", "DirNode.Open") + log.Tracef("args: %v, %#o", n.dir.Name(), flags) rdwrMode := int(flags) & accessModeMask if rdwrMode != os.O_RDONLY { @@ -69,6 +70,7 @@ func (n *DirNode) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, reader, err := n.dir.ReadChildren() if err != nil { + log.Warnf("read children: %v", err) return nil, 0, translateError(err) } @@ -78,10 +80,12 @@ func (n *DirNode) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, var _ = (fusefs.NodeOpener)((*DirNode)(nil)) func (n *DirNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (inode *fusefs.Inode, errno syscall.Errno) { - logger.Tracef("DirNode.Lookup: %v, %v", n.dir.Name(), name) + log := logger.WithField("F", "DirNode.Lookup") + log.Tracef("args: %v, %v", n.dir.Name(), name) child, err := n.dir.Child(ctx, name) if err != nil { + log.Warnf("child: %v", err) return nil, translateError(err) } @@ -125,8 +129,11 @@ func (s *dirStream) HasNext() bool { } func (s *dirStream) Next() (fuse.DirEntry, syscall.Errno) { + log := logger.WithField("F", "dirStream.Next") + entries, err := s.reader.Next(1) if err != nil { + log.Warnf("next: %v", err) return fuse.DirEntry{}, translateError(err) } entry := entries[0] @@ -142,10 +149,11 @@ func (s *dirStream) Close() { } func (n *DirNode) Readdir(ctx context.Context) (ds fusefs.DirStream, errno syscall.Errno) { - logger.Tracef("DirNode.Readdir: %v", n.dir.Name()) + log := logger.WithField("F", "DirNode.Readdir") reader, err := n.dir.ReadChildren() if err != nil { + log.Warnf("read children: %v", err) return nil, translateError(err) } @@ -155,10 +163,12 @@ func (n *DirNode) Readdir(ctx context.Context) (ds fusefs.DirStream, errno sysca var _ = (fusefs.NodeReaddirer)((*DirNode)(nil)) func (n *DirNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (inode *fusefs.Inode, errno syscall.Errno) { - logger.Tracef("DirNode.Mkdir: %v, %v, %#o", n.dir.Name(), name, mode) + log := logger.WithField("F", "DirNode.Mkdir") + log.Tracef("args: %v, %v, %#o", n.dir.Name(), name, mode) newDir, err := n.dir.NewDir(ctx, name) if err != nil { + log.Warnf("new dir: %v", err) return nil, translateError(err) } @@ -173,10 +183,12 @@ func (n *DirNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse var _ = (fusefs.NodeMkdirer)((*DirNode)(nil)) func (n *DirNode) Create(ctx context.Context, name string, flags uint32, mode uint32, out *fuse.EntryOut) (node *fusefs.Inode, fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - logger.Tracef("DirNode.Create: %v, %v, %#x, %#o", n.dir.Name(), name, flags, mode) + log := logger.WithField("F", "DirNode.Create") + logger.Tracef("args: %v, %v, %#x, %#o", n.dir.Name(), name, flags, mode) hd, flags, err := n.dir.NewFile(ctx, name, flags) if err != nil { + log.Warnf("new file: %v", err) return nil, nil, 0, translateError(err) } @@ -194,9 +206,16 @@ var _ = (fusefs.NodeCreater)((*DirNode)(nil)) // return status is OK, the Inode is removed as child in the // FS tree automatically. Default is to return EROFS. func (n *DirNode) Unlink(ctx context.Context, name string) (errno syscall.Errno) { - logger.Tracef("DirNode.Unlink: %v, %v", n.dir.Name(), name) + log := logger.WithField("F", "DirNode.Unlink") + log.Tracef("args: %v, %v", n.dir.Name(), name) + + err := n.dir.RemoveChild(ctx, name) + if err != nil { + log.Warnf("remove child: %v", err) + return translateError(err) + } - return translateError(n.dir.RemoveChild(ctx, name)) + return 0 } var _ = (fusefs.NodeUnlinker)((*DirNode)(nil)) @@ -204,21 +223,36 @@ var _ = (fusefs.NodeUnlinker)((*DirNode)(nil)) // Rmdir is like Unlink but for directories. // Default is to return EROFS. func (n *DirNode) Rmdir(ctx context.Context, name string) (errno syscall.Errno) { - logger.Tracef("DirNode.Rmdir: %v, %v", n.dir.Name(), name) + log := logger.WithField("F", "DirNode.Rmdir") + log.Tracef("args: %v, %v", n.dir.Name(), name) + + err := n.dir.RemoveChild(ctx, name) + if err != nil { + log.Warnf("remove child: %v", err) + return translateError(err) + } - return translateError(n.dir.RemoveChild(ctx, name)) + return 0 } var _ = (fusefs.NodeRmdirer)((*DirNode)(nil)) func (n *DirNode) Rename(ctx context.Context, oldName string, newParent fusefs.InodeEmbedder, newName string, flags uint32) (errno syscall.Errno) { - logger.Tracef("DirNode.Rename: %v/%v->%v, %#o", n.dir.Name(), oldName, newName, flags) + log := logger.WithField("F", "DirNode.Rename") + log.Tracef("args: %v/%v->%v, %#o", n.dir.Name(), oldName, newName, flags) newParentNode, ok := newParent.(*DirNode) if !ok { return syscall.ENOTDIR } - return translateError(n.dir.MoveChild(ctx, oldName, newName, newParentNode.dir)) + + err := n.dir.MoveChild(ctx, oldName, newName, newParentNode.dir) + if err != nil { + log.Warnf("move child: %v", err) + return translateError(err) + } + + return 0 } var _ = (fusefs.NodeRenamer)((*DirNode)(nil)) diff --git a/client/internal/mount/fuse/file_node.go b/client/internal/mount/fuse/file_node.go index de4d29f..7440081 100644 --- a/client/internal/mount/fuse/file_node.go +++ b/client/internal/mount/fuse/file_node.go @@ -31,7 +31,7 @@ func (n *FileNode) Getattr(ctx context.Context, f fusefs.FileHandle, out *fuse.A } func (n *FileNode) Setattr(ctx context.Context, f fusefs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) { - logger.Tracef("FileNode.Setattr: %v", n.file.Name()) + log := logger.WithField("F", "FileNode.Setattr") n.fs.fillAttrOut(n.file, out) @@ -39,6 +39,7 @@ func (n *FileNode) Setattr(ctx context.Context, f fusefs.FileHandle, in *fuse.Se if ok { err := n.file.Truncate(size) if err != nil { + log.Warnf("truncate: %v", err) return translateError(err) } out.Size = size @@ -48,6 +49,7 @@ func (n *FileNode) Setattr(ctx context.Context, f fusefs.FileHandle, in *fuse.Se if ok { err := n.file.SetModTime(modTime) if err != nil { + log.Warnf("set mod time: %v", err) return translateError(err) } out.Mtime = uint64(modTime.Unix()) @@ -60,10 +62,12 @@ func (n *FileNode) Setattr(ctx context.Context, f fusefs.FileHandle, in *fuse.Se var _ = (fusefs.NodeSetattrer)((*FileNode)(nil)) func (n *FileNode) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - logger.Tracef("FileNode.Open: %v, %#o", n.file.Name(), flags) + log := logger.WithField("F", "FileNode.Open") + log.Tracef("args: %v", flags) hd, flags, err := n.file.Open(flags) if err != nil { + log.Warnf("open: %v", err) return nil, 0, translateError(err) } diff --git a/client/internal/mount/vfs/cache/file.go b/client/internal/mount/vfs/cache/file.go index e761a77..8dba53b 100644 --- a/client/internal/mount/vfs/cache/file.go +++ b/client/internal/mount/vfs/cache/file.go @@ -641,6 +641,9 @@ type CacheFileHandle struct { } func (h *CacheFileHandle) ReadAt(buf []byte, off int64) (int, error) { + log := logger.WithField("F", "CacheFileHandle.ReadAt") + log.Tracef("buf: %v, off: %v", len(buf), off) + if !h.readable { return 0, fuse.ErrPermission } @@ -743,6 +746,9 @@ func (h *CacheFileHandle) ReadAt(buf []byte, off int64) (int, error) { } func (h *CacheFileHandle) WriteAt(buf []byte, off int64) (int, error) { + log := logger.WithField("F", "CacheFileHandle.WriteAt") + log.Tracef("buf: %v, off: %v", len(buf), off) + if !h.writeable { return 0, fuse.ErrPermission } diff --git a/client/internal/mount/vfs/fuse_dir.go b/client/internal/mount/vfs/fuse_dir.go index f349ed7..8ceb3c7 100644 --- a/client/internal/mount/vfs/fuse_dir.go +++ b/client/internal/mount/vfs/fuse_dir.go @@ -45,7 +45,11 @@ func (r *FuseDir) Mode() os.FileMode { } func (r *FuseDir) ModTime() time.Time { - return r.modTime + info := r.vfs.cache.Stat(r.pathComps) + if info == nil { + return r.modTime + } + return info.ModTime } func (r *FuseDir) IsDir() bool { diff --git a/client/internal/mount/vfs/fuse_file.go b/client/internal/mount/vfs/fuse_file.go index 7a8a236..97956d3 100644 --- a/client/internal/mount/vfs/fuse_file.go +++ b/client/internal/mount/vfs/fuse_file.go @@ -43,7 +43,12 @@ func (n *FuseFileNode) Name() string { } func (n *FuseFileNode) Size() int64 { - return n.size + info := n.vfs.cache.Stat(n.pathComps) + if info == nil { + return n.size + } + + return info.Size } func (n *FuseFileNode) Mode() os.FileMode { @@ -51,7 +56,12 @@ func (n *FuseFileNode) Mode() os.FileMode { } func (n *FuseFileNode) ModTime() time.Time { - return n.modTime + info := n.vfs.cache.Stat(n.pathComps) + if info == nil { + return n.modTime + } + + return info.ModTime } func (n *FuseFileNode) IsDir() bool { diff --git a/client/internal/mount/vfstest/fs.go b/client/internal/mount/vfstest/fs.go index 163029e..21de64a 100644 --- a/client/internal/mount/vfstest/fs.go +++ b/client/internal/mount/vfstest/fs.go @@ -42,33 +42,33 @@ func RunTests(t *testing.T, mnt *mount.Mount) { run.Init() logger.Infof("Starting test run") ok := t.Run("", func(t *testing.T) { - // t.Run("TestTouchAndDelete", TestTouchAndDelete) - // t.Run("TestRenameOpenHandle", TestRenameOpenHandle) - // t.Run("TestDirLs", TestDirLs) - // t.Run("TestDirCreateAndRemoveDir", TestDirCreateAndRemoveDir) - // t.Run("TestDirCreateAndRemoveFile", TestDirCreateAndRemoveFile) - // t.Run("TestDirRenameFile", TestDirRenameFile) - // t.Run("TestDirRenameEmptyDir", TestDirRenameEmptyDir) - // t.Run("TestDirRenameFullDir", TestDirRenameFullDir) - // t.Run("TestDirModTime", TestDirModTime) + t.Run("TestTouchAndDelete", TestTouchAndDelete) + t.Run("TestRenameOpenHandle", TestRenameOpenHandle) + t.Run("TestDirLs", TestDirLs) + t.Run("TestDirCreateAndRemoveDir", TestDirCreateAndRemoveDir) + t.Run("TestDirCreateAndRemoveFile", TestDirCreateAndRemoveFile) + t.Run("TestDirRenameFile", TestDirRenameFile) + t.Run("TestDirRenameEmptyDir", TestDirRenameEmptyDir) + t.Run("TestDirRenameFullDir", TestDirRenameFullDir) + t.Run("TestDirModTime", TestDirModTime) // if enableCacheTests { // t.Run("TestDirCacheFlush", TestDirCacheFlush) // } // t.Run("TestDirCacheFlushOnDirRename", TestDirCacheFlushOnDirRename) - // t.Run("TestFileModTime", TestFileModTime) - // t.Run("TestFileModTimeWithOpenWriters", TestFileModTimeWithOpenWriters) + t.Run("TestFileModTime", TestFileModTime) + t.Run("TestFileModTimeWithOpenWriters", TestFileModTimeWithOpenWriters) // t.Run("TestMount", TestMount) - // t.Run("TestRoot", TestRoot) - // t.Run("TestReadByByte", TestReadByByte) - // t.Run("TestReadChecksum", TestReadChecksum) - // t.Run("TestReadFileDoubleClose", TestReadFileDoubleClose) - // t.Run("TestReadSeek", TestReadSeek) - // t.Run("TestWriteFileNoWrite", TestWriteFileNoWrite) - // t.Run("TestWriteFileWrite", TestWriteFileWrite) - // t.Run("TestWriteFileOverwrite", TestWriteFileOverwrite) - // t.Run("TestWriteFileDoubleClose", TestWriteFileDoubleClose) - // t.Run("TestWriteFileFsync", TestWriteFileFsync) - // t.Run("TestWriteFileDup", TestWriteFileDup) + t.Run("TestRoot", TestRoot) + t.Run("TestReadByByte", TestReadByByte) + t.Run("TestReadChecksum", TestReadChecksum) + t.Run("TestReadFileDoubleClose", TestReadFileDoubleClose) + t.Run("TestReadSeek", TestReadSeek) + t.Run("TestWriteFileNoWrite", TestWriteFileNoWrite) + t.Run("TestWriteFileWrite", TestWriteFileWrite) + t.Run("TestWriteFileOverwrite", TestWriteFileOverwrite) + t.Run("TestWriteFileDoubleClose", TestWriteFileDoubleClose) + t.Run("TestWriteFileFsync", TestWriteFileFsync) + t.Run("TestWriteFileDup", TestWriteFileDup) t.Run("TestWriteFileAppend", TestWriteFileAppend) }) logger.Infof("Finished test run (ok=%v)", ok) diff --git a/client/internal/mount/vfstest/write.go b/client/internal/mount/vfstest/write.go index c3acd9e..2054f71 100644 --- a/client/internal/mount/vfstest/write.go +++ b/client/internal/mount/vfstest/write.go @@ -4,7 +4,6 @@ import ( "os" "runtime" "testing" - "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -159,8 +158,6 @@ func TestWriteFileAppend(t *testing.T) { err = fh.Close() require.NoError(t, err) - <-time.After(time.Second * 10) - info, err := run.os.Stat(filepath) require.NoError(t, err) require.EqualValues(t, len(testData)+len(appendData), info.Size())