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
noOpen bool
data []byte 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()
......
...@@ -39,9 +39,9 @@ func init() { ...@@ -39,9 +39,9 @@ func init() {
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
) )
...@@ -158,9 +158,9 @@ const ( ...@@ -158,9 +158,9 @@ const (
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