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 (
type nodeReadNode struct {
Node
noOpen bool
data []byte
}
func newNodeReadNode(d []byte) *nodeReadNode {
return &nodeReadNode{NewDefaultNode(), d}
func newNodeReadNode(noOpen bool, d []byte) *nodeReadNode {
return &nodeReadNode{
Node: NewDefaultNode(),
noOpen: noOpen,
data: d,
}
}
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
}
......@@ -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) {
out.Mode = fuse.S_IFREG | 0644
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
}
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) {
dir, err := ioutil.TempDir("", "nodefs")
if err != nil {
t.Fatalf("TempDir: %v", err)
}
root := newNodeReadNode(nil)
root := newNodeReadNode(false, nil)
s, _, err := MountRoot(dir, root, nil)
if err != nil {
t.Fatalf("MountRoot: %v", err)
......@@ -56,4 +100,5 @@ func TestNodeRead(t *testing.T) {
if string(content) != want {
t.Fatalf("got %q, want %q", content, want)
}
}
......@@ -79,7 +79,7 @@ func doInit(server *Server, req *request) {
server.reqMu.Lock()
server.kernelSettings = *input
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 {
server.setSplice()
......
......@@ -39,9 +39,9 @@ func init() {
CAP_AUTO_INVAL_DATA: "AUTO_INVAL_DATA",
CAP_READDIRPLUS: "READDIRPLUS",
CAP_READDIRPLUS_AUTO: "READDIRPLUS_AUTO",
CAP_FUSE_ASYNC_DIO: "ASYNC_DIO",
CAP_FUSE_WRITEBACK_CACHE: "WRITEBACK_CACHE",
CAP_FUSE_NO_OPEN_SUPPORT: "NO_OPEN_SUPPORT",
CAP_ASYNC_DIO: "ASYNC_DIO",
CAP_WRITEBACK_CACHE: "WRITEBACK_CACHE",
CAP_NO_OPEN_SUPPORT: "NO_OPEN_SUPPORT",
}
releaseFlagNames = map[int64]string{
RELEASE_FLUSH: "FLUSH",
......
......@@ -5,5 +5,5 @@ const outputHeaderSize = 160
const (
_FUSE_KERNEL_VERSION = 7
_MINIMUM_MINOR_VERSION = 12
_OUR_MINOR_VERSION = 21
_OUR_MINOR_VERSION = 23
)
......@@ -158,9 +158,9 @@ const (
CAP_AUTO_INVAL_DATA = (1 << 12)
CAP_READDIRPLUS = (1 << 13)
CAP_READDIRPLUS_AUTO = (1 << 14)
CAP_FUSE_ASYNC_DIO = (1 << 15)
CAP_FUSE_WRITEBACK_CACHE = (1 << 16)
CAP_FUSE_NO_OPEN_SUPPORT = (1 << 17)
CAP_ASYNC_DIO = (1 << 15)
CAP_WRITEBACK_CACHE = (1 << 16)
CAP_NO_OPEN_SUPPORT = (1 << 17)
)
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