Commit 3e137f8a authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fuse: support handleless read/write that skips the OPEN opcode.

parent 24519377
...@@ -9,14 +9,22 @@ import ( ...@@ -9,14 +9,22 @@ import (
type nodeReadNode struct { type nodeReadNode struct {
Node Node
data []byte noOpen bool
data []byte
} }
func newNodeReadNode(d []byte) *nodeReadNode { func newNodeReadNode(noOpen bool, d []byte) *nodeReadNode {
return &nodeReadNode{NewDefaultNode(), d} return &nodeReadNode{
Node: NewDefaultNode(),
noOpen: noOpen,
data: d,
}
} }
func (n *nodeReadNode) Open(flags uint32, context *fuse.Context) (file File, code fuse.Status) { func (n *nodeReadNode) Open(flags uint32, context *fuse.Context) (file File, code fuse.Status) {
if n.noOpen {
return nil, fuse.ENOSYS
}
return nil, fuse.OK return nil, fuse.OK
} }
...@@ -31,17 +39,53 @@ func (n *nodeReadNode) Read(file File, dest []byte, off int64, context *fuse.Con ...@@ -31,17 +39,53 @@ func (n *nodeReadNode) Read(file File, dest []byte, off int64, context *fuse.Con
func (n *nodeReadNode) Lookup(out *fuse.Attr, name string, context *fuse.Context) (*Inode, fuse.Status) { func (n *nodeReadNode) Lookup(out *fuse.Attr, name string, context *fuse.Context) (*Inode, fuse.Status) {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0644
out.Size = uint64(len(name)) out.Size = uint64(len(name))
ch := n.Inode().NewChild(name, false, newNodeReadNode([]byte(name))) ch := n.Inode().NewChild(name, false, newNodeReadNode(n.noOpen, []byte(name)))
return ch, fuse.OK return ch, fuse.OK
} }
func TestNoOpen(t *testing.T) {
dir, err := ioutil.TempDir("", "nodefs")
if err != nil {
t.Fatalf("TempDir: %v", err)
}
root := newNodeReadNode(true, nil)
root.noOpen = true
s, _, err := MountRoot(dir, root, nil)
if err != nil {
t.Fatalf("MountRoot: %v", err)
}
s.SetDebug(VerboseTest())
defer s.Unmount()
go s.Serve()
content, err := ioutil.ReadFile(dir + "/file")
if err != nil {
t.Fatalf("ReadFile: %v", err)
}
want := "file"
if string(content) != want {
t.Fatalf("got %q, want %q", content, want)
}
content, err = ioutil.ReadFile(dir + "/file2")
if err != nil {
t.Fatalf("ReadFile: %v", err)
}
want = "file2"
if string(content) != want {
t.Fatalf("got %q, want %q", content, want)
}
}
func TestNodeRead(t *testing.T) { func TestNodeRead(t *testing.T) {
dir, err := ioutil.TempDir("", "nodefs") dir, err := ioutil.TempDir("", "nodefs")
if err != nil { if err != nil {
t.Fatalf("TempDir: %v", err) t.Fatalf("TempDir: %v", err)
} }
root := newNodeReadNode(nil) root := newNodeReadNode(false, nil)
s, _, err := MountRoot(dir, root, nil) s, _, err := MountRoot(dir, root, nil)
if err != nil { if err != nil {
t.Fatalf("MountRoot: %v", err) t.Fatalf("MountRoot: %v", err)
...@@ -56,4 +100,5 @@ func TestNodeRead(t *testing.T) { ...@@ -56,4 +100,5 @@ func TestNodeRead(t *testing.T) {
if string(content) != want { if string(content) != want {
t.Fatalf("got %q, want %q", content, want) t.Fatalf("got %q, want %q", content, want)
} }
} }
...@@ -79,7 +79,7 @@ func doInit(server *Server, req *request) { ...@@ -79,7 +79,7 @@ func doInit(server *Server, req *request) {
server.reqMu.Lock() server.reqMu.Lock()
server.kernelSettings = *input server.kernelSettings = *input
server.kernelSettings.Flags = input.Flags & (CAP_ASYNC_READ | CAP_BIG_WRITES | CAP_FILE_OPS | server.kernelSettings.Flags = input.Flags & (CAP_ASYNC_READ | CAP_BIG_WRITES | CAP_FILE_OPS |
CAP_AUTO_INVAL_DATA | CAP_READDIRPLUS) CAP_AUTO_INVAL_DATA | CAP_READDIRPLUS | CAP_NO_OPEN_SUPPORT)
if input.Minor >= 13 { if input.Minor >= 13 {
server.setSplice() server.setSplice()
......
...@@ -24,24 +24,24 @@ func init() { ...@@ -24,24 +24,24 @@ func init() {
READ_LOCKOWNER: "LOCKOWNER", READ_LOCKOWNER: "LOCKOWNER",
} }
initFlagNames = map[int64]string{ initFlagNames = map[int64]string{
CAP_ASYNC_READ: "ASYNC_READ", CAP_ASYNC_READ: "ASYNC_READ",
CAP_POSIX_LOCKS: "POSIX_LOCKS", CAP_POSIX_LOCKS: "POSIX_LOCKS",
CAP_FILE_OPS: "FILE_OPS", CAP_FILE_OPS: "FILE_OPS",
CAP_ATOMIC_O_TRUNC: "ATOMIC_O_TRUNC", CAP_ATOMIC_O_TRUNC: "ATOMIC_O_TRUNC",
CAP_EXPORT_SUPPORT: "EXPORT_SUPPORT", CAP_EXPORT_SUPPORT: "EXPORT_SUPPORT",
CAP_BIG_WRITES: "BIG_WRITES", CAP_BIG_WRITES: "BIG_WRITES",
CAP_DONT_MASK: "DONT_MASK", CAP_DONT_MASK: "DONT_MASK",
CAP_SPLICE_WRITE: "SPLICE_WRITE", CAP_SPLICE_WRITE: "SPLICE_WRITE",
CAP_SPLICE_MOVE: "SPLICE_MOVE", CAP_SPLICE_MOVE: "SPLICE_MOVE",
CAP_SPLICE_READ: "SPLICE_READ", CAP_SPLICE_READ: "SPLICE_READ",
CAP_FLOCK_LOCKS: "FLOCK_LOCKS", CAP_FLOCK_LOCKS: "FLOCK_LOCKS",
CAP_IOCTL_DIR: "IOCTL_DIR", CAP_IOCTL_DIR: "IOCTL_DIR",
CAP_AUTO_INVAL_DATA: "AUTO_INVAL_DATA", CAP_AUTO_INVAL_DATA: "AUTO_INVAL_DATA",
CAP_READDIRPLUS: "READDIRPLUS", CAP_READDIRPLUS: "READDIRPLUS",
CAP_READDIRPLUS_AUTO: "READDIRPLUS_AUTO", CAP_READDIRPLUS_AUTO: "READDIRPLUS_AUTO",
CAP_FUSE_ASYNC_DIO: "ASYNC_DIO", CAP_ASYNC_DIO: "ASYNC_DIO",
CAP_FUSE_WRITEBACK_CACHE: "WRITEBACK_CACHE", CAP_WRITEBACK_CACHE: "WRITEBACK_CACHE",
CAP_FUSE_NO_OPEN_SUPPORT: "NO_OPEN_SUPPORT", CAP_NO_OPEN_SUPPORT: "NO_OPEN_SUPPORT",
} }
releaseFlagNames = map[int64]string{ releaseFlagNames = map[int64]string{
RELEASE_FLUSH: "FLUSH", RELEASE_FLUSH: "FLUSH",
......
...@@ -5,5 +5,5 @@ const outputHeaderSize = 160 ...@@ -5,5 +5,5 @@ const outputHeaderSize = 160
const ( const (
_FUSE_KERNEL_VERSION = 7 _FUSE_KERNEL_VERSION = 7
_MINIMUM_MINOR_VERSION = 12 _MINIMUM_MINOR_VERSION = 12
_OUR_MINOR_VERSION = 21 _OUR_MINOR_VERSION = 23
) )
...@@ -143,24 +143,24 @@ type OpenOut struct { ...@@ -143,24 +143,24 @@ type OpenOut struct {
// To be set in InitIn/InitOut.Flags. // To be set in InitIn/InitOut.Flags.
const ( const (
CAP_ASYNC_READ = (1 << 0) CAP_ASYNC_READ = (1 << 0)
CAP_POSIX_LOCKS = (1 << 1) CAP_POSIX_LOCKS = (1 << 1)
CAP_FILE_OPS = (1 << 2) CAP_FILE_OPS = (1 << 2)
CAP_ATOMIC_O_TRUNC = (1 << 3) CAP_ATOMIC_O_TRUNC = (1 << 3)
CAP_EXPORT_SUPPORT = (1 << 4) CAP_EXPORT_SUPPORT = (1 << 4)
CAP_BIG_WRITES = (1 << 5) CAP_BIG_WRITES = (1 << 5)
CAP_DONT_MASK = (1 << 6) CAP_DONT_MASK = (1 << 6)
CAP_SPLICE_WRITE = (1 << 7) CAP_SPLICE_WRITE = (1 << 7)
CAP_SPLICE_MOVE = (1 << 8) CAP_SPLICE_MOVE = (1 << 8)
CAP_SPLICE_READ = (1 << 9) CAP_SPLICE_READ = (1 << 9)
CAP_FLOCK_LOCKS = (1 << 10) CAP_FLOCK_LOCKS = (1 << 10)
CAP_IOCTL_DIR = (1 << 11) CAP_IOCTL_DIR = (1 << 11)
CAP_AUTO_INVAL_DATA = (1 << 12) CAP_AUTO_INVAL_DATA = (1 << 12)
CAP_READDIRPLUS = (1 << 13) CAP_READDIRPLUS = (1 << 13)
CAP_READDIRPLUS_AUTO = (1 << 14) CAP_READDIRPLUS_AUTO = (1 << 14)
CAP_FUSE_ASYNC_DIO = (1 << 15) CAP_ASYNC_DIO = (1 << 15)
CAP_FUSE_WRITEBACK_CACHE = (1 << 16) CAP_WRITEBACK_CACHE = (1 << 16)
CAP_FUSE_NO_OPEN_SUPPORT = (1 << 17) CAP_NO_OPEN_SUPPORT = (1 << 17)
) )
type InitIn struct { type InitIn struct {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment