From 25b3ba465992163bf8e10f1653a749266c5887a3 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Mon, 19 Jun 2023 23:12:23 +0300 Subject: [PATCH] Make TestReadDirSlurpContinuation work on Windows --- internal/goofys_fs_test.go | 23 +++++++++-------- internal/goofys_unix_test.go | 13 ++++++++++ internal/goofys_windows.go | 45 +++++++++++++++++++++++++++++++++ internal/goofys_windows_test.go | 13 ++++++++++ 4 files changed, 84 insertions(+), 10 deletions(-) diff --git a/internal/goofys_fs_test.go b/internal/goofys_fs_test.go index 398047b5..98971778 100644 --- a/internal/goofys_fs_test.go +++ b/internal/goofys_fs_test.go @@ -20,9 +20,11 @@ package internal import ( "bytes" "fmt" + "io/fs" "io/ioutil" "os" "os/exec" + "path/filepath" "syscall" "time" @@ -163,22 +165,23 @@ func (s *GoofysTest) TestReadDirSlurpContinuation(t *C) { t.Assert(err, IsNil) } // Sync the whole filesystem - fh, err := os.Open(mountPoint) - t.Assert(err, IsNil) - err = fh.Sync() - t.Assert(err, IsNil) - err = fh.Close() + err := FsyncDir(mountPoint) t.Assert(err, IsNil) // Unmount s.umount(t, mountPoint) // Mount again s.mount(t, mountPoint) - // Check that `find` returns all files to check that slurp works correctly with the continuation - c := exec.Command("/bin/bash", "-c", "find "+mountPoint+"/slurpc -type f | wc -l") - out, err := c.CombinedOutput() - t.Assert(err, IsNil) - t.Assert(string(out), Equals, "2003\n") + // Check that all files are present to check that slurp works correctly with the continuation + count := 0 + filepath.Walk(mountPoint+"/slurpc", func(path string, info fs.FileInfo, err error) error { + t.Assert(err, IsNil) + if !info.IsDir() { + count++ + } + return nil + }) + t.Assert(count, Equals, 2003) } func (s *GoofysTest) writeSeekWriteFuse(t *C, file string, fh *os.File, first string, second string, third string) { diff --git a/internal/goofys_unix_test.go b/internal/goofys_unix_test.go index a1c16484..103f5807 100644 --- a/internal/goofys_unix_test.go +++ b/internal/goofys_unix_test.go @@ -91,6 +91,19 @@ func (s *GoofysTest) umount(t *C, mountPoint string) { os.Remove(mountPoint) } +func FsyncDir(dir string) error { + fh, err := os.Open(dir) + if err != nil { + return err + } + err = fh.Sync() + if err != nil { + fh.Close() + return err + } + return fh.Close() +} + func (s *GoofysTest) SetUpSuite(t *C) { s.tmp = os.Getenv("TMPDIR") if s.tmp == "" { diff --git a/internal/goofys_windows.go b/internal/goofys_windows.go index 462d89d5..29243ef4 100644 --- a/internal/goofys_windows.go +++ b/internal/goofys_windows.go @@ -411,6 +411,22 @@ func (fs *GoofysWin) Create(path string, flags int, mode uint32) (ret int, fhId return mapWinError(err), 0 } + if fs.flags.FlushFilename != "" && child == fs.flags.FlushFilename { + err = fs.SyncFS(parent) + if err == nil { + err = syscall.ENOENT + } + return mapWinError(err), 0 + } + + if fs.flags.RefreshFilename != "" && child == fs.flags.RefreshFilename { + err = fs.RefreshInodeCache(parent) + if err == nil { + err = syscall.ENOENT + } + return mapWinError(err), 0 + } + inode, fh, err := parent.Create(child) if err != nil { return mapWinError(err), 0 @@ -428,6 +444,11 @@ func (fs *GoofysWin) Create(path string, flags int, mode uint32) (ret int, fhId return 0, uint64(handleID) } +func endsWith(path, part string) bool { + ld := len(path)-len(part) + return len(part) > 0 && ld >= 0 && (ld == 0 || path[ld-1] == '/') && path[ld:] == part +} + // Open opens a file. // The flags are a combination of the fuse.O_* constants. func (fs *GoofysWin) Open(path string, flags int) (ret int, fhId uint64) { @@ -442,6 +463,30 @@ func (fs *GoofysWin) Open(path string, flags int) (ret int, fhId uint64) { inode, err := fs.LookupPath(path) if err != nil { + if endsWith(path, fs.flags.FlushFilename) { + parent, _, err := fs.LookupParent(path) + if err != nil { + return mapWinError(err), 0 + } + if err == nil { + err = fs.SyncFS(parent) + } + if err == nil { + err = syscall.ENOENT + } + } + if endsWith(path, fs.flags.RefreshFilename) { + parent, _, err := fs.LookupParent(path) + if err != nil { + return mapWinError(err), 0 + } + if err == nil { + err = fs.RefreshInodeCache(parent) + } + if err == nil { + err = syscall.ENOENT + } + } return mapWinError(err), 0 } diff --git a/internal/goofys_windows_test.go b/internal/goofys_windows_test.go index 992178db..2816aed7 100644 --- a/internal/goofys_windows_test.go +++ b/internal/goofys_windows_test.go @@ -20,7 +20,9 @@ package internal import ( + "errors" "os" + "syscall" "time" . "gopkg.in/check.v1" ) @@ -54,3 +56,14 @@ func (s *GoofysTest) umount(t *C, mountPoint string) { s.mfs.Unmount() s.mfs = nil } + +func FsyncDir(dir string) error { + fh, err := os.Create(dir+"/.fsyncdir") + if errors.Is(err, syscall.ENOENT) { + return nil + } + if err == nil { + fh.Close() + } + return err +}