Skip to content

Commit

Permalink
FUSE3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
billziss-gh committed Jan 4, 2025
1 parent 1bbc1ac commit 7def2b6
Show file tree
Hide file tree
Showing 17 changed files with 472 additions and 352 deletions.
15 changes: 15 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ build_script:
- go version
- go build -v ./...
- go build -v ./examples/memfs
- go build -tags=memfs3 -v -o memfs3.exe ./examples/memfs

test_script:
- go test -v ./fuse
Expand All @@ -43,6 +44,7 @@ test_script:

# hard code fsreg parameters because appveyor does not like percents ("--VolumePrefix=%1 %2")
- C:\projects\winfsp\tools\fsreg.bat gomemfs "C:\projects\go\src\github.com\winfsp\cgofuse\memfs.exe" "--VolumePrefix=\gomemfs\share M:" "D:P(A;;RPWPLC;;;WD)"
- C:\projects\winfsp\tools\fsreg.bat gomemfs3 "C:\projects\go\src\github.com\winfsp\cgofuse\memfs3.exe" "--VolumePrefix=\gomemfs3\share N:" "D:P(A;;RPWPLC;;;WD)"

# test against WinFsp v1.0
- 'net use M: \\gomemfs\share'
Expand All @@ -52,6 +54,13 @@ test_script:
# - C:\Projects\winfsp\ext\test\fstools\src\fsx\fsx.exe -N 10000 test xxxxxx
- 'C: & cd'
- 'net use M: /delete'
- 'net use N: \\gomemfs3\share'
- 'N: & cd'
- C:\projects\winfsp\build\VStudio\build\Release\winfsp-tests-x64.exe --external --resilient --share-prefix=\gomemfs\share -create_allocation_test -create_fileattr_test -getfileinfo_name_test -setfileinfo_test -delete_access_test -setsecurity_test -querydir_namelen_test -reparse* -stream*
# disable fsx test on WinFsp v1.0, as there was a bug in FUSE write.
# - C:\Projects\winfsp\ext\test\fstools\src\fsx\fsx.exe -N 10000 test xxxxxx
- 'C: & cd'
- 'net use N: /delete'

# test against WinFsp v1.2 DLL with chflags, setcrtime and setchgtime
# HACK: mixing DLL and FSD versions; do not try this at home
Expand All @@ -63,3 +72,9 @@ test_script:
- C:\Projects\winfsp\ext\test\fstools\src\fsx\fsx.exe -N 10000 test xxxxxx
- 'C: & cd'
- 'net use M: /delete'
- 'net use N: \\gomemfs3\share'
- 'N: & cd'
- C:\projects\winfsp\build\VStudio\build\Release\winfsp-tests-x64.exe --external --resilient --share-prefix=\gomemfs\share -create_allocation_test -create_fileattr_test -getfileinfo_name_test -delete_access_test -setsecurity_test -querydir_namelen_test -reparse* -stream*
- C:\Projects\winfsp\ext\test\fstools\src\fsx\fsx.exe -N 10000 test xxxxxx
- 'C: & cd'
- 'net use N: /delete'
92 changes: 71 additions & 21 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,27 @@ jobs:
GOARCH: ${{ matrix.arch }}
CGO_ENABLED: ${{ matrix.cgo }}
CPATH: ${{ matrix.cpath }}
GOEXPERIMENT: cgocheck2
GODEBUG: cgocheck=2
strategy:
matrix:
include:
- os: windows-latest
arch: amd64
exe: .exe
cgo: 1
cpath: C:\Program Files (x86)\WinFsp\inc\fuse
- os: windows-latest
arch: amd64
exe: .exe
cgo: 0
- os: windows-latest
arch: 386
exe: .exe
cgo: 0
- os: ubuntu-latest
arch: amd64
cgo: 1
# macOS runner can no longer load the macfuse kext; use runner only to build
- os: macos-latest
arch: amd64
cgo: 1
Expand All @@ -43,18 +50,14 @@ jobs:
- name: Install go
uses: actions/setup-go@v5
with:
go-version: '1.23'
go-version: 1.20.*

