Commit 83e93502 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Pass destination to FsNode.GetAttr() as argument.

Drop fuse.Attr return from Create, Mkdir, Mknod, Symlink, Link return.
parent ff2a5cbc
...@@ -31,7 +31,7 @@ type FsNode interface { ...@@ -31,7 +31,7 @@ type FsNode interface {
Inode() *Inode Inode() *Inode
SetInode(node *Inode) SetInode(node *Inode)
Lookup(name string, context *Context) (fi *Attr, node FsNode, code Status) Lookup(out *Attr, name string, context *Context) (node FsNode, code Status)
// Deletable() should return true if this inode may be // Deletable() should return true if this inode may be
// discarded from the children list. This will be called from // discarded from the children list. This will be called from
...@@ -48,16 +48,16 @@ type FsNode interface { ...@@ -48,16 +48,16 @@ type FsNode interface {
Readlink(c *Context) ([]byte, Status) Readlink(c *Context) ([]byte, Status)
// Namespace operations // Namespace operations
Mknod(name string, mode uint32, dev uint32, context *Context) (fi *Attr, newNode FsNode, code Status) Mknod(name string, mode uint32, dev uint32, context *Context) (newNode FsNode, code Status)
Mkdir(name string, mode uint32, context *Context) (fi *Attr, newNode FsNode, code Status) Mkdir(name string, mode uint32, context *Context) (newNode FsNode, code Status)
Unlink(name string, context *Context) (code Status) Unlink(name string, context *Context) (code Status)
Rmdir(name string, context *Context) (code Status) Rmdir(name string, context *Context) (code Status)
Symlink(name string, content string, context *Context) (fi *Attr, newNode FsNode, code Status) Symlink(name string, content string, context *Context) (newNode FsNode, code Status)
Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status) Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status)
Link(name string, existing FsNode, context *Context) (fi *Attr, newNode FsNode, code Status) Link(name string, existing FsNode, context *Context) (newNode FsNode, code Status)
// Files // Files
Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *Attr, newNode FsNode, code Status) Create(name string, flags uint32, mode uint32, context *Context) (file File, newNode FsNode, code Status)
Open(flags uint32, context *Context) (file File, code Status) Open(flags uint32, context *Context) (file File, code Status)
OpenDir(context *Context) ([]DirEntry, Status) OpenDir(context *Context) ([]DirEntry, Status)
...@@ -68,7 +68,7 @@ type FsNode interface { ...@@ -68,7 +68,7 @@ type FsNode interface {
ListXAttr(context *Context) (attrs []string, code Status) ListXAttr(context *Context) (attrs []string, code Status)
// Attributes // Attributes
GetAttr(file File, context *Context) (fi *Attr, code Status) GetAttr(out *Attr, file File, context *Context) (code Status)
Chmod(file File, perms uint32, context *Context) (code Status) Chmod(file File, perms uint32, context *Context) (code Status)
Chown(file File, uid uint32, gid uint32, context *Context) (code Status) Chown(file File, uid uint32, gid uint32, context *Context) (code Status)
Truncate(file File, size uint64, context *Context) (code Status) Truncate(file File, size uint64, context *Context) (code Status)
......
...@@ -31,6 +31,8 @@ type DefaultFsNode struct { ...@@ -31,6 +31,8 @@ type DefaultFsNode struct {
inode *Inode inode *Inode
} }
var _ = FsNode((*DefaultFsNode)(nil))
func (n *DefaultFsNode) StatFs() *StatfsOut { func (n *DefaultFsNode) StatFs() *StatfsOut {
return nil return nil
} }
...@@ -56,8 +58,8 @@ func (n *DefaultFsNode) Inode() *Inode { ...@@ -56,8 +58,8 @@ func (n *DefaultFsNode) Inode() *Inode {
func (n *DefaultFsNode) OnForget() { func (n *DefaultFsNode) OnForget() {
} }
func (n *DefaultFsNode) Lookup(name string, context *Context) (fi *Attr, node FsNode, code Status) { func (n *DefaultFsNode) Lookup(out *Attr, name string, context *Context) (node FsNode, code Status) {
return nil, nil, ENOENT return nil, ENOENT
} }
func (n *DefaultFsNode) Access(mode uint32, context *Context) (code Status) { func (n *DefaultFsNode) Access(mode uint32, context *Context) (code Status) {
...@@ -68,11 +70,11 @@ func (n *DefaultFsNode) Readlink(c *Context) ([]byte, Status) { ...@@ -68,11 +70,11 @@ func (n *DefaultFsNode) Readlink(c *Context) ([]byte, Status) {
return nil, ENOSYS return nil, ENOSYS
} }
func (n *DefaultFsNode) Mknod(name string, mode uint32, dev uint32, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *DefaultFsNode) Mknod(name string, mode uint32, dev uint32, context *Context) (newNode FsNode, code Status) {
return nil, nil, ENOSYS return nil, ENOSYS
} }
func (n *DefaultFsNode) Mkdir(name string, mode uint32, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *DefaultFsNode) Mkdir(name string, mode uint32, context *Context) (newNode FsNode, code Status) {
return nil, nil, ENOSYS return nil, ENOSYS
} }
func (n *DefaultFsNode) Unlink(name string, context *Context) (code Status) { func (n *DefaultFsNode) Unlink(name string, context *Context) (code Status) {
return ENOSYS return ENOSYS
...@@ -80,20 +82,20 @@ func (n *DefaultFsNode) Unlink(name string, context *Context) (code Status) { ...@@ -80,20 +82,20 @@ func (n *DefaultFsNode) Unlink(name string, context *Context) (code Status) {
func (n *DefaultFsNode) Rmdir(name string, context *Context) (code Status) { func (n *DefaultFsNode) Rmdir(name string, context *Context) (code Status) {
return ENOSYS return ENOSYS
} }
func (n *DefaultFsNode) Symlink(name string, content string, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *DefaultFsNode) Symlink(name string, content string, context *Context) (newNode FsNode, code Status) {
return nil, nil, ENOSYS return nil, ENOSYS
} }
func (n *DefaultFsNode) Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status) { func (n *DefaultFsNode) Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status) {
return ENOSYS return ENOSYS
} }
func (n *DefaultFsNode) Link(name string, existing FsNode, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *DefaultFsNode) Link(name string, existing FsNode, context *Context) (newNode FsNode, code Status) {
return nil, nil, ENOSYS return nil, ENOSYS
} }
func (n *DefaultFsNode) Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *Attr, newNode FsNode, code Status) { func (n *DefaultFsNode) Create(name string, flags uint32, mode uint32, context *Context) (file File, newNode FsNode, code Status) {
return nil, nil, nil, ENOSYS return nil, nil, ENOSYS
} }
func (n *DefaultFsNode) Open(flags uint32, context *Context) (file File, code Status) { func (n *DefaultFsNode) Open(flags uint32, context *Context) (file File, code Status) {
...@@ -108,9 +110,10 @@ func (n *DefaultFsNode) OpenDir(context *Context) ([]DirEntry, Status) { ...@@ -108,9 +110,10 @@ func (n *DefaultFsNode) OpenDir(context *Context) ([]DirEntry, Status) {
ch := n.Inode().Children() ch := n.Inode().Children()
s := make([]DirEntry, 0, len(ch)) s := make([]DirEntry, 0, len(ch))
for name, child := range ch { for name, child := range ch {
fi, code := child.FsNode().GetAttr(nil, context) var a Attr
code := child.FsNode().GetAttr(&a, nil, context)
if code.Ok() { if code.Ok() {
s = append(s, DirEntry{Name: name, Mode: fi.Mode}) s = append(s, DirEntry{Name: name, Mode: a.Mode})
} }
} }
return s, OK return s, OK
...@@ -132,11 +135,13 @@ func (n *DefaultFsNode) ListXAttr(context *Context) (attrs []string, code Status ...@@ -132,11 +135,13 @@ func (n *DefaultFsNode) ListXAttr(context *Context) (attrs []string, code Status
return nil, ENOSYS return nil, ENOSYS
} }
func (n *DefaultFsNode) GetAttr(file File, context *Context) (fi *Attr, code Status) { func (n *DefaultFsNode) GetAttr(out *Attr, file File, context *Context) (code Status) {
if n.Inode().IsDir() { if n.Inode().IsDir() {
return &Attr{Mode: S_IFDIR | 0755}, OK out.Mode = S_IFDIR | 0755
} else {
out.Mode = S_IFREG | 0644
} }
return &Attr{Mode: S_IFREG | 0644}, OK return OK
} }
func (n *DefaultFsNode) Chmod(file File, perms uint32, context *Context) (code Status) { func (n *DefaultFsNode) Chmod(file File, perms uint32, context *Context) (code Status) {
......
...@@ -79,9 +79,10 @@ func (c *FileSystemConnector) verify() { ...@@ -79,9 +79,10 @@ 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(out *raw.EntryOut, fi *raw.Attr, fsi FsNode) { func (c *FileSystemConnector) childLookup(out *raw.EntryOut, fsi FsNode) {
n := fsi.Inode() n := fsi.Inode()
n.mount.attrToEntry(out, fi) fsi.GetAttr((*Attr)(&out.Attr), nil, nil)
n.mount.fillEntry(out)
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 {
...@@ -223,7 +224,8 @@ func (c *FileSystemConnector) LookupNode(parent *Inode, path string) *Inode { ...@@ -223,7 +224,8 @@ func (c *FileSystemConnector) LookupNode(parent *Inode, path string) *Inode {
} }
components := strings.Split(path, "/") components := strings.Split(path, "/")
for _, r := range components { for _, r := range components {
_, child, _ := c.internalLookup(parent, r, nil) var a Attr
child, _ := c.internalLookup(&a, parent, r, nil)
if child == nil { if child == nil {
return nil return nil
} }
......
...@@ -61,19 +61,16 @@ func (m *fileSystemMount) setOwner(attr *raw.Attr) { ...@@ -61,19 +61,16 @@ func (m *fileSystemMount) setOwner(attr *raw.Attr) {
} }
} }
func (m *fileSystemMount) attrToEntry(out *raw.EntryOut, attr *raw.Attr) () { func (m *fileSystemMount) fillEntry(out *raw.EntryOut) {
out.Attr = *attr
splitDuration(m.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec) splitDuration(m.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec)
splitDuration(m.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec) splitDuration(m.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec)
m.setOwner(&out.Attr) m.setOwner(&out.Attr)
if attr.Mode & S_IFDIR == 0 && attr.Nlink == 0 { if out.Mode & S_IFDIR == 0 && out.Nlink == 0 {
out.Nlink = 1 out.Nlink = 1
} }
} }
func (m *fileSystemMount) fillAttr(out *raw.AttrOut, a *raw.Attr, nodeId uint64) { func (m *fileSystemMount) fillAttr(out *raw.AttrOut, nodeId uint64) {
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
......
...@@ -16,19 +16,20 @@ func (c *FileSystemConnector) Init(fsInit *RawFsInit) { ...@@ -16,19 +16,20 @@ func (c *FileSystemConnector) Init(fsInit *RawFsInit) {
c.fsInit = *fsInit c.fsInit = *fsInit
} }
func (c *FileSystemConnector) lookupMountUpdate(mount *fileSystemMount) (fi *Attr, node *Inode, code Status) { func (c *FileSystemConnector) lookupMountUpdate(out *Attr, mount *fileSystemMount) (node *Inode, code Status) {
fi, code = mount.fs.Root().GetAttr(nil, nil) code = mount.fs.Root().GetAttr(out, nil, nil)
if !code.Ok() { if !code.Ok() {
log.Println("Root getattr should not return error", code) log.Println("Root getattr should not return error", code)
return &Attr{Mode: S_IFDIR | 0755}, mount.mountInode, OK out.Mode = S_IFDIR | 0755
return mount.mountInode, OK
} }
return fi, mount.mountInode, OK return mount.mountInode, OK
} }
func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context *Context) (fi *Attr, node *Inode, code Status) { func (c *FileSystemConnector) internalLookup(out *Attr, parent *Inode, name string, context *Context) (node *Inode, code Status) {
if subMount := c.findMount(parent, name); subMount != nil { if subMount := c.findMount(parent, name); subMount != nil {
return c.lookupMountUpdate(subMount) return c.lookupMountUpdate(out, subMount)
} }
child := parent.GetChild(name) child := parent.GetChild(name)
...@@ -37,10 +38,10 @@ func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context ...@@ -37,10 +38,10 @@ func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context
} }
var fsNode FsNode var fsNode FsNode
if child != nil { if child != nil {
fi, code = child.fsInode.GetAttr(nil, context) code = child.fsInode.GetAttr(out, nil, context)
fsNode = child.FsNode() fsNode = child.FsNode()
} else { } else {
fi, fsNode, code = parent.fsInode.Lookup(name, context) fsNode, code = parent.fsInode.Lookup(out, name, context)
} }
if child == nil && fsNode != nil { if child == nil && fsNode != nil {
...@@ -50,7 +51,7 @@ func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context ...@@ -50,7 +51,7 @@ func (c *FileSystemConnector) internalLookup(parent *Inode, name string, context
} }
} }
return fi, child, code return child, code
} }
func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, name string) (code Status) { func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, name string) (code Status) {
...@@ -60,7 +61,8 @@ func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, na ...@@ -60,7 +61,8 @@ func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, na
return ENOTDIR return ENOTDIR
} }
context := (*Context)(&header.Context) context := (*Context)(&header.Context)
fi, child, code := c.internalLookup(parent, name, context) outAttr := (*Attr)(&out.Attr)
child, code := c.internalLookup(outAttr, parent, name, context)
if code == ENOENT && parent.mount.negativeEntry(out) { if code == ENOENT && parent.mount.negativeEntry(out) {
return OK return OK
} }
...@@ -71,8 +73,7 @@ func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, na ...@@ -71,8 +73,7 @@ func (c *FileSystemConnector) Lookup(out *raw.EntryOut, header *raw.InHeader, na
log.Println("Lookup returned OK with nil child", name) log.Println("Lookup returned OK with nil child", name)
} }
rawAttr := (*raw.Attr)(fi) child.mount.fillEntry(out)
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
...@@ -95,13 +96,13 @@ func (c *FileSystemConnector) GetAttr(out *raw.AttrOut, header *raw.InHeader, in ...@@ -95,13 +96,13 @@ func (c *FileSystemConnector) GetAttr(out *raw.AttrOut, header *raw.InHeader, in
} }
} }
fi, code := node.fsInode.GetAttr(f, (*Context)(&header.Context)) dest := (*Attr)(&out.Attr)
code = node.fsInode.GetAttr(dest, f, (*Context)(&header.Context))
if !code.Ok() { if !code.Ok() {
return code return code
} }
rawAttr := (*raw.Attr)(fi)
node.mount.fillAttr(out, rawAttr, header.NodeId) node.mount.fillAttr(out, header.NodeId)
return OK return OK
} }
...@@ -183,11 +184,10 @@ func (c *FileSystemConnector) SetAttr(out *raw.AttrOut, header *raw.InHeader, in ...@@ -183,11 +184,10 @@ func (c *FileSystemConnector) SetAttr(out *raw.AttrOut, header *raw.InHeader, in
// Must call GetAttr(); the filesystem may override some of // Must call GetAttr(); the filesystem may override some of
// the changes we effect here. // the changes we effect here.
fi, code := node.fsInode.GetAttr(f, (*Context)(&header.Context)) attr := (*Attr)(&out.Attr)
code = node.fsInode.GetAttr(attr, nil, (*Context)(&header.Context))
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) node.mount.fillAttr(out, header.NodeId)
node.mount.fillAttr(out, rawAttr, header.NodeId)
} }
return code return code
} }
...@@ -199,21 +199,22 @@ func (c *FileSystemConnector) Readlink(header *raw.InHeader) (out []byte, code S ...@@ -199,21 +199,22 @@ func (c *FileSystemConnector) Readlink(header *raw.InHeader) (out []byte, code S
func (c *FileSystemConnector) Mknod(out *raw.EntryOut, header *raw.InHeader, input *raw.MknodIn, name string) (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)) ctx := (*Context)(&header.Context)
rawAttr := (*raw.Attr)(fi) fsNode, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), ctx)
if code.Ok() { if code.Ok() {
c.childLookup(out, rawAttr, fsNode) c.childLookup(out, fsNode)
code = fsNode.GetAttr((*Attr)(&out.Attr), nil, ctx)
} }
return code return code
} }
func (c *FileSystemConnector) Mkdir(out *raw.EntryOut, header *raw.InHeader, input *raw.MkdirIn, name string) (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)) ctx := (*Context)(&header.Context)
fsNode, code := parent.fsInode.Mkdir(name, input.Mode, ctx)
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) c.childLookup(out, fsNode)
c.childLookup(out, rawAttr, fsInode) code = fsNode.GetAttr((*Attr)(&out.Attr), nil, ctx)
} }
return code return code
} }
...@@ -230,10 +231,11 @@ func (c *FileSystemConnector) Rmdir(header *raw.InHeader, name string) (code Sta ...@@ -230,10 +231,11 @@ func (c *FileSystemConnector) Rmdir(header *raw.InHeader, name string) (code Sta
func (c *FileSystemConnector) Symlink(out *raw.EntryOut, header *raw.InHeader, pointedTo string, linkName string) (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)) ctx := (*Context)(&header.Context)
fsNode, code := parent.fsInode.Symlink(linkName, pointedTo, ctx)
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) c.childLookup(out, fsNode)
c.childLookup(out, rawAttr, fsNode) code = fsNode.GetAttr((*Attr)(&out.Attr), nil, ctx)
} }
return code return code
} }
...@@ -260,11 +262,11 @@ func (c *FileSystemConnector) Link(out *raw.EntryOut, header *raw.InHeader, inpu ...@@ -260,11 +262,11 @@ func (c *FileSystemConnector) Link(out *raw.EntryOut, header *raw.InHeader, inpu
if existing.mount != parent.mount { if existing.mount != parent.mount {
return EXDEV return EXDEV
} }
ctx := (*Context)(&header.Context)
fi, fsInode, code := parent.fsInode.Link(name, existing.fsInode, (*Context)(&header.Context)) fsNode, code := parent.fsInode.Link(name, existing.fsInode, ctx)
if code.Ok() { if code.Ok() {
rawAttr := (*raw.Attr)(fi) c.childLookup(out, fsNode)
c.childLookup(out, rawAttr, fsInode) code = fsNode.GetAttr((*Attr)(&out.Attr), nil, ctx)
} }
return code return code
...@@ -277,12 +279,12 @@ func (c *FileSystemConnector) Access(header *raw.InHeader, input *raw.AccessIn) ...@@ -277,12 +279,12 @@ func (c *FileSystemConnector) Access(header *raw.InHeader, input *raw.AccessIn)
func (c *FileSystemConnector) Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (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, fsNode, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, (*Context)(&header.Context))
if !code.Ok() { if !code.Ok() {
return code return code
} }
rawAttr := (*raw.Attr)(fi)
c.childLookup(&out.EntryOut, rawAttr, fsNode) c.childLookup(&out.EntryOut, fsNode)
handle, opened := parent.mount.registerFileHandle(fsNode.Inode(), nil, f, input.Flags) handle, opened := parent.mount.registerFileHandle(fsNode.Inode(), nil, f, input.Flags)
out.OpenOut.OpenFlags = opened.FuseFlags out.OpenOut.OpenFlags = opened.FuseFlags
......
...@@ -80,11 +80,11 @@ func (n *memNode) Readlink(c *Context) ([]byte, Status) { ...@@ -80,11 +80,11 @@ func (n *memNode) Readlink(c *Context) ([]byte, Status) {
return []byte(n.link), OK return []byte(n.link), OK
} }
func (n *memNode) Mkdir(name string, mode uint32, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *memNode) Mkdir(name string, mode uint32, context *Context) (newNode FsNode, code Status) {
ch := n.newNode(true) ch := n.newNode(true)
ch.info.Mode = mode | S_IFDIR ch.info.Mode = mode | S_IFDIR
n.Inode().AddChild(name, ch.Inode()) n.Inode().AddChild(name, ch.Inode())
return &ch.info, ch, OK return ch, OK
} }
func (n *memNode) Unlink(name string, context *Context) (code Status) { func (n *memNode) Unlink(name string, context *Context) (code Status) {
...@@ -99,13 +99,13 @@ func (n *memNode) Rmdir(name string, context *Context) (code Status) { ...@@ -99,13 +99,13 @@ func (n *memNode) Rmdir(name string, context *Context) (code Status) {
return n.Unlink(name, context) return n.Unlink(name, context)
} }
func (n *memNode) Symlink(name string, content string, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *memNode) Symlink(name string, content string, context *Context) (newNode FsNode, code Status) {
ch := n.newNode(false) ch := n.newNode(false)
ch.info.Mode = S_IFLNK | 0777 ch.info.Mode = S_IFLNK | 0777
ch.link = content ch.link = content
n.Inode().AddChild(name, ch.Inode()) n.Inode().AddChild(name, ch.Inode())
return &ch.info, ch, OK return ch, OK
} }
func (n *memNode) Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status) { func (n *memNode) Rename(oldName string, newParent FsNode, newName string, context *Context) (code Status) {
...@@ -115,22 +115,21 @@ func (n *memNode) Rename(oldName string, newParent FsNode, newName string, conte ...@@ -115,22 +115,21 @@ func (n *memNode) Rename(oldName string, newParent FsNode, newName string, conte
return OK return OK
} }
func (n *memNode) Link(name string, existing FsNode, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *memNode) Link(name string, existing FsNode, context *Context) (newNode FsNode, code Status) {
n.Inode().AddChild(name, existing.Inode()) n.Inode().AddChild(name, existing.Inode())
fi, code = existing.GetAttr(nil, context) return existing, code
return fi, existing, code
} }
func (n *memNode) Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *Attr, newNode FsNode, code Status) { func (n *memNode) Create(name string, flags uint32, mode uint32, context *Context) (file File, newNode FsNode, code Status) {
ch := n.newNode(false) ch := n.newNode(false)
ch.info.Mode = mode | S_IFREG ch.info.Mode = mode | S_IFREG
f, err := os.Create(n.filename()) f, err := os.Create(n.filename())
if err != nil { if err != nil {
return nil, nil, nil, ToStatus(err) return nil, nil, ToStatus(err)
} }
n.Inode().AddChild(name, ch.Inode()) n.Inode().AddChild(name, ch.Inode())
return ch.newFile(f), &ch.info, ch, OK return ch.newFile(f), ch, OK
} }
type memNodeFile struct { type memNodeFile struct {
...@@ -170,8 +169,9 @@ func (n *memNode) Open(flags uint32, context *Context) (file File, code Status) ...@@ -170,8 +169,9 @@ func (n *memNode) Open(flags uint32, context *Context) (file File, code Status)
return n.newFile(f), OK return n.newFile(f), OK
} }
func (n *memNode) GetAttr(file File, context *Context) (fi *Attr, code Status) { func (n *memNode) GetAttr(fi *Attr, file File, context *Context) (code Status) {
return &n.info, OK *fi = n.info
return OK
} }
func (n *memNode) Truncate(file File, size uint64, context *Context) (code Status) { func (n *memNode) Truncate(file File, size uint64, context *Context) (code Status) {
......
...@@ -200,7 +200,7 @@ func (n *pathInode) forgetClientInodes() { ...@@ -200,7 +200,7 @@ func (n *pathInode) forgetClientInodes() {
// Reread all client nodes below this node. Must run outside the treeLock. // Reread all client nodes below this node. Must run outside the treeLock.
func (n *pathInode) updateClientInodes() { func (n *pathInode) updateClientInodes() {
n.GetAttr(nil, nil) n.GetAttr(&Attr{}, nil, nil)
for _, ch := range n.Inode().FsChildren() { for _, ch := range n.Inode().FsChildren() {
ch.FsNode().(*pathInode).updateClientInodes() ch.FsNode().(*pathInode).updateClientInodes()
} }
...@@ -216,19 +216,6 @@ func (n *pathInode) RLockTree() func() { ...@@ -216,19 +216,6 @@ func (n *pathInode) RLockTree() func() {
return func() { n.pathFs.pathLock.RUnlock() } return func() { n.pathFs.pathLock.RUnlock() }
} }
func (n *pathInode) fillNewChildAttr(path string, child *pathInode, c *Context) (fi *Attr, code Status) {
fi, _ = n.fs.GetAttr(path, c)
if fi != nil && fi.Ino > 0 {
child.clientInode = fi.Ino
}
if fi == nil {
log.Println("fillNewChildAttr found nil FileInfo", path)
return nil, ENOENT
}
return fi, OK
}
// GetPath returns the path relative to the mount governing this // GetPath returns the path relative to the mount governing this
// inode. It returns nil for mount if the file was deleted or the // inode. It returns nil for mount if the file was deleted or the
// filesystem unmounted. // filesystem unmounted.
...@@ -376,25 +363,23 @@ func (n *pathInode) OpenDir(context *Context) ([]DirEntry, Status) { ...@@ -376,25 +363,23 @@ func (n *pathInode) OpenDir(context *Context) ([]DirEntry, Status) {
return n.fs.OpenDir(n.GetPath(), context) return n.fs.OpenDir(n.GetPath(), context)
} }
func (n *pathInode) Mknod(name string, mode uint32, dev uint32, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *pathInode) Mknod(name string, mode uint32, dev uint32, context *Context) (newNode FsNode, code Status) {
fullPath := filepath.Join(n.GetPath(), name) fullPath := filepath.Join(n.GetPath(), name)
code = n.fs.Mknod(fullPath, mode, dev, context) code = n.fs.Mknod(fullPath, mode, dev, context)
if code.Ok() { if code.Ok() {
pNode := n.createChild(false) pNode := n.createChild(false)
newNode = pNode newNode = pNode
fi, code = n.fillNewChildAttr(fullPath, pNode, context)
n.addChild(name, pNode) n.addChild(name, pNode)
} }
return return
} }
func (n *pathInode) Mkdir(name string, mode uint32, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *pathInode) Mkdir(name string, mode uint32, context *Context) (newNode FsNode, code Status) {
fullPath := filepath.Join(n.GetPath(), name) fullPath := filepath.Join(n.GetPath(), name)
code = n.fs.Mkdir(fullPath, mode, context) code = n.fs.Mkdir(fullPath, mode, context)
if code.Ok() { if code.Ok() {
pNode := n.createChild(true) pNode := n.createChild(true)
newNode = pNode newNode = pNode
fi, code = n.fillNewChildAttr(fullPath, pNode, context)
n.addChild(name, pNode) n.addChild(name, pNode)
} }
return return
...@@ -416,13 +401,12 @@ func (n *pathInode) Rmdir(name string, context *Context) (code Status) { ...@@ -416,13 +401,12 @@ func (n *pathInode) Rmdir(name string, context *Context) (code Status) {
return code return code
} }
func (n *pathInode) Symlink(name string, content string, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *pathInode) Symlink(name string, content string, context *Context) (newNode FsNode, code Status) {
fullPath := filepath.Join(n.GetPath(), name) fullPath := filepath.Join(n.GetPath(), name)
code = n.fs.Symlink(content, fullPath, context) code = n.fs.Symlink(content, fullPath, context)
if code.Ok() { if code.Ok() {
pNode := n.createChild(false) pNode := n.createChild(false)
newNode = pNode newNode = pNode
fi, code = n.fillNewChildAttr(fullPath, pNode, context)
n.addChild(name, pNode) n.addChild(name, pNode)
} }
return return
...@@ -441,40 +425,41 @@ func (n *pathInode) Rename(oldName string, newParent FsNode, newName string, con ...@@ -441,40 +425,41 @@ func (n *pathInode) Rename(oldName string, newParent FsNode, newName string, con
return code return code
} }
func (n *pathInode) Link(name string, existingFsnode FsNode, context *Context) (fi *Attr, newNode FsNode, code Status) { func (n *pathInode) Link(name string, existingFsnode FsNode, context *Context) (newNode FsNode, code Status) {
if !n.pathFs.options.ClientInodes { if !n.pathFs.options.ClientInodes {
return nil, nil, ENOSYS return nil, ENOSYS
} }
newPath := filepath.Join(n.GetPath(), name) newPath := filepath.Join(n.GetPath(), name)
existing := existingFsnode.(*pathInode) existing := existingFsnode.(*pathInode)
oldPath := existing.GetPath() oldPath := existing.GetPath()
code = n.fs.Link(oldPath, newPath, context) code = n.fs.Link(oldPath, newPath, context)
var a *Attr
if code.Ok() { if code.Ok() {
fi, code = n.fs.GetAttr(newPath, context) a, code = n.fs.GetAttr(newPath, context)
} }
if code.Ok() { if code.Ok() {
if existing.clientInode != 0 && existing.clientInode == fi.Ino { if existing.clientInode != 0 && existing.clientInode == a.Ino {
newNode = existing newNode = existing
n.addChild(name, existing) n.addChild(name, existing)
} else { } else {
pNode := n.createChild(false) pNode := n.createChild(false)
newNode = pNode newNode = pNode
pNode.clientInode = fi.Ino pNode.clientInode = a.Ino
n.addChild(name, pNode) n.addChild(name, pNode)
} }
} }
return return
} }
func (n *pathInode) Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *Attr, newNode FsNode, code Status) { func (n *pathInode) Create(name string, flags uint32, mode uint32, context *Context) (file File, newNode FsNode, code Status) {
fullPath := filepath.Join(n.GetPath(), name) fullPath := filepath.Join(n.GetPath(), name)
file, code = n.fs.Create(fullPath, flags, mode, context) file, code = n.fs.Create(fullPath, flags, mode, context)
if code.Ok() { if code.Ok() {
pNode := n.createChild(false) pNode := n.createChild(false)
newNode = pNode newNode = pNode
fi, code = n.fillNewChildAttr(fullPath, pNode, context)
n.addChild(name, pNode) n.addChild(name, pNode)
} }
return return
...@@ -500,14 +485,15 @@ func (n *pathInode) Open(flags uint32, context *Context) (file File, code Status ...@@ -500,14 +485,15 @@ func (n *pathInode) Open(flags uint32, context *Context) (file File, code Status
return return
} }
func (n *pathInode) Lookup(name string, context *Context) (fi *Attr, node FsNode, code Status) { func (n *pathInode) Lookup(out *Attr, name string, context *Context) (node FsNode, code Status) {
fullPath := filepath.Join(n.GetPath(), name) fullPath := filepath.Join(n.GetPath(), name)
fi, code = n.fs.GetAttr(fullPath, context) fi, code := n.fs.GetAttr(fullPath, context)
if code.Ok() { if code.Ok() {
node = n.findChild(fi, name, fullPath) node = n.findChild(fi, name, fullPath)
*out = *fi
} }
return return node, code
} }
func (n *pathInode) findChild(fi *Attr, name string, fullPath string) (out *pathInode) { func (n *pathInode) findChild(fi *Attr, name string, fullPath string) (out *pathInode) {
...@@ -533,7 +519,8 @@ func (n *pathInode) findChild(fi *Attr, name string, fullPath string) (out *path ...@@ -533,7 +519,8 @@ func (n *pathInode) findChild(fi *Attr, name string, fullPath string) (out *path
return out return out
} }
func (n *pathInode) GetAttr(file File, context *Context) (fi *Attr, code Status) { func (n *pathInode) GetAttr(out *Attr, file File, context *Context) (code Status) {
var fi *Attr
if file == nil { if file == nil {
// called on a deleted files. // called on a deleted files.
file = n.inode.AnyFile() file = n.inode.AnyFile()
...@@ -541,10 +528,12 @@ func (n *pathInode) GetAttr(file File, context *Context) (fi *Attr, code Status) ...@@ -541,10 +528,12 @@ func (n *pathInode) GetAttr(file File, context *Context) (fi *Attr, code Status)
if file != nil { if file != nil {
fi, code = file.GetAttr() fi, code = file.GetAttr()
*out = *fi
} }
if file == nil || code == ENOSYS || code == EBADF { if file == nil || code == ENOSYS || code == EBADF {
fi, code = n.fs.GetAttr(n.GetPath(), context) fi, code = n.fs.GetAttr(n.GetPath(), context)
*out = *fi
} }
if fi != nil { if fi != nil {
...@@ -554,7 +543,7 @@ func (n *pathInode) GetAttr(file File, context *Context) (fi *Attr, code Status) ...@@ -554,7 +543,7 @@ func (n *pathInode) GetAttr(file File, context *Context) (fi *Attr, code Status)
if fi != nil && !fi.IsDir() && fi.Nlink == 0 { if fi != nil && !fi.IsDir() && fi.Nlink == 0 {
fi.Nlink = 1 fi.Nlink = 1
} }
return fi, code return code
} }
func (n *pathInode) Chmod(file File, perms uint32, context *Context) (code Status) { func (n *pathInode) Chmod(file File, perms uint32, context *Context) (code Status) {
......
...@@ -357,7 +357,8 @@ func (fs *UnionFs) Link(orig string, newName string, context *fuse.Context) (cod ...@@ -357,7 +357,8 @@ func (fs *UnionFs) Link(orig string, newName string, context *fuse.Context) (cod
// to see the Inode number. // to see the Inode number.
fs.branchCache.GetFresh(orig) fs.branchCache.GetFresh(orig)
inode := fs.nodeFs.Node(orig) inode := fs.nodeFs.Node(orig)
inode.FsNode().GetAttr(nil, nil) var a fuse.Attr
inode.FsNode().GetAttr(&a, nil, nil)
} }
if code.Ok() { if code.Ok() {
code = fs.promoteDirsTo(newName) code = fs.promoteDirsTo(newName)
......
...@@ -61,11 +61,6 @@ func (n *memNode) Print(indent int) { ...@@ -61,11 +61,6 @@ func (n *memNode) Print(indent int) {
} }
} }
// We construct the tree at mount, so we never need to look anything up.
func (n *memNode) Lookup(name string, c *fuse.Context) (fi *fuse.Attr, node fuse.FsNode, code fuse.Status) {
return nil, nil, fuse.ENOENT
}
func (n *memNode) OpenDir(context *fuse.Context) (stream []fuse.DirEntry, code fuse.Status) { func (n *memNode) OpenDir(context *fuse.Context) (stream []fuse.DirEntry, code fuse.Status) {
children := n.Inode().Children() children := n.Inode().Children()
stream = make([]fuse.DirEntry, 0, len(children)) stream = make([]fuse.DirEntry, 0, len(children))
...@@ -94,14 +89,13 @@ func (n *memNode) Deletable() bool { ...@@ -94,14 +89,13 @@ func (n *memNode) Deletable() bool {
return false return false
} }
func (n *memNode) GetAttr(file fuse.File, context *fuse.Context) (*fuse.Attr, fuse.Status) { func (n *memNode) GetAttr(out *fuse.Attr, file fuse.File, context *fuse.Context) (fuse.Status) {
if n.Inode().IsDir() { if n.Inode().IsDir() {
return &fuse.Attr{ out.Mode= fuse.S_IFDIR | 0777
Mode: fuse.S_IFDIR | 0777, return fuse.OK
}, fuse.OK
} }
*out = *n.file.Stat()
return n.file.Stat(), fuse.OK return fuse.OK
} }
func (n *MemTreeFs) addFile(name string, f MemFile) { func (n *MemTreeFs) addFile(name string, f MemFile) {
......
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