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