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

nodefs: various fixes

* Fix deadlock with OnAdd

* return EROFS for missing Create

* Fill Mode using Inode.setEntryOut in all namespace operations
parent c7cf8409
...@@ -450,4 +450,8 @@ type Options struct { ...@@ -450,4 +450,8 @@ type Options struct {
// Automatic inode numbers are handed out sequentially // Automatic inode numbers are handed out sequentially
// starting from this number. If unset, use 2^63. // starting from this number. If unset, use 2^63.
FirstAutomaticIno uint64 FirstAutomaticIno uint64
// OnAdd is an alternative way to specify the OnAdd
// functionality of the root node.
OnAdd func(ctx context.Context, root InodeEmbedder)
} }
...@@ -49,7 +49,7 @@ type rawBridge struct { ...@@ -49,7 +49,7 @@ type rawBridge struct {
} }
// newInode creates creates new inode pointing to ops. // newInode creates creates new inode pointing to ops.
func (b *rawBridge) newInode(ctx context.Context, ops InodeEmbedder, id NodeAttr, persistent bool) *Inode { func (b *rawBridge) newInodeUnlocked(ops InodeEmbedder, id NodeAttr, persistent bool) *Inode {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
...@@ -96,10 +96,19 @@ func (b *rawBridge) newInode(ctx context.Context, ops InodeEmbedder, id NodeAttr ...@@ -96,10 +96,19 @@ func (b *rawBridge) newInode(ctx context.Context, ops InodeEmbedder, id NodeAttr
b.nodes[id.Ino] = ops.embed() b.nodes[id.Ino] = ops.embed()
initInode(ops.embed(), ops, id, b, persistent) initInode(ops.embed(), ops, id, b, persistent)
return ops.embed()
}
func (b *rawBridge) newInode(ctx context.Context, ops InodeEmbedder, id NodeAttr, persistent bool) *Inode {
ch := b.newInodeUnlocked(ops, id, persistent)
if ch != ops.embed() {
return ch
}
if oa, ok := ops.(OnAdder); ok { if oa, ok := ops.(OnAdder); ok {
oa.OnAdd(ctx) oa.OnAdd(ctx)
} }
return ops.embed() return ch
} }
// addNewChild inserts the child into the tree. Returns file handle if file != nil. // addNewChild inserts the child into the tree. Returns file handle if file != nil.
...@@ -178,7 +187,9 @@ func NewNodeFS(root InodeEmbedder, opts *Options) fuse.RawFileSystem { ...@@ -178,7 +187,9 @@ func NewNodeFS(root InodeEmbedder, opts *Options) fuse.RawFileSystem {
// Fh 0 means no file handle. // Fh 0 means no file handle.
bridge.files = []*fileEntry{{}} bridge.files = []*fileEntry{{}}
if oa, ok := root.(OnAdder); ok { if opts.OnAdd != nil {
opts.OnAdd(context.Background(), root)
} else if oa, ok := root.(OnAdder); ok {
oa.OnAdd(context.Background()) oa.OnAdd(context.Background())
} }
...@@ -303,6 +314,7 @@ func (b *rawBridge) Mknod(cancel <-chan struct{}, input *fuse.MknodIn, name stri ...@@ -303,6 +314,7 @@ func (b *rawBridge) Mknod(cancel <-chan struct{}, input *fuse.MknodIn, name stri
b.addNewChild(parent, name, child, nil, 0, out) b.addNewChild(parent, name, child, nil, 0, out)
b.setEntryOutTimeout(out) b.setEntryOutTimeout(out)
child.setEntryOut(out)
return fuse.OK return fuse.OK
} }
...@@ -316,6 +328,8 @@ func (b *rawBridge) Create(cancel <-chan struct{}, input *fuse.CreateIn, name st ...@@ -316,6 +328,8 @@ func (b *rawBridge) Create(cancel <-chan struct{}, input *fuse.CreateIn, name st
var flags uint32 var flags uint32
if mops, ok := parent.ops.(Creater); ok { if mops, ok := parent.ops.(Creater); ok {
child, f, flags, errno = mops.Create(ctx, name, input.Flags, input.Mode) child, f, flags, errno = mops.Create(ctx, name, input.Flags, input.Mode)
} else {
return fuse.EROFS
} }
if errno != 0 { if errno != 0 {
...@@ -336,8 +350,8 @@ func (b *rawBridge) Create(cancel <-chan struct{}, input *fuse.CreateIn, name st ...@@ -336,8 +350,8 @@ func (b *rawBridge) Create(cancel <-chan struct{}, input *fuse.CreateIn, name st
out.AttrValidNsec = temp.AttrValidNsec out.AttrValidNsec = temp.AttrValidNsec
b.setEntryOutTimeout(&out.EntryOut) b.setEntryOutTimeout(&out.EntryOut)
out.NodeId = child.nodeAttr.Ino child.setEntryOut(&out.EntryOut)
out.Mode = (out.Attr.Mode & 07777) | child.nodeAttr.Mode
return fuse.OK return fuse.OK
} }
...@@ -442,6 +456,7 @@ func (b *rawBridge) Link(cancel <-chan struct{}, input *fuse.LinkIn, name string ...@@ -442,6 +456,7 @@ func (b *rawBridge) Link(cancel <-chan struct{}, input *fuse.LinkIn, name string
b.addNewChild(parent, name, child, nil, 0, out) b.addNewChild(parent, name, child, nil, 0, out)
b.setEntryOutTimeout(out) b.setEntryOutTimeout(out)
child.setEntryOut(out)
return fuse.OK return fuse.OK
} }
return fuse.ENOTSUP return fuse.ENOTSUP
...@@ -458,6 +473,7 @@ func (b *rawBridge) Symlink(cancel <-chan struct{}, header *fuse.InHeader, targe ...@@ -458,6 +473,7 @@ func (b *rawBridge) Symlink(cancel <-chan struct{}, header *fuse.InHeader, targe
b.addNewChild(parent, name, child, nil, 0, out) b.addNewChild(parent, name, child, nil, 0, out)
b.setEntryOutTimeout(out) b.setEntryOutTimeout(out)
child.setEntryOut(out)
return fuse.OK return fuse.OK
} }
return fuse.ENOTSUP return fuse.ENOTSUP
......
...@@ -115,6 +115,13 @@ func initInode(n *Inode, ops InodeEmbedder, attr NodeAttr, bridge *rawBridge, pe ...@@ -115,6 +115,13 @@ func initInode(n *Inode, ops InodeEmbedder, attr NodeAttr, bridge *rawBridge, pe
} }
} }
// Set node ID and mode in EntryOut
func (n *Inode) setEntryOut(out *fuse.EntryOut) {
out.NodeId = n.nodeAttr.Ino
out.Ino = n.nodeAttr.Ino
out.Mode = (out.Attr.Mode & 07777) | n.nodeAttr.Mode
}
// NodeAttr returns the (Ino, Gen) tuple for this node. // NodeAttr returns the (Ino, Gen) tuple for this node.
func (n *Inode) NodeAttr() NodeAttr { func (n *Inode) NodeAttr() NodeAttr {
return n.nodeAttr return n.nodeAttr
......
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