Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Levin Zimmermann
go-fuse
Commits
06a252bd
Commit
06a252bd
authored
Mar 29, 2023
by
Han-Wen Nienhuys
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Run gofmt
Change-Id: I
144cb541
parent
144cb541
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
60 additions
and
59 deletions
+60
-59
fs/api.go
fs/api.go
+33
-35
fs/bridge_test.go
fs/bridge_test.go
+1
-2
fs/dynamic_example_test.go
fs/dynamic_example_test.go
+5
-6
fuse/api.go
fuse/api.go
+2
-2
fuse/pathfs/syscall_test.go
fuse/pathfs/syscall_test.go
+1
-0
fuse/pathfs/xattr_test.go
fuse/pathfs/xattr_test.go
+1
-0
fuse/server.go
fuse/server.go
+2
-2
fuse/splice_linux.go
fuse/splice_linux.go
+5
-5
fuse/test/file_lock_test.go
fuse/test/file_lock_test.go
+1
-0
fuse/test/node_parallel_lookup_test.go
fuse/test/node_parallel_lookup_test.go
+3
-4
fuse/test/xattr_test.go
fuse/test/xattr_test.go
+1
-0
fuse/test/xfs_test.go
fuse/test/xfs_test.go
+1
-0
fuse/types.go
fuse/types.go
+1
-1
internal/testutil/helpers.go
internal/testutil/helpers.go
+3
-2
No files found.
fs/api.go
View file @
06a252bd
...
@@ -4,43 +4,43 @@
...
@@ -4,43 +4,43 @@
// Package fs provides infrastructure to build tree-organized filesystems.
// Package fs provides infrastructure to build tree-organized filesystems.
//
//
// Structure of a file system implementation
//
#
Structure of a file system implementation
//
//
// To create a file system, you should first define types for the
// To create a file system, you should first define types for the
// nodes of the file system tree.
// nodes of the file system tree.
//
//
//
struct myNode {
//
struct myNode {
//
fs.Inode
//
fs.Inode
//
}
//
}
//
//
//
// Node types must be InodeEmbedders
//
// Node types must be InodeEmbedders
//
var _ = (fs.InodeEmbedder)((*myNode)(nil))
//
var _ = (fs.InodeEmbedder)((*myNode)(nil))
//
//
//
// Node types should implement some file system operations, eg. Lookup
//
// Node types should implement some file system operations, eg. Lookup
//
var _ = (fs.NodeLookuper)((*myNode)(nil))
//
var _ = (fs.NodeLookuper)((*myNode)(nil))
//
//
//
func (n *myNode) Lookup(ctx context.Context, name string, ... ) (*Inode, syscall.Errno) {
//
func (n *myNode) Lookup(ctx context.Context, name string, ... ) (*Inode, syscall.Errno) {
//
ops := myNode{}
//
ops := myNode{}
//
return n.NewInode(ctx, &ops, fs.StableAttr{Mode: syscall.S_IFDIR}), 0
//
return n.NewInode(ctx, &ops, fs.StableAttr{Mode: syscall.S_IFDIR}), 0
//
}
//
}
//
//
// The method names are inspired on the system call names, so we have
// The method names are inspired on the system call names, so we have
// Listxattr rather than ListXAttr.
// Listxattr rather than ListXAttr.
//
//
// the file system is mounted by calling mount on the root of the tree,
// the file system is mounted by calling mount on the root of the tree,
//
//
//
server, err := fs.Mount("/tmp/mnt", &myNode{}, &fs.Options{})
//
server, err := fs.Mount("/tmp/mnt", &myNode{}, &fs.Options{})
//
..
//
..
//
// start serving the file system
//
// start serving the file system
//
server.Wait()
//
server.Wait()
//
//
// Error handling
//
#
Error handling
//
//
// All error reporting must use the syscall.Errno type. This is an
// All error reporting must use the syscall.Errno type. This is an
// integer with predefined error codes, where the value 0 (`OK`)
// integer with predefined error codes, where the value 0 (`OK`)
// should be used to indicate success.
// should be used to indicate success.
//
//
// File system concepts
//
#
File system concepts
//
//
// The FUSE API is very similar to Linux' internal VFS API for
// The FUSE API is very similar to Linux' internal VFS API for
// defining file systems in the kernel. It is therefore useful to
// defining file systems in the kernel. It is therefore useful to
...
@@ -58,11 +58,11 @@
...
@@ -58,11 +58,11 @@
// There can be several paths leading from tree root to a particular node,
// There can be several paths leading from tree root to a particular node,
// known as hard-linking, for example
// known as hard-linking, for example
//
//
//
root
// root
//
/ \
// / \
//
dir1 dir2
// dir1 dir2
//
\ /
// \ /
//
file
// file
//
//
// Inode: ("index node") points to the file content, and stores
// Inode: ("index node") points to the file content, and stores
// metadata (size, timestamps) about a file or directory. Each
// metadata (size, timestamps) about a file or directory. Each
...
@@ -87,8 +87,7 @@
...
@@ -87,8 +87,7 @@
// Go-FUSE, but the result of Lookup operation essentially is a
// Go-FUSE, but the result of Lookup operation essentially is a
// dirent, which the kernel puts in a cache.
// dirent, which the kernel puts in a cache.
//
//
//
// # Kernel caching
// Kernel caching
//
//
// The kernel caches several pieces of information from the FUSE process:
// The kernel caches several pieces of information from the FUSE process:
//
//
...
@@ -117,19 +116,19 @@
...
@@ -117,19 +116,19 @@
// entries. by default. This can be achieve in go-fuse by setting
// entries. by default. This can be achieve in go-fuse by setting
// options on mount, eg.
// options on mount, eg.
//
//
//
sec := time.Second
//
sec := time.Second
//
opts := fs.Options{
//
opts := fs.Options{
//
EntryTimeout: &sec,
//
EntryTimeout: &sec,
//
AttrTimeout: &sec,
//
AttrTimeout: &sec,
//
}
//
}
//
//
// Locking
//
#
Locking
//
//
// Locks for networked filesystems are supported through the suite of
// Locks for networked filesystems are supported through the suite of
// Getlk, Setlk and Setlkw methods. They alllow locks on regions of
// Getlk, Setlk and Setlkw methods. They alllow locks on regions of
// regular files.
// regular files.
//
//
// Parallelism
//
#
Parallelism
//
//
// The VFS layer in the kernel is optimized to be highly parallel, and
// The VFS layer in the kernel is optimized to be highly parallel, and
// this parallelism also affects FUSE file systems: many FUSE
// this parallelism also affects FUSE file systems: many FUSE
...
@@ -138,7 +137,7 @@
...
@@ -138,7 +137,7 @@
// system issuing file operations in parallel, and using the race
// system issuing file operations in parallel, and using the race
// detector to weed out data races.
// detector to weed out data races.
//
//
// Dynamically discovered file systems
//
#
Dynamically discovered file systems
//
//
// File system data usually cannot fit all in RAM, so the kernel must
// File system data usually cannot fit all in RAM, so the kernel must
// discover the file system dynamically: as you are entering and list
// discover the file system dynamically: as you are entering and list
...
@@ -151,7 +150,7 @@
...
@@ -151,7 +150,7 @@
// individual children of directories, and 2. Readdir, part of the
// individual children of directories, and 2. Readdir, part of the
// NodeReaddirer interface for listing the contents of a directory.
// NodeReaddirer interface for listing the contents of a directory.
//
//
// Static in-memory file systems
//
#
Static in-memory file systems
//
//
// For small, read-only file systems, getting the locking mechanics of
// For small, read-only file systems, getting the locking mechanics of
// Lookup correct is tedious, so Go-FUSE provides a feature to
// Lookup correct is tedious, so Go-FUSE provides a feature to
...
@@ -401,7 +400,6 @@ type DirStream interface {
...
@@ -401,7 +400,6 @@ type DirStream interface {
// children in directories. Hence, they also return *Inode and must
// children in directories. Hence, they also return *Inode and must
// populate their fuse.EntryOut arguments.
// populate their fuse.EntryOut arguments.
//
type
NodeLookuper
interface
{
type
NodeLookuper
interface
{
Lookup
(
ctx
context
.
Context
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
syscall
.
Errno
)
Lookup
(
ctx
context
.
Context
,
name
string
,
out
*
fuse
.
EntryOut
)
(
*
Inode
,
syscall
.
Errno
)
}
}
...
...
fs/bridge_test.go
View file @
06a252bd
...
@@ -206,8 +206,7 @@ func (n *testDeletedIno) Getattr(ctx context.Context, f FileHandle, out *fuse.At
...
@@ -206,8 +206,7 @@ func (n *testDeletedIno) Getattr(ctx context.Context, f FileHandle, out *fuse.At
//
//
// We used to panic like this because inode number 1 was special:
// We used to panic like this because inode number 1 was special:
//
//
// panic: using reserved ID 1 for inode number
// panic: using reserved ID 1 for inode number
//
func
TestIno1
(
t
*
testing
.
T
)
{
func
TestIno1
(
t
*
testing
.
T
)
{
rootNode
:=
testIno1
{}
rootNode
:=
testIno1
{}
mnt
,
_
,
clean
:=
testMount
(
t
,
&
rootNode
,
nil
)
mnt
,
_
,
clean
:=
testMount
(
t
,
&
rootNode
,
nil
)
...
...
fs/dynamic_example_test.go
View file @
06a252bd
...
@@ -19,17 +19,16 @@ import (
...
@@ -19,17 +19,16 @@ import (
// numbers are regular files, while composite numbers are directories
// numbers are regular files, while composite numbers are directories
// containing all smaller numbers, eg.
// containing all smaller numbers, eg.
//
//
//
$ ls -F /tmp/x/6
//
$ ls -F /tmp/x/6
//
2 3 4/ 5
//
2 3 4/ 5
//
//
// the file system nodes are deduplicated using inode numbers. The
// the file system nodes are deduplicated using inode numbers. The
// number 2 appears in many directories, but it is actually the represented
// number 2 appears in many directories, but it is actually the represented
// by the same numberNode{} object, with inode number 2.
// by the same numberNode{} object, with inode number 2.
//
//
// $ ls -i1 /tmp/x/2 /tmp/x/8/6/4/2
// $ ls -i1 /tmp/x/2 /tmp/x/8/6/4/2
// 2 /tmp/x/2
// 2 /tmp/x/2
// 2 /tmp/x/8/6/4/2
// 2 /tmp/x/8/6/4/2
//
type
numberNode
struct
{
type
numberNode
struct
{
// Must embed an Inode for the struct to work as a node.
// Must embed an Inode for the struct to work as a node.
fs
.
Inode
fs
.
Inode
...
...
fuse/api.go
View file @
06a252bd
...
@@ -74,7 +74,7 @@
...
@@ -74,7 +74,7 @@
// see https://github.com/hanwen/go-fuse/issues/261 for an example of that
// see https://github.com/hanwen/go-fuse/issues/261 for an example of that
// problem.
// problem.
//
//
// Higher level interfaces
//
#
Higher level interfaces
//
//
// As said above this packages provides way to implement filesystems in terms of
// As said above this packages provides way to implement filesystems in terms of
// raw FUSE protocol.
// raw FUSE protocol.
...
@@ -82,7 +82,7 @@
...
@@ -82,7 +82,7 @@
// Package github.com/hanwen/go-fuse/v2/fs provides way to implement
// Package github.com/hanwen/go-fuse/v2/fs provides way to implement
// filesystems in terms of paths and/or inodes.
// filesystems in terms of paths and/or inodes.
//
//
// Mount styles
//
#
Mount styles
//
//
// The NewServer() handles mounting the filesystem, which
// The NewServer() handles mounting the filesystem, which
// involves opening `/dev/fuse` and calling the
// involves opening `/dev/fuse` and calling the
...
...
fuse/pathfs/syscall_test.go
View file @
06a252bd
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
// +build linux
package
pathfs
package
pathfs
...
...
fuse/pathfs/xattr_test.go
View file @
06a252bd
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
// +build linux
package
pathfs
package
pathfs
...
...
fuse/server.go
View file @
06a252bd
...
@@ -121,9 +121,9 @@ func (ms *Server) RecordLatencies(l LatencyMap) {
...
@@ -121,9 +121,9 @@ func (ms *Server) RecordLatencies(l LatencyMap) {
// Does not work when we were mounted with the magic /dev/fd/N mountpoint syntax,
// Does not work when we were mounted with the magic /dev/fd/N mountpoint syntax,
// as we do not know the real mountpoint. Unmount using
// as we do not know the real mountpoint. Unmount using
//
//
//
fusermount -u /path/to/real/mountpoint
//
fusermount -u /path/to/real/mountpoint
//
//
/// in this case.
//
/ in this case.
func
(
ms
*
Server
)
Unmount
()
(
err
error
)
{
func
(
ms
*
Server
)
Unmount
()
(
err
error
)
{
if
ms
.
mountPoint
==
""
{
if
ms
.
mountPoint
==
""
{
return
nil
return
nil
...
...
fuse/splice_linux.go
View file @
06a252bd
...
@@ -19,12 +19,12 @@ func (s *Server) setSplice() {
...
@@ -19,12 +19,12 @@ func (s *Server) setSplice() {
//
//
// This is a four-step process:
// This is a four-step process:
//
//
//
1)
Splice data form fdData.Fd into the "pair1" pipe buffer --> pair1: [payload]
//
1.
Splice data form fdData.Fd into the "pair1" pipe buffer --> pair1: [payload]
//
Now we know the actual payload length and can
//
Now we know the actual payload length and can
// construct the reply header
// construct the reply header
//
2)
Write header into the "pair2" pipe buffer --> pair2: [header]
//
2.
Write header into the "pair2" pipe buffer --> pair2: [header]
//
4)
Splice data from "pair1" into "pair2" --> pair2: [header][payload]
//
4.
Splice data from "pair1" into "pair2" --> pair2: [header][payload]
//
3)
Splice the data from "pair2" into /dev/fuse
//
3.
Splice the data from "pair2" into /dev/fuse
//
//
// This dance is neccessary because header and payload cannot be split across
// This dance is neccessary because header and payload cannot be split across
// two splices and we cannot seek in a pipe buffer.
// two splices and we cannot seek in a pipe buffer.
...
...
fuse/test/file_lock_test.go
View file @
06a252bd
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
// +build linux
package
test
package
test
...
...
fuse/test/node_parallel_lookup_test.go
View file @
06a252bd
...
@@ -45,7 +45,6 @@ func (r *tRoot) Lookup(out *fuse.Attr, name string, fctx *fuse.Context) (*nodefs
...
@@ -45,7 +45,6 @@ func (r *tRoot) Lookup(out *fuse.Attr, name string, fctx *fuse.Context) (*nodefs
return
node
.
Inode
(),
st
return
node
.
Inode
(),
st
}
}
// verifyFileRead verifies that file @path has content == dataOK.
// verifyFileRead verifies that file @path has content == dataOK.
func
verifyFileRead
(
path
string
,
dataOK
string
)
error
{
func
verifyFileRead
(
path
string
,
dataOK
string
)
error
{
v
,
err
:=
ioutil
.
ReadFile
(
path
)
v
,
err
:=
ioutil
.
ReadFile
(
path
)
...
@@ -99,7 +98,7 @@ func TestNodeParallelLookup(t *testing.T) {
...
@@ -99,7 +98,7 @@ func TestNodeParallelLookup(t *testing.T) {
}()
}()
// the test will deadlock if the client cannot issue several lookups simultaneously
// the test will deadlock if the client cannot issue several lookups simultaneously
if
srv
.
KernelSettings
()
.
Flags
&
fuse
.
CAP_PARALLEL_DIROPS
==
0
{
if
srv
.
KernelSettings
()
.
Flags
&
fuse
.
CAP_PARALLEL_DIROPS
==
0
{
t
.
Skip
(
"Kernel serializes dir lookups"
)
t
.
Skip
(
"Kernel serializes dir lookups"
)
}
}
...
@@ -110,10 +109,10 @@ func TestNodeParallelLookup(t *testing.T) {
...
@@ -110,10 +109,10 @@ func TestNodeParallelLookup(t *testing.T) {
defer
cancel
()
defer
cancel
()
wg
,
ctx
:=
errgroup
.
WithContext
(
ctx0
)
wg
,
ctx
:=
errgroup
.
WithContext
(
ctx0
)
wg
.
Go
(
func
()
error
{
wg
.
Go
(
func
()
error
{
return
verifyFileRead
(
dir
+
"/hello"
,
"abc"
)
return
verifyFileRead
(
dir
+
"/hello"
,
"abc"
)
})
})
wg
.
Go
(
func
()
error
{
wg
.
Go
(
func
()
error
{
return
verifyFileRead
(
dir
+
"/world"
,
"def"
)
return
verifyFileRead
(
dir
+
"/world"
,
"def"
)
})
})
// wait till both threads queue into Lookup
// wait till both threads queue into Lookup
...
...
fuse/test/xattr_test.go
View file @
06a252bd
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
// +build linux
package
test
package
test
...
...
fuse/test/xfs_test.go
View file @
06a252bd
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
// +build linux
package
test
package
test
...
...
fuse/types.go
View file @
06a252bd
...
@@ -509,7 +509,7 @@ const (
...
@@ -509,7 +509,7 @@ const (
NOTIFY_RETRIEVE_CACHE
=
-
5
// retrieve data from kernel cache of an inode
NOTIFY_RETRIEVE_CACHE
=
-
5
// retrieve data from kernel cache of an inode
NOTIFY_DELETE
=
-
6
// notify kernel that a directory entry has been deleted
NOTIFY_DELETE
=
-
6
// notify kernel that a directory entry has been deleted
//
NOTIFY_CODE_MAX = -6
//
NOTIFY_CODE_MAX = -6
)
)
type
FlushIn
struct
{
type
FlushIn
struct
{
...
...
internal/testutil/helpers.go
View file @
06a252bd
...
@@ -16,8 +16,9 @@ import (
...
@@ -16,8 +16,9 @@ import (
// Called by TestLoopbackFileUtimens and TestLoopbackFileSystemUtimens.
// Called by TestLoopbackFileUtimens and TestLoopbackFileSystemUtimens.
//
//
// Parameters:
// Parameters:
// path ........ path to the backing file
//
// utimensFn ... Utimens() function that acts on the backing file
// path ........ path to the backing file
// utimensFn ... Utimens() function that acts on the backing file
func
TestLoopbackUtimens
(
t
*
testing
.
T
,
path
string
,
utimensFn
func
(
atime
*
time
.
Time
,
mtime
*
time
.
Time
)
fuse
.
Status
)
{
func
TestLoopbackUtimens
(
t
*
testing
.
T
,
path
string
,
utimensFn
func
(
atime
*
time
.
Time
,
mtime
*
time
.
Time
)
fuse
.
Status
)
{
// Arbitrary date: 05/02/2018 @ 7:57pm (UTC)
// Arbitrary date: 05/02/2018 @ 7:57pm (UTC)
t0sec
:=
int64
(
1525291058
)
t0sec
:=
int64
(
1525291058
)
...
...
Levin Zimmermann
@levin.zimmermann
mentioned in commit
95d4266e
·
May 12, 2023
mentioned in commit
95d4266e
mentioned in commit 95d4266e62bafb096d79807eba5959e1915bbd56
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment