Commit a519b679 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Have RawFileSystem fill in passed destination structured data.

parent 18ff28f7
...@@ -249,22 +249,22 @@ type DefaultFile struct{} ...@@ -249,22 +249,22 @@ type DefaultFile struct{}
// //
// Include DefaultRawFileSystem to inherit a null implementation. // Include DefaultRawFileSystem to inherit a null implementation.
type RawFileSystem interface { type RawFileSystem interface {
Lookup(header *raw.InHeader, name string) (out *raw.EntryOut, status Status) Lookup(out *raw.EntryOut, header *raw.InHeader, name string) (status Status)
Forget(nodeid, nlookup uint64) Forget(nodeid, nlookup uint64)
// Attributes. // Attributes.
GetAttr(header *raw.InHeader, input *raw.GetAttrIn) (out *raw.AttrOut, code Status) GetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.GetAttrIn) (code Status)
SetAttr(header *raw.InHeader, input *raw.SetAttrIn) (out *raw.AttrOut, code Status) SetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.SetAttrIn) (code Status)
// Modifying structure. // Modifying structure.
Mknod(header *raw.InHeader, input *raw.MknodIn, name string) (out *raw.EntryOut, code Status) Mknod(out *raw.EntryOut, header *raw.InHeader, input *raw.MknodIn, name string) (code Status)
Mkdir(header *raw.InHeader, input *raw.MkdirIn, name string) (out *raw.EntryOut, code Status) Mkdir(out *raw.EntryOut, header *raw.InHeader, input *raw.MkdirIn, name string) (code Status)
Unlink(header *raw.InHeader, name string) (code Status) Unlink(header *raw.InHeader, name string) (code Status)
Rmdir(header *raw.InHeader, name string) (code Status) Rmdir(header *raw.InHeader, name string) (code Status)
Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status)
Link(header *raw.InHeader, input *raw.LinkIn, filename string) (out *raw.EntryOut, code Status) Link(out *raw.EntryOut, header *raw.InHeader, input *raw.LinkIn, filename string) (code Status)
Symlink(header *raw.InHeader, pointedTo string, linkName string) (out *raw.EntryOut, code Status) Symlink(out *raw.EntryOut, header *raw.InHeader, pointedTo string, linkName string) (code Status)
Readlink(header *raw.InHeader) (out []byte, code Status) Readlink(header *raw.InHeader) (out []byte, code Status)
Access(header *raw.InHeader, input *raw.AccessIn) (code Status) Access(header *raw.InHeader, input *raw.AccessIn) (code Status)
...@@ -276,8 +276,8 @@ type RawFileSystem interface { ...@@ -276,8 +276,8 @@ type RawFileSystem interface {
RemoveXAttr(header *raw.InHeader, attr string) (code Status) RemoveXAttr(header *raw.InHeader, attr string) (code Status)
// File handling. // File handling.
Create(header *raw.InHeader, input *raw.CreateIn, name string) (flags uint32, handle uint64, out *raw.EntryOut, code Status) Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (code Status)
Open(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, status Status) Open(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status)
Read(*raw.InHeader, *ReadIn, BufferPool) ([]byte, Status) Read(*raw.InHeader, *ReadIn, BufferPool) ([]byte, Status)
Release(header *raw.InHeader, input *raw.ReleaseIn) Release(header *raw.InHeader, input *raw.ReleaseIn)
...@@ -286,14 +286,13 @@ type RawFileSystem interface { ...@@ -286,14 +286,13 @@ type RawFileSystem interface {
Fsync(*raw.InHeader, *raw.FsyncIn) (code Status) Fsync(*raw.InHeader, *raw.FsyncIn) (code Status)
// Directory handling // Directory handling
OpenDir(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, status Status) OpenDir(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status)
ReadDir(header *raw.InHeader, input *ReadIn) (*DirEntryList, Status) ReadDir(out *DirEntryList, header *raw.InHeader, input *ReadIn) (Status)
ReleaseDir(header *raw.InHeader, input *raw.ReleaseIn) ReleaseDir(header *raw.InHeader, input *raw.ReleaseIn)
FsyncDir(header *raw.InHeader, input *raw.FsyncIn) (code Status) FsyncDir(header *raw.InHeader, input *raw.FsyncIn) (code Status)
// //
Ioctl(header *raw.InHeader, input *raw.IoctlIn) (output *raw.IoctlOut, data []byte, code Status) StatFs(out *StatfsOut, eader *raw.InHeader) (code Status)
StatFs(header *raw.InHeader) *StatfsOut
// Provide callbacks for pushing notifications to the kernel. // Provide callbacks for pushing notifications to the kernel.
Init(params *RawFsInit) Init(params *RawFsInit)
......
...@@ -10,8 +10,6 @@ import ( ...@@ -10,8 +10,6 @@ import (
func TestRawFs(t *testing.T) { func TestRawFs(t *testing.T) {
var iface RawFileSystem var iface RawFileSystem
iface = new(DefaultRawFileSystem)
_ = iface _ = iface
} }
......
...@@ -4,42 +4,45 @@ import ( ...@@ -4,42 +4,45 @@ import (
"github.com/hanwen/go-fuse/raw" "github.com/hanwen/go-fuse/raw"
) )
var _ = RawFileSystem((*DefaultRawFileSystem)(nil))
func (fs *DefaultRawFileSystem) Init(init *RawFsInit) { func (fs *DefaultRawFileSystem) Init(init *RawFsInit) {
} }
func (fs *DefaultRawFileSystem) StatFs(h *raw.InHeader) *StatfsOut { func (fs *DefaultRawFileSystem) StatFs(out *StatfsOut, h *raw.InHeader) Status {
return nil return ENOSYS
} }
func (fs *DefaultRawFileSystem) Lookup(h *raw.InHeader, name string) (out *raw.EntryOut, code Status) { func (fs *DefaultRawFileSystem) Lookup(out *raw.EntryOut, h *raw.InHeader, name string) (code Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Forget(nodeID, nlookup uint64) { func (fs *DefaultRawFileSystem) Forget(nodeID, nlookup uint64) {
} }
func (fs *DefaultRawFileSystem) GetAttr(header *raw.InHeader, input *raw.GetAttrIn) (out *raw.AttrOut, code Status) { func (fs *DefaultRawFileSystem) GetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.GetAttrIn) (code Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Open(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, status Status) { func (fs *DefaultRawFileSystem) Open(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status) {
return 0, 0, OK return OK
} }
func (fs *DefaultRawFileSystem) SetAttr(header *raw.InHeader, input *raw.SetAttrIn) (out *raw.AttrOut, code Status) { func (fs *DefaultRawFileSystem) SetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.SetAttrIn) (code Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Readlink(header *raw.InHeader) (out []byte, code Status) { func (fs *DefaultRawFileSystem) Readlink(header *raw.InHeader) (out []byte, code Status) {
return nil, ENOSYS return nil, ENOSYS
} }
func (fs *DefaultRawFileSystem) Mknod(header *raw.InHeader, input *raw.MknodIn, name string) (out *raw.EntryOut, code Status) { func (fs *DefaultRawFileSystem) Mknod(out *raw.EntryOut, header *raw.InHeader, input *raw.MknodIn, name string) (code Status) {
return new(raw.EntryOut), ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Mkdir(header *raw.InHeader, input *raw.MkdirIn, name string) (out *raw.EntryOut, code Status) { func (fs *DefaultRawFileSystem) Mkdir(out *raw.EntryOut, header *raw.InHeader, input *raw.MkdirIn, name string) (code Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Unlink(header *raw.InHeader, name string) (code Status) { func (fs *DefaultRawFileSystem) Unlink(header *raw.InHeader, name string) (code Status) {
...@@ -50,16 +53,16 @@ func (fs *DefaultRawFileSystem) Rmdir(header *raw.InHeader, name string) (code S ...@@ -50,16 +53,16 @@ func (fs *DefaultRawFileSystem) Rmdir(header *raw.InHeader, name string) (code S
return ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Symlink(header *raw.InHeader, pointedTo string, linkName string) (out *raw.EntryOut, code Status) { func (fs *DefaultRawFileSystem) Symlink(out *raw.EntryOut, header *raw.InHeader, pointedTo string, linkName string) (code Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) { func (fs *DefaultRawFileSystem) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) {
return ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Link(header *raw.InHeader, input *raw.LinkIn, name string) (out *raw.EntryOut, code Status) { func (fs *DefaultRawFileSystem) Link(out *raw.EntryOut, header *raw.InHeader, input *raw.LinkIn, name string) (code Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) GetXAttrSize(header *raw.InHeader, attr string) (size int, code Status) { func (fs *DefaultRawFileSystem) GetXAttrSize(header *raw.InHeader, attr string) (size int, code Status) {
...@@ -86,20 +89,12 @@ func (fs *DefaultRawFileSystem) Access(header *raw.InHeader, input *raw.AccessIn ...@@ -86,20 +89,12 @@ func (fs *DefaultRawFileSystem) Access(header *raw.InHeader, input *raw.AccessIn
return ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Create(header *raw.InHeader, input *raw.CreateIn, name string) (flags uint32, handle uint64, out *raw.EntryOut, code Status) { func (fs *DefaultRawFileSystem) Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (code Status) {
return 0, 0, nil, ENOSYS return ENOSYS
}
func (fs *DefaultRawFileSystem) Bmap(header *raw.InHeader, input *raw.BmapIn) (out *raw.BmapOut, code Status) {
return nil, ENOSYS
}
func (fs *DefaultRawFileSystem) Poll(header *raw.InHeader, input *raw.PollIn) (out *raw.PollOut, code Status) {
return nil, ENOSYS
} }
func (fs *DefaultRawFileSystem) OpenDir(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, status Status) { func (fs *DefaultRawFileSystem) OpenDir(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status) {
return 0, 0, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Read(header *raw.InHeader, input *ReadIn, bp BufferPool) ([]byte, Status) { func (fs *DefaultRawFileSystem) Read(header *raw.InHeader, input *ReadIn, bp BufferPool) ([]byte, Status) {
...@@ -121,8 +116,8 @@ func (fs *DefaultRawFileSystem) Fsync(header *raw.InHeader, input *raw.FsyncIn) ...@@ -121,8 +116,8 @@ func (fs *DefaultRawFileSystem) Fsync(header *raw.InHeader, input *raw.FsyncIn)
return ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) ReadDir(header *raw.InHeader, input *ReadIn) (*DirEntryList, Status) { func (fs *DefaultRawFileSystem) ReadDir(l *DirEntryList, header *raw.InHeader, input *ReadIn) ( Status) {
return nil, ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) ReleaseDir(header *raw.InHeader, input *raw.ReleaseIn) { func (fs *DefaultRawFileSystem) ReleaseDir(header *raw.InHeader, input *raw.ReleaseIn) {
...@@ -131,7 +126,3 @@ func (fs *DefaultRawFileSystem) ReleaseDir(header *raw.InHeader, input *raw.Rele ...@@ -131,7 +126,3 @@ func (fs *DefaultRawFileSystem) ReleaseDir(header *raw.InHeader, input *raw.Rele
func (fs *DefaultRawFileSystem) FsyncDir(header *raw.InHeader, input *raw.FsyncIn) (code Status) { func (fs *DefaultRawFileSystem) FsyncDir(header *raw.InHeader, input *raw.FsyncIn) (code Status) {
return ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Ioctl(header *raw.InHeader, input *raw.IoctlIn) (output *raw.IoctlOut, data []byte, code Status) {
return nil, nil, ENOSYS
}
...@@ -74,7 +74,7 @@ func (l *DirEntryList) Bytes() []byte { ...@@ -74,7 +74,7 @@ func (l *DirEntryList) Bytes() []byte {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
type rawDir interface { type rawDir interface {
ReadDir(input *ReadIn) (*DirEntryList, Status) ReadDir(out *DirEntryList, input *ReadIn) (Status)
Release() Release()
} }
...@@ -84,30 +84,27 @@ type connectorDir struct { ...@@ -84,30 +84,27 @@ type connectorDir struct {
lastOffset uint64 lastOffset uint64
} }
func (d *connectorDir) ReadDir(input *ReadIn) (list *DirEntryList, code Status) { func (d *connectorDir) ReadDir(list *DirEntryList, input *ReadIn) (code Status) {
if d.stream == nil { if d.stream == nil {
return nil, OK return OK
} }
// rewinddir() should be as if reopening directory. // rewinddir() should be as if reopening directory.
// TODO - test this. // TODO - test this.
if d.lastOffset > 0 && input.Offset == 0 { if d.lastOffset > 0 && input.Offset == 0 {
d.stream, code = d.node.OpenDir(nil) d.stream, code = d.node.OpenDir(nil)
if !code.Ok() { if !code.Ok() {
return nil, code return code
} }
} }
off := input.Offset todo := d.stream[input.Offset:]
list = NewDirEntryList(int(input.Size), off)
todo := d.stream[off:]
for _, e := range todo { for _, e := range todo {
if !list.AddDirEntry(e) { if !list.AddDirEntry(e) {
break break
} }
} }
d.lastOffset = list.offset d.lastOffset = list.offset
return list, OK return OK
} }
// Read everything so we make goroutines exit. // Read everything so we make goroutines exit.
......
...@@ -79,9 +79,9 @@ func (c *FileSystemConnector) verify() { ...@@ -79,9 +79,9 @@ func (c *FileSystemConnector) verify() {
} }
// Generate EntryOut and increase the lookup count for an inode. // Generate EntryOut and increase the lookup count for an inode.
func (c *FileSystemConnector) childLookup(fi *raw.Attr, fsi FsNode) (out *raw.EntryOut) { func (c *FileSystemConnector) childLookup(out *raw.EntryOut, fi *raw.Attr, fsi FsNode) {
n := fsi.Inode() n := fsi.Inode()
out = n.mount.attrToEntry(fi) n.mount.attrToEntry(out, fi)
out.Ino = c.lookupUpdate(n) out.Ino = c.lookupUpdate(n)
out.NodeId = out.Ino out.NodeId = out.Ino
if out.Nlink == 0 { if out.Nlink == 0 {
...@@ -89,7 +89,6 @@ func (c *FileSystemConnector) childLookup(fi *raw.Attr, fsi FsNode) (out *raw.En ...@@ -89,7 +89,6 @@ func (c *FileSystemConnector) childLookup(fi *raw.Attr, fsi FsNode) (out *raw.En
// operations. // operations.
out.Nlink = 1 out.Nlink = 1
} }
return out
} }
func (c *FileSystemConnector) findMount(parent *Inode, name string) (mount *fileSystemMount) { func (c *FileSystemConnector) findMount(parent *Inode, name string) (mount *fileSystemMount) {
......
...@@ -61,8 +61,7 @@ func (m *fileSystemMount) setOwner(attr *raw.Attr) { ...@@ -61,8 +61,7 @@ func (m *fileSystemMount) setOwner(attr *raw.Attr) {
} }
} }
func (m *fileSystemMount) attrToEntry(attr *raw.Attr) (out *raw.EntryOut) { func (m *fileSystemMount) attrToEntry(out *raw.EntryOut, attr *raw.Attr) () {
out = &raw.EntryOut{}
out.Attr = *attr out.Attr = *attr
splitDuration(m.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec) splitDuration(m.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec)
...@@ -71,16 +70,13 @@ func (m *fileSystemMount) attrToEntry(attr *raw.Attr) (out *raw.EntryOut) { ...@@ -71,16 +70,13 @@ func (m *fileSystemMount) attrToEntry(attr *raw.Attr) (out *raw.EntryOut) {
if attr.Mode & S_IFDIR == 0 && attr.Nlink == 0 { if attr.Mode & S_IFDIR == 0 && attr.Nlink == 0 {
out.Nlink = 1 out.Nlink = 1
} }
return out
} }
func (m *fileSystemMount) fillAttr(a *raw.Attr, nodeId uint64) (out *raw.AttrOut) { func (m *fileSystemMount) fillAttr(out *raw.AttrOut, a *raw.Attr, nodeId uint64) {
out = &raw.AttrOut{}
out.Attr = *a out.Attr = *a
splitDuration(m.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec) splitDuration(m.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec)
m.setOwner(&out.Attr) m.setOwner(&out.Attr)
out.Ino = nodeId out.Ino = nodeId
return out
} }
func (m *fileSystemMount) getOpenedFile(h uint64) *openedFile { func (m *fileSystemMount) getOpenedFile(h uint64) *openedFile {
...@@ -143,12 +139,11 @@ func (m *fileSystemMount) registerFileHandle(node *Inode, dir rawDir, f File, fl ...@@ -143,12 +139,11 @@ func (m *fileSystemMount) registerFileHandle(node *Inode, dir rawDir, f File, fl
} }
// Creates a return entry for a non-existent path. // Creates a return entry for a non-existent path.
func (m *fileSystemMount) negativeEntry() (*raw.EntryOut, Status) { func (m *fileSystemMount) negativeEntry(out *raw.EntryOut) bool {
if m.options.NegativeTimeout > 0.0 { if m.options.NegativeTimeout > 0.0 {
out := new(raw.EntryOut)
out.NodeId = 0 out.NodeId = 0
splitDuration(m.options.NegativeTimeout, &out.EntryValid, &out.EntryValidNsec) splitDuration(m.options.NegativeTimeout, &out.EntryValid, &out.EntryValidNsec)
return out, OK return true
} }
return nil, ENOENT return false
} }
...@@ -53,31 +53,31 @@ func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context ...@@ -53,31 +53,31 @@ func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context
return fi, child, code return fi, child, code
} }
func (c *FileSystemConnector) Lookup(header *raw.InHeader, name string) (out *raw.EntryOut, code Status) { func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, name string) (code Status) {
parent := c.toInode(header.NodeId) parent := c.toInode(header.NodeId)
if !parent.IsDir() { if !parent.IsDir() {
log.Printf("Lookup %q called on non-Directory node %d", name, header.NodeId) log.Printf("Lookup %q called on non-Directory node %d", name, header.NodeId)
return nil, ENOTDIR return ENOTDIR
} }
context := (*Context)(&header.Context) context := (*Context)(&header.Context)
fi, child, code := c.internalLookup(parent, name, context) fi, child, code := c.internalLookup(parent, name, context)
if code == ENOENT && parent.mount.negativeEntry(out) {
return OK
}
if !code.Ok() { if !code.Ok() {
if code == ENOENT { return code
return parent.mount.negativeEntry()
}
return nil, code
} }
if child == nil { if child == nil {
log.Println("Lookup returned OK with nil child", name) log.Println("Lookup returned OK with nil child", name)
} }
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = child.mount.attrToEntry(rawAttr) child.mount.attrToEntry(out, rawAttr)
out.NodeId = c.lookupUpdate(child) out.NodeId = c.lookupUpdate(child)
out.Generation = 1 out.Generation = 1
out.Ino = out.NodeId out.Ino = out.NodeId
return out, OK return OK
} }
func (c *FileSystemConnector) Forget(nodeID, nlookup uint64) { func (c *FileSystemConnector) Forget(nodeID, nlookup uint64) {
...@@ -85,7 +85,7 @@ func (c *FileSystemConnector) Forget(nodeID, nlookup uint64) { ...@@ -85,7 +85,7 @@ func (c *FileSystemConnector) Forget(nodeID, nlookup uint64) {
c.forgetUpdate(node, int(nlookup)) c.forgetUpdate(node, int(nlookup))
} }
func (c *FileSystemConnector) GetAttr(header *raw.InHeader, input *raw.GetAttrIn) (out *raw.AttrOut, code Status) { func (c *FileSystemConnector) GetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.GetAttrIn) (code Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
var f File var f File
...@@ -97,20 +97,19 @@ func (c *FileSystemConnector) GetAttr(header *raw.InHeader, input *raw.GetAttrIn ...@@ -97,20 +97,19 @@ func (c *FileSystemConnector) GetAttr(header *raw.InHeader, input *raw.GetAttrIn
fi, code := node.fsInode.GetAttr(f, (*Context)(&header.Context)) fi, code := node.fsInode.GetAttr(f, (*Context)(&header.Context))
if !code.Ok() { if !code.Ok() {
return nil, code return code
} }
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = node.mount.fillAttr(rawAttr, header.NodeId) node.mount.fillAttr(out, rawAttr, header.NodeId)
return out, OK return OK
} }
func (c *FileSystemConnector) OpenDir(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, code Status) { func (c *FileSystemConnector) OpenDir(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (code Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
stream, err := node.fsInode.OpenDir((*Context)(&header.Context)) stream, err := node.fsInode.OpenDir((*Context)(&header.Context))
if err != OK { if err != OK {
return 0, 0, err return err
} }
stream = append(stream, node.getMountDirEntries()...) stream = append(stream, node.getMountDirEntries()...)
de := &connectorDir{ de := &connectorDir{
...@@ -118,30 +117,30 @@ func (c *FileSystemConnector) OpenDir(header *raw.InHeader, input *raw.OpenIn) ( ...@@ -118,30 +117,30 @@ func (c *FileSystemConnector) OpenDir(header *raw.InHeader, input *raw.OpenIn) (
stream: append(stream, DirEntry{S_IFDIR, "."}, DirEntry{S_IFDIR, ".."}), stream: append(stream, DirEntry{S_IFDIR, "."}, DirEntry{S_IFDIR, ".."}),
} }
h, opened := node.mount.registerFileHandle(node, de, nil, input.Flags) h, opened := node.mount.registerFileHandle(node, de, nil, input.Flags)
return opened.FuseFlags, h, OK out.OpenFlags = opened.FuseFlags
out.Fh = h
return OK
} }
func (c *FileSystemConnector) ReadDir(header *raw.InHeader, input *ReadIn) (*DirEntryList, Status) { func (c *FileSystemConnector) ReadDir(l *DirEntryList, header *raw.InHeader, input *ReadIn) (Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
opened := node.mount.getOpenedFile(input.Fh) opened := node.mount.getOpenedFile(input.Fh)
de, code := opened.dir.ReadDir(input) return opened.dir.ReadDir(l, input)
if code != OK {
return nil, code
}
return de, OK
} }
func (c *FileSystemConnector) Open(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, status Status) { func (c *FileSystemConnector) Open(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
f, code := node.fsInode.Open(input.Flags, (*Context)(&header.Context)) f, code := node.fsInode.Open(input.Flags, (*Context)(&header.Context))
if !code.Ok() { if !code.Ok() {
return 0, 0, code return code
} }
h, opened := node.mount.registerFileHandle(node, nil, f, input.Flags) h, opened := node.mount.registerFileHandle(node, nil, f, input.Flags)
return opened.FuseFlags, h, OK out.OpenFlags = opened.FuseFlags
out.Fh = h
return OK
} }
func (c *FileSystemConnector) SetAttr(header *raw.InHeader, input *raw.SetAttrIn) (out *raw.AttrOut, code Status) { func (c *FileSystemConnector) SetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.SetAttrIn) (code Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
var f File var f File
if input.Valid&raw.FATTR_FH != 0 { if input.Valid&raw.FATTR_FH != 0 {
...@@ -179,7 +178,7 @@ func (c *FileSystemConnector) SetAttr(header *raw.InHeader, input *raw.SetAttrIn ...@@ -179,7 +178,7 @@ func (c *FileSystemConnector) SetAttr(header *raw.InHeader, input *raw.SetAttrIn
} }
if !code.Ok() { if !code.Ok() {
return nil, code return code
} }
// Must call GetAttr(); the filesystem may override some of // Must call GetAttr(); the filesystem may override some of
...@@ -188,9 +187,9 @@ func (c *FileSystemConnector) SetAttr(header *raw.InHeader, input *raw.SetAttrIn ...@@ -188,9 +187,9 @@ func (c *FileSystemConnector) SetAttr(header *raw.InHeader, input *raw.SetAttrIn
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = node.mount.fillAttr(rawAttr, header.NodeId) node.mount.fillAttr(out, rawAttr, header.NodeId)
} }
return out, code return code
} }
func (c *FileSystemConnector) Readlink(header *raw.InHeader) (out []byte, code Status) { func (c *FileSystemConnector) Readlink(header *raw.InHeader) (out []byte, code Status) {
...@@ -198,25 +197,25 @@ func (c *FileSystemConnector) Readlink(header *raw.InHeader) (out []byte, code S ...@@ -198,25 +197,25 @@ func (c *FileSystemConnector) Readlink(header *raw.InHeader) (out []byte, code S
return n.fsInode.Readlink((*Context)(&header.Context)) return n.fsInode.Readlink((*Context)(&header.Context))
} }
func (c *FileSystemConnector) Mknod(header *raw.InHeader, input *raw.MknodIn, name string) (out *raw.EntryOut, code Status) { func (c *FileSystemConnector) Mknod(out *raw.EntryOut, header *raw.InHeader, input *raw.MknodIn, name string) (code Status) {
parent := c.toInode(header.NodeId) parent := c.toInode(header.NodeId)
fi, fsNode, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), (*Context)(&header.Context)) fi, fsNode, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), (*Context)(&header.Context))
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
if code.Ok() { if code.Ok() {
out = c.childLookup(rawAttr, fsNode) c.childLookup(out, rawAttr, fsNode)
} }
return out, code return code
} }
func (c *FileSystemConnector) Mkdir(header *raw.InHeader, input *raw.MkdirIn, name string) (out *raw.EntryOut, code Status) { func (c *FileSystemConnector) Mkdir(out *raw.EntryOut, header *raw.InHeader, input *raw.MkdirIn, name string) (code Status) {
parent := c.toInode(header.NodeId) parent := c.toInode(header.NodeId)
fi, fsInode, code := parent.fsInode.Mkdir(name, input.Mode, (*Context)(&header.Context)) fi, fsInode, code := parent.fsInode.Mkdir(name, input.Mode, (*Context)(&header.Context))
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = c.childLookup(rawAttr, fsInode) c.childLookup(out, rawAttr, fsInode)
} }
return out, code return code
} }
func (c *FileSystemConnector) Unlink(header *raw.InHeader, name string) (code Status) { func (c *FileSystemConnector) Unlink(header *raw.InHeader, name string) (code Status) {
...@@ -229,14 +228,14 @@ func (c *FileSystemConnector) Rmdir(header *raw.InHeader, name string) (code Sta ...@@ -229,14 +228,14 @@ func (c *FileSystemConnector) Rmdir(header *raw.InHeader, name string) (code Sta
return parent.fsInode.Rmdir(name, (*Context)(&header.Context)) return parent.fsInode.Rmdir(name, (*Context)(&header.Context))
} }
func (c *FileSystemConnector) Symlink(header *raw.InHeader, pointedTo string, linkName string) (out *raw.EntryOut, code Status) { func (c *FileSystemConnector) Symlink(out *raw.EntryOut, header *raw.InHeader, pointedTo string, linkName string) (code Status) {
parent := c.toInode(header.NodeId) parent := c.toInode(header.NodeId)
fi, fsNode, code := parent.fsInode.Symlink(linkName, pointedTo, (*Context)(&header.Context)) fi, fsNode, code := parent.fsInode.Symlink(linkName, pointedTo, (*Context)(&header.Context))
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = c.childLookup(rawAttr, fsNode) c.childLookup(out, rawAttr, fsNode)
} }
return out, code return code
} }
func (c *FileSystemConnector) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) { func (c *FileSystemConnector) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) {
...@@ -254,21 +253,21 @@ func (c *FileSystemConnector) Rename(header *raw.InHeader, input *raw.RenameIn, ...@@ -254,21 +253,21 @@ func (c *FileSystemConnector) Rename(header *raw.InHeader, input *raw.RenameIn,
return oldParent.fsInode.Rename(oldName, newParent.fsInode, newName, (*Context)(&header.Context)) return oldParent.fsInode.Rename(oldName, newParent.fsInode, newName, (*Context)(&header.Context))
} }
func (c *FileSystemConnector) Link(header *raw.InHeader, input *raw.LinkIn, name string) (out *raw.EntryOut, code Status) { func (c *FileSystemConnector) Link(out *raw.EntryOut, header *raw.InHeader, input *raw.LinkIn, name string) (code Status) {
existing := c.toInode(input.Oldnodeid) existing := c.toInode(input.Oldnodeid)
parent := c.toInode(header.NodeId) parent := c.toInode(header.NodeId)
if existing.mount != parent.mount { if existing.mount != parent.mount {
return nil, EXDEV return EXDEV
} }
fi, fsInode, code := parent.fsInode.Link(name, existing.fsInode, (*Context)(&header.Context)) fi, fsInode, code := parent.fsInode.Link(name, existing.fsInode, (*Context)(&header.Context))
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = c.childLookup(rawAttr, fsInode) c.childLookup(out, rawAttr, fsInode)
} }
return out, code return code
} }
func (c *FileSystemConnector) Access(header *raw.InHeader, input *raw.AccessIn) (code Status) { func (c *FileSystemConnector) Access(header *raw.InHeader, input *raw.AccessIn) (code Status) {
...@@ -276,16 +275,19 @@ func (c *FileSystemConnector) Access(header *raw.InHeader, input *raw.AccessIn) ...@@ -276,16 +275,19 @@ func (c *FileSystemConnector) Access(header *raw.InHeader, input *raw.AccessIn)
return n.fsInode.Access(input.Mask, (*Context)(&header.Context)) return n.fsInode.Access(input.Mask, (*Context)(&header.Context))
} }
func (c *FileSystemConnector) Create(header *raw.InHeader, input *raw.CreateIn, name string) (flags uint32, h uint64, out *raw.EntryOut, code Status) { func (c *FileSystemConnector) Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (code Status) {
parent := c.toInode(header.NodeId) parent := c.toInode(header.NodeId)
f, fi, fsNode, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, (*Context)(&header.Context)) f, fi, fsNode, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, (*Context)(&header.Context))
if !code.Ok() { if !code.Ok() {
return 0, 0, nil, code return code
} }
rawAttr := (*raw.Attr)(fi) rawAttr := (*raw.Attr)(fi)
out = c.childLookup(rawAttr, fsNode) c.childLookup(&out.EntryOut, rawAttr, fsNode)
handle, opened := parent.mount.registerFileHandle(fsNode.Inode(), nil, f, input.Flags) handle, opened := parent.mount.registerFileHandle(fsNode.Inode(), nil, f, input.Flags)
return opened.FuseFlags, handle, out, code
out.OpenOut.OpenFlags = opened.FuseFlags
out.OpenOut.Fh = handle
return code
} }
func (c *FileSystemConnector) Release(header *raw.InHeader, input *raw.ReleaseIn) { func (c *FileSystemConnector) Release(header *raw.InHeader, input *raw.ReleaseIn) {
...@@ -352,9 +354,14 @@ func (c *FileSystemConnector) Read(header *raw.InHeader, input *ReadIn, bp Buffe ...@@ -352,9 +354,14 @@ func (c *FileSystemConnector) Read(header *raw.InHeader, input *ReadIn, bp Buffe
return opened.WithFlags.File.Read(input, bp) return opened.WithFlags.File.Read(input, bp)
} }
func (c *FileSystemConnector) StatFs(header *raw.InHeader) *StatfsOut { func (c *FileSystemConnector) StatFs(out *StatfsOut, header *raw.InHeader) Status {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
return node.FsNode().StatFs() s := node.FsNode().StatFs()
if s == nil {
return ENOSYS
}
*out = *s
return OK
} }
func (c *FileSystemConnector) Flush(header *raw.InHeader, input *raw.FlushIn) Status { func (c *FileSystemConnector) Flush(header *raw.InHeader, input *raw.FlushIn) Status {
......
...@@ -160,9 +160,9 @@ func NewLockingRawFileSystem(rfs RawFileSystem) *LockingRawFileSystem { ...@@ -160,9 +160,9 @@ func NewLockingRawFileSystem(rfs RawFileSystem) *LockingRawFileSystem {
return l return l
} }
func (fs *LockingRawFileSystem) Lookup(h *raw.InHeader, name string) (out *raw.EntryOut, code Status) { func (fs *LockingRawFileSystem) Lookup(out *raw.EntryOut, h *raw.InHeader, name string) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Lookup(h, name) return fs.RawFileSystem.Lookup(out, h, name)
} }
func (fs *LockingRawFileSystem) Forget(nodeID uint64, nlookup uint64) { func (fs *LockingRawFileSystem) Forget(nodeID uint64, nlookup uint64) {
...@@ -170,19 +170,20 @@ func (fs *LockingRawFileSystem) Forget(nodeID uint64, nlookup uint64) { ...@@ -170,19 +170,20 @@ func (fs *LockingRawFileSystem) Forget(nodeID uint64, nlookup uint64) {
fs.RawFileSystem.Forget(nodeID, nlookup) fs.RawFileSystem.Forget(nodeID, nlookup)
} }
func (fs *LockingRawFileSystem) GetAttr(header *raw.InHeader, input *raw.GetAttrIn) (out *raw.AttrOut, code Status) { func (fs *LockingRawFileSystem) GetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.GetAttrIn) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.GetAttr(header, input) return fs.RawFileSystem.GetAttr(out, header, input)
} }
func (fs *LockingRawFileSystem) Open(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, status Status) { func (fs *LockingRawFileSystem) Open(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Open(header, input) return fs.RawFileSystem.Open(out, header, input)
} }
func (fs *LockingRawFileSystem) SetAttr(header *raw.InHeader, input *raw.SetAttrIn) (out *raw.AttrOut, code Status) { func (fs *LockingRawFileSystem) SetAttr(out *raw.AttrOut, header *raw.InHeader, input *raw.SetAttrIn) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.SetAttr(header, input) return fs.RawFileSystem.SetAttr(out, header, input)
} }
func (fs *LockingRawFileSystem) Readlink(header *raw.InHeader) (out []byte, code Status) { func (fs *LockingRawFileSystem) Readlink(header *raw.InHeader) (out []byte, code Status) {
...@@ -190,14 +191,14 @@ func (fs *LockingRawFileSystem) Readlink(header *raw.InHeader) (out []byte, code ...@@ -190,14 +191,14 @@ func (fs *LockingRawFileSystem) Readlink(header *raw.InHeader) (out []byte, code
return fs.RawFileSystem.Readlink(header) return fs.RawFileSystem.Readlink(header)
} }
func (fs *LockingRawFileSystem) Mknod(header *raw.InHeader, input *raw.MknodIn, name string) (out *raw.EntryOut, code Status) { func (fs *LockingRawFileSystem) Mknod(out *raw.EntryOut, header *raw.InHeader, input *raw.MknodIn, name string) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Mknod(header, input, name) return fs.RawFileSystem.Mknod(out, header, input, name)
} }
func (fs *LockingRawFileSystem) Mkdir(header *raw.InHeader, input *raw.MkdirIn, name string) (out *raw.EntryOut, code Status) { func (fs *LockingRawFileSystem) Mkdir(out *raw.EntryOut, header *raw.InHeader, input *raw.MkdirIn, name string) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Mkdir(header, input, name) return fs.RawFileSystem.Mkdir(out, header, input, name)
} }
func (fs *LockingRawFileSystem) Unlink(header *raw.InHeader, name string) (code Status) { func (fs *LockingRawFileSystem) Unlink(header *raw.InHeader, name string) (code Status) {
...@@ -210,9 +211,9 @@ func (fs *LockingRawFileSystem) Rmdir(header *raw.InHeader, name string) (code S ...@@ -210,9 +211,9 @@ func (fs *LockingRawFileSystem) Rmdir(header *raw.InHeader, name string) (code S
return fs.RawFileSystem.Rmdir(header, name) return fs.RawFileSystem.Rmdir(header, name)
} }
func (fs *LockingRawFileSystem) Symlink(header *raw.InHeader, pointedTo string, linkName string) (out *raw.EntryOut, code Status) { func (fs *LockingRawFileSystem) Symlink(out *raw.EntryOut, header *raw.InHeader, pointedTo string, linkName string) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Symlink(header, pointedTo, linkName) return fs.RawFileSystem.Symlink(out, header, pointedTo, linkName)
} }
func (fs *LockingRawFileSystem) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) { func (fs *LockingRawFileSystem) Rename(header *raw.InHeader, input *raw.RenameIn, oldName string, newName string) (code Status) {
...@@ -220,9 +221,9 @@ func (fs *LockingRawFileSystem) Rename(header *raw.InHeader, input *raw.RenameIn ...@@ -220,9 +221,9 @@ func (fs *LockingRawFileSystem) Rename(header *raw.InHeader, input *raw.RenameIn
return fs.RawFileSystem.Rename(header, input, oldName, newName) return fs.RawFileSystem.Rename(header, input, oldName, newName)
} }
func (fs *LockingRawFileSystem) Link(header *raw.InHeader, input *raw.LinkIn, name string) (out *raw.EntryOut, code Status) { func (fs *LockingRawFileSystem) Link(out *raw.EntryOut, header *raw.InHeader, input *raw.LinkIn, name string) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Link(header, input, name) return fs.RawFileSystem.Link(out, header, input, name)
} }
func (fs *LockingRawFileSystem) SetXAttr(header *raw.InHeader, input *raw.SetXAttrIn, attr string, data []byte) Status { func (fs *LockingRawFileSystem) SetXAttr(header *raw.InHeader, input *raw.SetXAttrIn, attr string, data []byte) Status {
...@@ -255,14 +256,14 @@ func (fs *LockingRawFileSystem) Access(header *raw.InHeader, input *raw.AccessIn ...@@ -255,14 +256,14 @@ func (fs *LockingRawFileSystem) Access(header *raw.InHeader, input *raw.AccessIn
return fs.RawFileSystem.Access(header, input) return fs.RawFileSystem.Access(header, input)
} }
func (fs *LockingRawFileSystem) Create(header *raw.InHeader, input *raw.CreateIn, name string) (flags uint32, handle uint64, out *raw.EntryOut, code Status) { func (fs *LockingRawFileSystem) Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (code Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Create(header, input, name) return fs.RawFileSystem.Create(out, header, input, name)
} }
func (fs *LockingRawFileSystem) OpenDir(header *raw.InHeader, input *raw.OpenIn) (flags uint32, h uint64, status Status) { func (fs *LockingRawFileSystem) OpenDir(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.OpenDir(header, input) return fs.RawFileSystem.OpenDir(out, header, input)
} }
func (fs *LockingRawFileSystem) Release(header *raw.InHeader, input *raw.ReleaseIn) { func (fs *LockingRawFileSystem) Release(header *raw.InHeader, input *raw.ReleaseIn) {
...@@ -295,9 +296,9 @@ func (fs *LockingRawFileSystem) Fsync(header *raw.InHeader, input *raw.FsyncIn) ...@@ -295,9 +296,9 @@ func (fs *LockingRawFileSystem) Fsync(header *raw.InHeader, input *raw.FsyncIn)
return fs.RawFileSystem.Fsync(header, input) return fs.RawFileSystem.Fsync(header, input)
} }
func (fs *LockingRawFileSystem) ReadDir(header *raw.InHeader, input *ReadIn) (*DirEntryList, Status) { func (fs *LockingRawFileSystem) ReadDir(out *DirEntryList, header *raw.InHeader, input *ReadIn) (Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.ReadDir(header, input) return fs.RawFileSystem.ReadDir(out, header, input)
} }
func (fs *LockingRawFileSystem) FsyncDir(header *raw.InHeader, input *raw.FsyncIn) (code Status) { func (fs *LockingRawFileSystem) FsyncDir(header *raw.InHeader, input *raw.FsyncIn) (code Status) {
......
...@@ -103,36 +103,25 @@ func doInit(state *MountState, req *request) { ...@@ -103,36 +103,25 @@ func doInit(state *MountState, req *request) {
} }
func doOpen(state *MountState, req *request) { func doOpen(state *MountState, req *request) {
flags, handle, status := state.fileSystem.Open(req.inHeader, (*raw.OpenIn)(req.inData)) out := (*raw.OpenOut)(req.outData)
status := state.fileSystem.Open(out, req.inHeader, (*raw.OpenIn)(req.inData))
req.status = status req.status = status
if status != OK { if status != OK {
return return
} }
out := &raw.OpenOut{
Fh: handle,
OpenFlags: flags,
}
req.outData = unsafe.Pointer(out)
} }
func doCreate(state *MountState, req *request) { func doCreate(state *MountState, req *request) {
flags, handle, entry, status := state.fileSystem.Create(req.inHeader, (*raw.CreateIn)(req.inData), req.filenames[0]) out := (*raw.CreateOut)(req.outData)
status := state.fileSystem.Create(out, req.inHeader, (*raw.CreateIn)(req.inData), req.filenames[0])
req.status = status req.status = status
if status.Ok() {
req.outData = unsafe.Pointer(&raw.CreateOut{
raw.EntryOut: *entry,
raw.OpenOut: raw.OpenOut{
Fh: handle,
OpenFlags: flags,
},
})
}
} }
func doReadDir(state *MountState, req *request) { func doReadDir(state *MountState, req *request) {
entries, code := state.fileSystem.ReadDir(req.inHeader, (*ReadIn)(req.inData)) in := (*ReadIn)(req.inData)
entries := NewDirEntryList(int(in.Size), uint64(in.Offset))
code := state.fileSystem.ReadDir(entries, req.inHeader, in)
if entries != nil { if entries != nil {
req.flatData = entries.Bytes() req.flatData = entries.Bytes()
} }
...@@ -140,28 +129,20 @@ func doReadDir(state *MountState, req *request) { ...@@ -140,28 +129,20 @@ func doReadDir(state *MountState, req *request) {
} }
func doOpenDir(state *MountState, req *request) { func doOpenDir(state *MountState, req *request) {
flags, handle, status := state.fileSystem.OpenDir(req.inHeader, (*raw.OpenIn)(req.inData)) out := (*raw.OpenOut)(req.outData)
status := state.fileSystem.OpenDir(out, req.inHeader, (*raw.OpenIn)(req.inData))
req.status = status req.status = status
if status.Ok() {
req.outData = unsafe.Pointer(&raw.OpenOut{
Fh: handle,
OpenFlags: flags,
})
}
} }
func doSetattr(state *MountState, req *request) { func doSetattr(state *MountState, req *request) {
o, s := state.fileSystem.SetAttr(req.inHeader, (*raw.SetAttrIn)(req.inData)) out := (*raw.AttrOut)(req.outData)
req.outData = unsafe.Pointer(o) req.status = state.fileSystem.SetAttr(out, req.inHeader, (*raw.SetAttrIn)(req.inData))
req.status = s
} }
func doWrite(state *MountState, req *request) { func doWrite(state *MountState, req *request) {
n, status := state.fileSystem.Write(req.inHeader, (*WriteIn)(req.inData), req.arg) n, status := state.fileSystem.Write(req.inHeader, (*WriteIn)(req.inData), req.arg)
o := &raw.WriteOut{ o := (*raw.WriteOut)(req.outData)
Size: n, o.Size = n
}
req.outData = unsafe.Pointer(o)
req.status = status req.status = status
} }
...@@ -183,19 +164,19 @@ func doGetXAttr(state *MountState, req *request) { ...@@ -183,19 +164,19 @@ func doGetXAttr(state *MountState, req *request) {
var data []byte var data []byte
switch { switch {
case req.inHeader.Opcode == _OP_GETXATTR && input.Size == 0: case req.inHeader.Opcode == _OP_GETXATTR && input.Size == 0:
out := (*raw.GetXAttrOut)(req.outData)
sz, code := state.fileSystem.GetXAttrSize(req.inHeader, req.filenames[0]) sz, code := state.fileSystem.GetXAttrSize(req.inHeader, req.filenames[0])
if code.Ok() { if code.Ok() {
out := &raw.GetXAttrOut{ out.Size = uint32(sz)
Size: uint32(sz),
}
req.outData = unsafe.Pointer(out)
req.status = ERANGE req.status = ERANGE
return return
} }
req.status = code req.status = code
case req.inHeader.Opcode == _OP_GETXATTR: case req.inHeader.Opcode == _OP_GETXATTR:
req.outData = nil
data, req.status = state.fileSystem.GetXAttrData(req.inHeader, req.filenames[0]) data, req.status = state.fileSystem.GetXAttrData(req.inHeader, req.filenames[0])
default: default:
req.outData = nil
data, req.status = state.fileSystem.ListXAttr(req.inHeader) data, req.status = state.fileSystem.ListXAttr(req.inHeader)
} }
...@@ -211,9 +192,9 @@ func doGetXAttr(state *MountState, req *request) { ...@@ -211,9 +192,9 @@ func doGetXAttr(state *MountState, req *request) {
} }
func doGetAttr(state *MountState, req *request) { func doGetAttr(state *MountState, req *request) {
attrOut, s := state.fileSystem.GetAttr(req.inHeader, (*raw.GetAttrIn)(req.inData)) attrOut := (*raw.AttrOut)(req.outData)
s := state.fileSystem.GetAttr(attrOut, req.inHeader, (*raw.GetAttrIn)(req.inData))
req.status = s req.status = s
req.outData = unsafe.Pointer(attrOut)
} }
func doForget(state *MountState, req *request) { func doForget(state *MountState, req *request) {
...@@ -242,21 +223,21 @@ func doReadlink(state *MountState, req *request) { ...@@ -242,21 +223,21 @@ func doReadlink(state *MountState, req *request) {
} }
func doLookup(state *MountState, req *request) { func doLookup(state *MountState, req *request) {
lookupOut, s := state.fileSystem.Lookup(req.inHeader, req.filenames[0]) lookupOut := (*raw.EntryOut)(req.outData)
s := state.fileSystem.Lookup(lookupOut, req.inHeader, req.filenames[0])
req.status = s req.status = s
req.outData = unsafe.Pointer(lookupOut) req.outData = unsafe.Pointer(lookupOut)
} }
func doMknod(state *MountState, req *request) { func doMknod(state *MountState, req *request) {
entryOut, s := state.fileSystem.Mknod(req.inHeader, (*raw.MknodIn)(req.inData), req.filenames[0]) out := (*raw.EntryOut)(req.outData)
req.status = s
req.outData = unsafe.Pointer(entryOut) req.status = state.fileSystem.Mknod(out, req.inHeader, (*raw.MknodIn)(req.inData), req.filenames[0])
} }
func doMkdir(state *MountState, req *request) { func doMkdir(state *MountState, req *request) {
entryOut, s := state.fileSystem.Mkdir(req.inHeader, (*raw.MkdirIn)(req.inData), req.filenames[0]) out := (*raw.EntryOut)(req.outData)
req.status = s req.status = state.fileSystem.Mkdir(out, req.inHeader, (*raw.MkdirIn)(req.inData), req.filenames[0])
req.outData = unsafe.Pointer(entryOut)
} }
func doUnlink(state *MountState, req *request) { func doUnlink(state *MountState, req *request) {
...@@ -268,9 +249,8 @@ func doRmdir(state *MountState, req *request) { ...@@ -268,9 +249,8 @@ func doRmdir(state *MountState, req *request) {
} }
func doLink(state *MountState, req *request) { func doLink(state *MountState, req *request) {
entryOut, s := state.fileSystem.Link(req.inHeader, (*raw.LinkIn)(req.inData), req.filenames[0]) out := (*raw.EntryOut)(req.outData)
req.status = s req.status = state.fileSystem.Link(out, req.inHeader, (*raw.LinkIn)(req.inData), req.filenames[0])
req.outData = unsafe.Pointer(entryOut)
} }
func doRead(state *MountState, req *request) { func doRead(state *MountState, req *request) {
...@@ -311,9 +291,8 @@ func doAccess(state *MountState, req *request) { ...@@ -311,9 +291,8 @@ func doAccess(state *MountState, req *request) {
} }
func doSymlink(state *MountState, req *request) { func doSymlink(state *MountState, req *request) {
entryOut, s := state.fileSystem.Symlink(req.inHeader, req.filenames[1], req.filenames[0]) out := (*raw.EntryOut)(req.outData)
req.status = s req.status = state.fileSystem.Symlink(out, req.inHeader, req.filenames[1], req.filenames[0])
req.outData = unsafe.Pointer(entryOut)
} }
func doRename(state *MountState, req *request) { func doRename(state *MountState, req *request) {
...@@ -321,20 +300,8 @@ func doRename(state *MountState, req *request) { ...@@ -321,20 +300,8 @@ func doRename(state *MountState, req *request) {
} }
func doStatFs(state *MountState, req *request) { func doStatFs(state *MountState, req *request) {
stat := state.fileSystem.StatFs(req.inHeader) stat := (*StatfsOut)(req.outData)
if stat != nil { req.status = state.fileSystem.StatFs(stat, req.inHeader)
req.outData = unsafe.Pointer(stat)
req.status = OK
} else {
req.status = ENOSYS
}
}
func doIoctl(state *MountState, req *request) {
out, data, stat := state.fileSystem.Ioctl(req.inHeader, (*raw.IoctlIn)(req.inData))
req.outData = unsafe.Pointer(out)
req.flatData = data
req.status = stat
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
...@@ -517,7 +484,6 @@ func init() { ...@@ -517,7 +484,6 @@ func init() {
_OP_SYMLINK: doSymlink, _OP_SYMLINK: doSymlink,
_OP_RENAME: doRename, _OP_RENAME: doRename,
_OP_STATFS: doStatFs, _OP_STATFS: doStatFs,
_OP_IOCTL: doIoctl,
} { } {
operationHandlers[op].Func = v operationHandlers[op].Func = v
} }
......
...@@ -10,6 +10,9 @@ import ( ...@@ -10,6 +10,9 @@ import (
"github.com/hanwen/go-fuse/raw" "github.com/hanwen/go-fuse/raw"
) )
var sizeOfOutHeader = unsafe.Sizeof(raw.OutHeader{})
var zeroOutBuf [160]byte
func (req *request) Discard() { func (req *request) Discard() {
req.pool.FreeBuffer(req.flatData) req.pool.FreeBuffer(req.flatData)
req.pool.FreeBuffer(req.bufferPoolInputBuf) req.pool.FreeBuffer(req.bufferPoolInputBuf)
...@@ -158,6 +161,9 @@ func (r *request) parse() { ...@@ -158,6 +161,9 @@ func (r *request) parse() {
} }
} }
} }
r.outBuf = zeroOutBuf
r.outData = unsafe.Pointer(&r.outBuf[sizeOfOutHeader])
} }
func (r *request) serialize() (header []byte, data []byte) { func (r *request) serialize() (header []byte, data []byte) {
...@@ -177,3 +183,4 @@ func (r *request) serialize() (header []byte, data []byte) { ...@@ -177,3 +183,4 @@ func (r *request) serialize() (header []byte, data []byte) {
copy(header[sizeOfOutHeader:], asSlice(r.outData, dataLength)) copy(header[sizeOfOutHeader:], asSlice(r.outData, dataLength))
return header, r.flatData return header, r.flatData
} }
...@@ -12,6 +12,12 @@ import ( ...@@ -12,6 +12,12 @@ import (
var _ = log.Print var _ = log.Print
var xattrGolden = map[string][]byte{
"user.attr1": []byte("val1"),
"user.attr2": []byte("val2")}
var xattrFilename = "filename"
type XAttrTestFs struct { type XAttrTestFs struct {
tester *testing.T tester *testing.T
filename string filename string
...@@ -92,13 +98,8 @@ func readXAttr(p, a string) (val []byte, errno int) { ...@@ -92,13 +98,8 @@ func readXAttr(p, a string) (val []byte, errno int) {
return GetXAttr(p, a, val) return GetXAttr(p, a, val)
} }
func TestXAttrRead(t *testing.T) { func xattrTestCase(t *testing.T, nm string) (mountPoint string, cleanup func()) {
nm := "filename" xfs := NewXAttrFs(nm, xattrGolden)
golden := map[string][]byte{
"user.attr1": []byte("val1"),
"user.attr2": []byte("val2")}
xfs := NewXAttrFs(nm, golden)
xfs.tester = t xfs.tester = t
mountPoint, err := ioutil.TempDir("", "go-fuse") mountPoint, err := ioutil.TempDir("", "go-fuse")
CheckSuccess(err) CheckSuccess(err)
...@@ -108,12 +109,18 @@ func TestXAttrRead(t *testing.T) { ...@@ -108,12 +109,18 @@ func TestXAttrRead(t *testing.T) {
state, _, err := MountNodeFileSystem(mountPoint, nfs, nil) state, _, err := MountNodeFileSystem(mountPoint, nfs, nil)
CheckSuccess(err) CheckSuccess(err)
state.Debug = VerboseTest() state.Debug = VerboseTest()
defer state.Unmount()
go state.Loop() go state.Loop()
return mountPoint, func() { state.Unmount() }
}
func TestXAttrNoExist(t *testing.T) {
nm := xattrFilename
mountPoint, clean := xattrTestCase(t, nm)
defer clean()
mounted := filepath.Join(mountPoint, nm) mounted := filepath.Join(mountPoint, nm)
_, err = os.Lstat(mounted) _, err := os.Lstat(mounted)
if err != nil { if err != nil {
t.Error("Unexpected stat error", err) t.Error("Unexpected stat error", err)
} }
...@@ -122,27 +129,34 @@ func TestXAttrRead(t *testing.T) { ...@@ -122,27 +129,34 @@ func TestXAttrRead(t *testing.T) {
if errno == 0 { if errno == 0 {
t.Error("Expected GetXAttr error", val) t.Error("Expected GetXAttr error", val)
} }
}
func TestXAttrRead(t *testing.T) {
nm := xattrFilename
mountPoint, clean := xattrTestCase(t, nm)
defer clean()
mounted := filepath.Join(mountPoint, nm)
attrs, errno := ListXAttr(mounted) attrs, errno := ListXAttr(mounted)
readback := make(map[string][]byte) readback := make(map[string][]byte)
if errno != 0 { if errno != 0 {
t.Error("Unexpected ListXAttr error", errno) t.Error("Unexpected ListXAttr error", errno)
} else { } else {
for _, a := range attrs { for _, a := range attrs {
val, errno = readXAttr(mounted, a) val, errno := readXAttr(mounted, a)
if errno != 0 { if errno != 0 {
t.Error("Unexpected GetXAttr error", syscall.Errno(errno)) t.Errorf("GetXAttr(%q) failed: %v", a, syscall.Errno(errno))
} }
readback[a] = val readback[a] = val
} }
} }
if len(readback) != len(golden) { if len(readback) != len(xattrGolden) {
t.Error("length mismatch", golden, readback) t.Error("length mismatch", xattrGolden, readback)
} else { } else {
for k, v := range readback { for k, v := range readback {
if bytes.Compare(golden[k], v) != 0 { if bytes.Compare(xattrGolden[k], v) != 0 {
t.Error("val mismatch", k, v, golden[k]) t.Error("val mismatch", k, v, xattrGolden[k])
} }
} }
} }
...@@ -151,7 +165,7 @@ func TestXAttrRead(t *testing.T) { ...@@ -151,7 +165,7 @@ func TestXAttrRead(t *testing.T) {
if errno != 0 { if errno != 0 {
t.Error("Setxattr error", errno) t.Error("Setxattr error", errno)
} }
val, errno = readXAttr(mounted, "third") val, errno := readXAttr(mounted, "third")
if errno != 0 || string(val) != "value" { if errno != 0 || string(val) != "value" {
t.Error("Read back set xattr:", errno, string(val)) t.Error("Read back set xattr:", errno, string(val))
} }
......
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