- name: Install winfsp and winfsp-tests (Windows)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: runner.os == 'Windows'
run: |
$headers = @{
Authorization = "token $env:GITHUB_TOKEN"
"User-Agent" = "GitHub Actions"
Authorization = "token ${{ secrets.GITHUB_TOKEN }}"
}
$releases = Invoke-WebRequest https://api.github.com/repos/winfsp/winfsp/releases -Headers $headers | `
ConvertFrom-Json
Expand Down Expand Up @@ -88,26 +91,43 @@ jobs:
rm -rf secfs.test/fstest/fstest/tests/xacl
rm -rf secfs.test/fstest/fstest/tests/zzz_ResourceFork
- name: Install FUSE (macOS)
if: runner.os == 'macOS'
- name: Install FUSE and secfs.test (macOS disabled)
if: false && runner.os == 'macOS'
run: |
brew install macfuse
- name: Build packages with fuse2
git clone -q https://github.com/billziss-gh/secfs.test.git secfs.test
git -C secfs.test checkout -q edf5eb4a108bfb41073f765aef0cdd32bb3ee1ed
mkdir -p secfs.test/tools/bin
touch secfs.test/tools/bin/bonnie++
touch secfs.test/tools/bin/iozone
make -C secfs.test
# configure fstest for cgofuse
sed -e 's/^fs=.*$/fs="cgofuse"/' -i "" secfs.test/fstest/fstest/tests/conf
# monkey-patch/disable some tests for macOS
rm secfs.test/fstest/fstest/tests/rmdir/12.t
sed -e 's/lchmod)/lchmod) return 1/' -i "" secfs.test/fstest/fstest/tests/misc.sh
# remove irrelevant tests
rm -rf secfs.test/fstest/fstest/tests/xacl
rm -rf secfs.test/fstest/fstest/tests/zzz_ResourceFork
- name: Build packages with FUSE2
run: |
go build -v -o . ./...
- name: Test packages with fuse2
if: runner.os == 'Linux' || runner.os == 'Windows'
run: |
go test -v -count=1 ./fuse
go build -tags=memfs3 -v -o memfs3${{ matrix.exe }} ./examples/memfs
- name: Test file systems (Windows) with fuse2
- name: Test file systems with FUSE2 (Windows)
if: runner.os == 'Windows'
run: |
Set-PSDebug -Trace 1
go test -v -count=1 ./fuse
$testexe = (Get-Item winfsp-tests\winfsp-tests-x64.exe)
Start-Process -NoNewWindow .\memfs.exe "-o uid=-1,rellinks,FileInfoTimeout=-1 X:"
Start-Sleep 3
Push-Location X:\
Expand All @@ -120,11 +140,25 @@ jobs:
Start-Sleep 3
Pop-Location
- name: Test file systems (Linux) with fuse2
if: runner.os == 'Linux'
Start-Process -NoNewWindow .\memfs3.exe "-o uid=-1,rellinks,FileInfoTimeout=-1 X:"
Start-Sleep 3
Push-Location X:\
. $testexe --fuse-external --resilient --case-insensitive-cmp `
+* `
-create_fileattr_test `
-reparse_nfs_test `
-ea*
Stop-Process -Name memfs3
Start-Sleep 3
Pop-Location
- name: Test file systems (Linux / macOS disabled) with FUSE2
if: runner.os == 'Linux' || (false && runner.os == 'macOS')
run: |
set -x
go test -v -count=1 ./fuse
mkdir p mnt
sudo ./memfs -o allow_other,default_permissions,use_ino,attr_timeout=0 mnt &
Expand All @@ -134,6 +168,13 @@ jobs:
(cd mnt && ../secfs.test/tools/bin/fsx -e -N 1000 test xxxx)
sudo umount mnt
sudo ./memfs3 -o allow_other,default_permissions,use_ino,attr_timeout=0 mnt &
sleep 3
(cd mnt && sudo prove -fr ../secfs.test/fstest/fstest/tests)
(cd mnt && ../secfs.test/tools/bin/fsx -N 10000 test xxxxxx)
(cd mnt && ../secfs.test/tools/bin/fsx -e -N 1000 test xxxx)
sudo umount mnt
sudo ./passthrough -o allow_other,default_permissions,use_ino,attr_timeout=0 p mnt &
sleep 3
(cd mnt && sudo prove -fr ../secfs.test/fstest/fstest/tests)
Expand All @@ -143,17 +184,19 @@ jobs:
rm -rf p
rmdir mnt
- name: Build packages with fuse3 (Linux)
- name: Build packages with FUSE3 (Linux)
if: runner.os == 'Linux'
run: |
go build -tags=fuse3 -v -o . ./...
go test -v -count=1 ./fuse
go build -tags=fuse3,memfs3 -v -o memfs3${{ matrix.exe }} ./examples/memfs
- name: Test file systems (Linux) with fuse3
- name: Test file systems with FUSE3 (Linux)
if: runner.os == 'Linux'
run: |
set -x
go test -tags=fuse3 -v -count=1 ./fuse
mkdir p mnt
sudo ./memfs -o allow_other,default_permissions,attr_timeout=0 mnt &
Expand All @@ -163,6 +206,13 @@ jobs:
(cd mnt && ../secfs.test/tools/bin/fsx -e -N 1000 test xxxx)
sudo umount mnt
sudo ./memfs3 -o allow_other,default_permissions,attr_timeout=0 mnt &
sleep 3
(cd mnt && sudo prove -fr ../secfs.test/fstest/fstest/tests)
(cd mnt && ../secfs.test/tools/bin/fsx -N 10000 test xxxxxx)
(cd mnt && ../secfs.test/tools/bin/fsx -e -N 1000 test xxxx)
sudo umount mnt
sudo ./passthrough -o allow_other,default_permissions,attr_timeout=0 p mnt &
sleep 3
(cd mnt && sudo prove -fr ../secfs.test/fstest/fstest/tests)
Expand Down
3 changes: 2 additions & 1 deletion examples/hellofs/hellofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ func (self *Hellofs) Read(path string, buff []byte, ofst int64, fh uint64) (n in

func (self *Hellofs) Readdir(path string,
fill func(name string, stat *fuse.Stat_t, ofst int64) bool,
ofst int64, fh uint64) (errc int) {
ofst int64,
fh uint64) (errc int) {
fill(".", nil, 0)
fill("..", nil, 0)
fill(filename, nil, 0)
Expand Down
22 changes: 6 additions & 16 deletions examples/memfs/memfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func (self *Memfs) Utimens(path string, tmsp []fuse.Timespec) (errc int) {
return -fuse.ENOENT
}
node.stat.Ctim = fuse.Now()
if tmsp == nil || (len(tmsp) == 2 && tmsp[0].Sec == 0 && tmsp[1].Sec == 0) {
if nil == tmsp {
tmsp0 := node.stat.Ctim
tmsa := [2]fuse.Timespec{tmsp0, tmsp0}
tmsp = tmsa[:]
Expand All @@ -244,7 +244,7 @@ func (self *Memfs) Utimens(path string, tmsp []fuse.Timespec) (errc int) {
func (self *Memfs) Open(path string, flags int) (errc int, fh uint64) {
defer trace(path, flags)(&errc, &fh)
defer self.synchronize()()
return self.openNode(path, false, flags)
return self.openNode(path, false)
}

func (self *Memfs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
Expand Down Expand Up @@ -320,7 +320,7 @@ func (self *Memfs) Release(path string, fh uint64) (errc int) {
func (self *Memfs) Opendir(path string) (errc int, fh uint64) {
defer trace(path)(&errc, &fh)
defer self.synchronize()()
return self.openNode(path, true, 0)
return self.openNode(path, true)
}

func (self *Memfs) Readdir(path string,
Expand Down Expand Up @@ -526,7 +526,7 @@ func (self *Memfs) removeNode(path string, dir bool) int {
return 0
}

func (self *Memfs) openNode(path string, dir bool, flags int) (int, uint64) {
func (self *Memfs) openNode(path string, dir bool) (int, uint64) {
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT, ^uint64(0)
Expand All @@ -537,13 +537,6 @@ func (self *Memfs) openNode(path string, dir bool, flags int) (int, uint64) {
if dir && fuse.S_IFDIR != node.stat.Mode&fuse.S_IFMT {
return -fuse.ENOTDIR, ^uint64(0)
}
if flags&fuse.O_TRUNC == fuse.O_TRUNC {
node.data = resize(node.data, 0, true)
node.stat.Size = 0
tmsp := fuse.Now()
node.stat.Ctim = tmsp
node.stat.Mtim = tmsp
}
node.opencnt++
if 1 == node.opencnt {
self.openmap[node.stat.Ino] = node
Expand All @@ -553,12 +546,9 @@ func (self *Memfs) openNode(path string, dir bool, flags int) (int, uint64) {

func (self *Memfs) closeNode(fh uint64) int {
node := self.openmap[fh]
if node == nil {
return -fuse.EBADF
}
node.opencnt--
if 0 == node.opencnt {
delete(self.openmap, fh)
delete(self.openmap, node.stat.Ino)
}
return 0
}
Expand Down Expand Up @@ -596,6 +586,6 @@ func main() {
memfs := NewMemfs()
host := fuse.NewFileSystemHost(memfs)
host.SetCapReaddirPlus(true)
host.SetUseIno(true)
host.SetUseIno(true) // FUSE3 only
host.Mount("", os.Args[1:])
}
Loading

0 comments on commit 7def2b6

Please sign in to comment.