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

fuse/nodefs: namespace functions now return *Inode.

This makes it impossible to forget to create an Inode to match the
FsNode.

This is an API change. To update, update function signatures, and change
  
  me.Inode().NewChild("name", isdir, child)
  return child, fuse.OK

to

  return me.Inode().NewChild("name", isdir, child), fuse.OK

in Mkdir, Mknod, Create, Symlink and Link methods.
parent 391230f2
......@@ -47,7 +47,7 @@ type Node interface {
// Lookup finds a child node to this node; it is only called
// for directory Nodes.
Lookup(out *fuse.Attr, name string, context *fuse.Context) (node Node, code fuse.Status)
Lookup(out *fuse.Attr, name string, context *fuse.Context) (*Inode, fuse.Status)
// Deletable() should return true if this inode may be
// discarded from the children list. This will be called from
......@@ -64,16 +64,30 @@ type Node interface {
Readlink(c *fuse.Context) ([]byte, fuse.Status)
// Namespace operations; these are only called on directory Nodes.
Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (newNode Node, code fuse.Status)
Mkdir(name string, mode uint32, context *fuse.Context) (newNode Node, code fuse.Status)
// Mknod should create the node, add it to the receiver's
// inode, and return it
Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (newNode *Inode, code fuse.Status)
// Mkdir should create the directory Inode, add it to the
// receiver's Inode, and return it
Mkdir(name string, mode uint32, context *fuse.Context) (newNode *Inode, code fuse.Status)
Unlink(name string, context *fuse.Context) (code fuse.Status)
Rmdir(name string, context *fuse.Context) (code fuse.Status)
Symlink(name string, content string, context *fuse.Context) (newNode Node, code fuse.Status)
// Symlink should create a child inode to the receiver, and
// return it.
Symlink(name string, content string, context *fuse.Context) (*Inode, fuse.Status)
Rename(oldName string, newParent Node, newName string, context *fuse.Context) (code fuse.Status)
Link(name string, existing Node, context *fuse.Context) (newNode Node, code fuse.Status)
// Files
Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, newNode Node, code fuse.Status)
// Link should return the Inode of the resulting link. In
// a POSIX conformant file system, this should add 'existing'
// to the receiver, and return the Inode corresponding to
// 'existing'.
Link(name string, existing Node, context *fuse.Context) (newNode *Inode, code fuse.Status)
// Create should return an open file, and the Inode for that file.
Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, child *Inode, code fuse.Status)
Open(flags uint32, context *fuse.Context) (file File, code fuse.Status)
OpenDir(context *fuse.Context) ([]fuse.DirEntry, fuse.Status)
......
......@@ -41,7 +41,7 @@ func (n *defaultNode) Inode() *Inode {
func (n *defaultNode) OnForget() {
}
func (n *defaultNode) Lookup(out *fuse.Attr, name string, context *fuse.Context) (node Node, code fuse.Status) {
func (n *defaultNode) Lookup(out *fuse.Attr, name string, context *fuse.Context) (node *Inode, code fuse.Status) {
return nil, fuse.ENOENT
}
......@@ -53,10 +53,10 @@ func (n *defaultNode) Readlink(c *fuse.Context) ([]byte, fuse.Status) {
return nil, fuse.ENOSYS
}
func (n *defaultNode) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *defaultNode) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (newNode *Inode, code fuse.Status) {
return nil, fuse.ENOSYS
}
func (n *defaultNode) Mkdir(name string, mode uint32, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *defaultNode) Mkdir(name string, mode uint32, context *fuse.Context) (newNode *Inode, code fuse.Status) {
return nil, fuse.ENOSYS
}
func (n *defaultNode) Unlink(name string, context *fuse.Context) (code fuse.Status) {
......@@ -65,7 +65,7 @@ func (n *defaultNode) Unlink(name string, context *fuse.Context) (code fuse.Stat
func (n *defaultNode) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
return fuse.ENOSYS
}
func (n *defaultNode) Symlink(name string, content string, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *defaultNode) Symlink(name string, content string, context *fuse.Context) (newNode *Inode, code fuse.Status) {
return nil, fuse.ENOSYS
}
......@@ -73,11 +73,11 @@ func (n *defaultNode) Rename(oldName string, newParent Node, newName string, con
return fuse.ENOSYS
}
func (n *defaultNode) Link(name string, existing Node, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *defaultNode) Link(name string, existing Node, context *fuse.Context) (newNode *Inode, code fuse.Status) {
return nil, fuse.ENOSYS
}
func (n *defaultNode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, newNode Node, code fuse.Status) {
func (n *defaultNode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, newNode *Inode, code fuse.Status) {
return nil, nil, fuse.ENOSYS
}
......
......@@ -96,9 +96,9 @@ func (c *FileSystemConnector) verify() {
root.verify(c.rootNode.mountPoint)
}
func (c *rawBridge) childLookup(out *fuse.EntryOut, fsi Node) {
n := fsi.Inode()
fsi.GetAttr((*fuse.Attr)(&out.Attr), nil, nil)
// childLookup fills entry information for a newly created child inode
func (c *rawBridge) childLookup(out *fuse.EntryOut, n *Inode) {
n.Node().GetAttr((*fuse.Attr)(&out.Attr), nil, nil)
n.mount.fillEntry(out)
out.Ino = c.fsConn().lookupUpdate(n)
out.NodeId = out.Ino
......
......@@ -70,19 +70,10 @@ func (c *FileSystemConnector) internalLookup(out *fuse.Attr, parent *Inode, name
if child != nil {
parent = nil
}
var fsNode Node
if child != nil {
code = child.fsInode.GetAttr(out, nil, &header.Context)
fsNode = child.Node()
} else {
fsNode, code = parent.fsInode.Lookup(out, name, &header.Context)
}
if child == nil && fsNode != nil {
child = fsNode.Inode()
if child == nil {
log.Panicf("Lookup %q returned child without Inode: %v", name, fsNode)
}
child, code = parent.fsInode.Lookup(out, name, &header.Context)
}
return child, code
......@@ -256,10 +247,10 @@ func (c *rawBridge) Readlink(header *fuse.InHeader) (out []byte, code fuse.Statu
func (c *rawBridge) Mknod(input *fuse.MknodIn, name string, out *fuse.EntryOut) (code fuse.Status) {
parent := c.toInode(input.NodeId)
fsNode, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), &input.Context)
child, code := parent.fsInode.Mknod(name, input.Mode, uint32(input.Rdev), &input.Context)
if code.Ok() {
c.childLookup(out, fsNode)
code = fsNode.GetAttr((*fuse.Attr)(&out.Attr), nil, &input.Context)
c.childLookup(out, child)
code = child.fsInode.GetAttr((*fuse.Attr)(&out.Attr), nil, &input.Context)
}
return code
}
......@@ -267,10 +258,10 @@ func (c *rawBridge) Mknod(input *fuse.MknodIn, name string, out *fuse.EntryOut)
func (c *rawBridge) Mkdir(input *fuse.MkdirIn, name string, out *fuse.EntryOut) (code fuse.Status) {
parent := c.toInode(input.NodeId)
fsNode, code := parent.fsInode.Mkdir(name, input.Mode, &input.Context)
child, code := parent.fsInode.Mkdir(name, input.Mode, &input.Context)
if code.Ok() {
c.childLookup(out, fsNode)
code = fsNode.GetAttr((*fuse.Attr)(&out.Attr), nil, &input.Context)
c.childLookup(out, child)
code = child.fsInode.GetAttr((*fuse.Attr)(&out.Attr), nil, &input.Context)
}
return code
}
......@@ -288,10 +279,10 @@ func (c *rawBridge) Rmdir(header *fuse.InHeader, name string) (code fuse.Status)
func (c *rawBridge) Symlink(header *fuse.InHeader, pointedTo string, linkName string, out *fuse.EntryOut) (code fuse.Status) {
parent := c.toInode(header.NodeId)
fsNode, code := parent.fsInode.Symlink(linkName, pointedTo, &header.Context)
child, code := parent.fsInode.Symlink(linkName, pointedTo, &header.Context)
if code.Ok() {
c.childLookup(out, fsNode)
code = fsNode.GetAttr((*fuse.Attr)(&out.Attr), nil, &header.Context)
c.childLookup(out, child)
code = child.fsInode.GetAttr((*fuse.Attr)(&out.Attr), nil, &header.Context)
}
return code
}
......@@ -323,10 +314,10 @@ func (c *rawBridge) Link(input *fuse.LinkIn, name string, out *fuse.EntryOut) (c
return fuse.EXDEV
}
fsNode, code := parent.fsInode.Link(name, existing.fsInode, &input.Context)
child, code := parent.fsInode.Link(name, existing.fsInode, &input.Context)
if code.Ok() {
c.childLookup(out, fsNode)
code = fsNode.GetAttr((*fuse.Attr)(&out.Attr), nil, &input.Context)
c.childLookup(out, child)
code = child.fsInode.GetAttr((*fuse.Attr)(&out.Attr), nil, &input.Context)
}
return code
......@@ -339,13 +330,13 @@ func (c *rawBridge) Access(input *fuse.AccessIn) (code fuse.Status) {
func (c *rawBridge) Create(input *fuse.CreateIn, name string, out *fuse.CreateOut) (code fuse.Status) {
parent := c.toInode(input.NodeId)
f, fsNode, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, &input.Context)
f, child, code := parent.fsInode.Create(name, uint32(input.Flags), input.Mode, &input.Context)
if !code.Ok() {
return code
}
c.childLookup(&out.EntryOut, fsNode)
handle, opened := parent.mount.registerFileHandle(fsNode.Inode(), nil, f, input.Flags)
c.childLookup(&out.EntryOut, child)
handle, opened := parent.mount.registerFileHandle(child, nil, f, input.Flags)
out.OpenOut.OpenFlags = opened.FuseFlags
out.OpenOut.Fh = handle
......
......@@ -96,10 +96,10 @@ func (n *memNode) StatFs() *fuse.StatfsOut {
return &fuse.StatfsOut{}
}
func (n *memNode) Mkdir(name string, mode uint32, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *memNode) Mkdir(name string, mode uint32, context *fuse.Context) (newNode *Inode, code fuse.Status) {
ch := n.newNode(name, true)
ch.info.Mode = mode | fuse.S_IFDIR
return ch, fuse.OK
return ch.Inode(), fuse.OK
}
func (n *memNode) Unlink(name string, context *fuse.Context) (code fuse.Status) {
......@@ -114,12 +114,12 @@ func (n *memNode) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
return n.Unlink(name, context)
}
func (n *memNode) Symlink(name string, content string, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *memNode) Symlink(name string, content string, context *fuse.Context) (newNode *Inode, code fuse.Status) {
ch := n.newNode(name, false)
ch.info.Mode = fuse.S_IFLNK | 0777
ch.link = content
return ch, fuse.OK
return ch.Inode(), fuse.OK
}
func (n *memNode) Rename(oldName string, newParent Node, newName string, context *fuse.Context) (code fuse.Status) {
......@@ -129,12 +129,12 @@ func (n *memNode) Rename(oldName string, newParent Node, newName string, context
return fuse.OK
}
func (n *memNode) Link(name string, existing Node, context *fuse.Context) (newNode Node, code fuse.Status) {
func (n *memNode) Link(name string, existing Node, context *fuse.Context) (*Inode, fuse.Status) {
n.Inode().AddChild(name, existing.Inode())
return existing, code
return existing.Inode(), fuse.OK
}
func (n *memNode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, newNode Node, code fuse.Status) {
func (n *memNode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file File, node *Inode, code fuse.Status) {
ch := n.newNode(name, false)
ch.info.Mode = mode | fuse.S_IFREG
......@@ -142,7 +142,7 @@ func (n *memNode) Create(name string, flags uint32, mode uint32, context *fuse.C
if err != nil {
return nil, nil, fuse.ToStatus(err)
}
return ch.newFile(f), ch, fuse.OK
return ch.newFile(f), ch.Inode(), fuse.OK
}
type memNodeFile struct {
......
......@@ -415,26 +415,28 @@ func (n *pathInode) OpenDir(context *fuse.Context) ([]fuse.DirEntry, fuse.Status
return n.fs.OpenDir(n.GetPath(), context)
}
func (n *pathInode) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (newNode nodefs.Node, code fuse.Status) {
func (n *pathInode) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (*nodefs.Inode, fuse.Status) {
fullPath := filepath.Join(n.GetPath(), name)
code = n.fs.Mknod(fullPath, mode, dev, context)
code := n.fs.Mknod(fullPath, mode, dev, context)
var child *nodefs.Inode
if code.Ok() {
pNode := n.createChild(name, false)
newNode = pNode
child = pNode.Inode()
n.addChild(name, pNode)
}
return
return child, code
}
func (n *pathInode) Mkdir(name string, mode uint32, context *fuse.Context) (newNode nodefs.Node, code fuse.Status) {
func (n *pathInode) Mkdir(name string, mode uint32, context *fuse.Context) (*nodefs.Inode, fuse.Status) {
fullPath := filepath.Join(n.GetPath(), name)
code = n.fs.Mkdir(fullPath, mode, context)
code := n.fs.Mkdir(fullPath, mode, context)
var child *nodefs.Inode
if code.Ok() {
pNode := n.createChild(name, true)
newNode = pNode
child = pNode.Inode()
n.addChild(name, pNode)
}
return
return child, code
}
func (n *pathInode) Unlink(name string, context *fuse.Context) (code fuse.Status) {
......@@ -453,15 +455,16 @@ func (n *pathInode) Rmdir(name string, context *fuse.Context) (code fuse.Status)
return code
}
func (n *pathInode) Symlink(name string, content string, context *fuse.Context) (newNode nodefs.Node, code fuse.Status) {
func (n *pathInode) Symlink(name string, content string, context *fuse.Context) (*nodefs.Inode, fuse.Status) {
fullPath := filepath.Join(n.GetPath(), name)
code = n.fs.Symlink(content, fullPath, context)
code := n.fs.Symlink(content, fullPath, context)
var child *nodefs.Inode
if code.Ok() {
pNode := n.createChild(name, false)
newNode = pNode
child = pNode.Inode()
n.addChild(name, pNode)
}
return
return child, code
}
func (n *pathInode) Rename(oldName string, newParent nodefs.Node, newName string, context *fuse.Context) (code fuse.Status) {
......@@ -478,7 +481,7 @@ func (n *pathInode) Rename(oldName string, newParent nodefs.Node, newName string
return code
}
func (n *pathInode) Link(name string, existingFsnode nodefs.Node, context *fuse.Context) (newNode nodefs.Node, code fuse.Status) {
func (n *pathInode) Link(name string, existingFsnode nodefs.Node, context *fuse.Context) (*nodefs.Inode, fuse.Status) {
if !n.pathFs.options.ClientInodes {
return nil, fuse.ENOSYS
}
......@@ -486,37 +489,39 @@ func (n *pathInode) Link(name string, existingFsnode nodefs.Node, context *fuse.
newPath := filepath.Join(n.GetPath(), name)
existing := existingFsnode.(*pathInode)
oldPath := existing.GetPath()
code = n.fs.Link(oldPath, newPath, context)
code := n.fs.Link(oldPath, newPath, context)
var a *fuse.Attr
if code.Ok() {
a, code = n.fs.GetAttr(newPath, context)
}
var child *nodefs.Inode
if code.Ok() {
if existing.clientInode != 0 && existing.clientInode == a.Ino {
newNode = existing
child = existing.Inode()
n.Inode().AddChild(name, existing.Inode())
n.addChild(name, existing)
} else {
pNode := n.createChild(name, false)
newNode = pNode
child = pNode.Inode()
pNode.clientInode = a.Ino
n.addChild(name, pNode)
}
}
return
return child, code
}
func (n *pathInode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file nodefs.File, newNode nodefs.Node, code fuse.Status) {
func (n *pathInode) Create(name string, flags uint32, mode uint32, context *fuse.Context) (nodefs.File, *nodefs.Inode, fuse.Status) {
var child *nodefs.Inode
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() {
pNode := n.createChild(name, false)
newNode = pNode
child = pNode.Inode()
n.addChild(name, pNode)
}
return
return file, child, code
}
func (n *pathInode) createChild(name string, isDir bool) *pathInode {
......@@ -539,11 +544,11 @@ func (n *pathInode) Open(flags uint32, context *fuse.Context) (file nodefs.File,
return
}
func (n *pathInode) Lookup(out *fuse.Attr, name string, context *fuse.Context) (node nodefs.Node, code fuse.Status) {
func (n *pathInode) Lookup(out *fuse.Attr, name string, context *fuse.Context) (node *nodefs.Inode, code fuse.Status) {
fullPath := filepath.Join(n.GetPath(), name)
fi, code := n.fs.GetAttr(fullPath, context)
if code.Ok() {
node = n.findChild(fi, name, fullPath)
node = n.findChild(fi, name, fullPath).Inode()
*out = *fi
}
......
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