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

nodefs: provide Inode.Root rather than Inode.IsRoot

Use this to simplify loopbackNode.
parent 30bc3e19
...@@ -13,8 +13,6 @@ import ( ...@@ -13,8 +13,6 @@ import (
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/hanwen/go-fuse/fuse"
) )
type parentData struct { type parentData struct {
...@@ -76,8 +74,9 @@ type Inode struct { ...@@ -76,8 +74,9 @@ type Inode struct {
// by calling removeRef. // by calling removeRef.
persistent bool persistent bool
// changeCounter increments every time the below mutable state // changeCounter increments every time the mutable state
// (lookupCount, nodeAttr, children, parents) is modified. // (lookupCount, persistent, children, parents) protected by
// mu is modified.
// //
// This is used in places where we have to relock inode into inode // This is used in places where we have to relock inode into inode
// group lock, and after locking the group we have to check if inode // group lock, and after locking the group we have to check if inode
...@@ -113,9 +112,9 @@ func (n *Inode) Mode() uint32 { ...@@ -113,9 +112,9 @@ func (n *Inode) Mode() uint32 {
return n.nodeAttr.Mode return n.nodeAttr.Mode
} }
// IsRoot returns true if this is the root of the FUSE mount. // Returns the root of the tree
func (n *Inode) IsRoot() bool { func (n *Inode) Root() *Inode {
return n.nodeAttr.Ino == fuse.FUSE_ROOT_ID return n.bridge.root
} }
// debugString is used for debugging. Racy. // debugString is used for debugging. Racy.
......
...@@ -16,16 +16,10 @@ import ( ...@@ -16,16 +16,10 @@ import (
type loopbackRoot struct { type loopbackRoot struct {
loopbackNode loopbackNode
root string rootPath string
rootDev uint64 rootDev uint64
} }
func (n *loopbackRoot) newLoopbackNode() *loopbackNode {
return &loopbackNode{
rootNode: n,
}
}
func (n *loopbackNode) StatFs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { func (n *loopbackNode) StatFs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno {
s := syscall.Statfs_t{} s := syscall.Statfs_t{}
err := syscall.Statfs(n.path(), &s) err := syscall.Statfs(n.path(), &s)
...@@ -37,9 +31,8 @@ func (n *loopbackNode) StatFs(ctx context.Context, out *fuse.StatfsOut) syscall. ...@@ -37,9 +31,8 @@ func (n *loopbackNode) StatFs(ctx context.Context, out *fuse.StatfsOut) syscall.
} }
func (n *loopbackRoot) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.Errno { func (n *loopbackRoot) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.Errno {
var err error = nil
st := syscall.Stat_t{} st := syscall.Stat_t{}
err = syscall.Stat(n.root, &st) err := syscall.Stat(n.rootPath, &st)
if err != nil { if err != nil {
return ToErrno(err) return ToErrno(err)
} }
...@@ -49,13 +42,15 @@ func (n *loopbackRoot) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.E ...@@ -49,13 +42,15 @@ func (n *loopbackRoot) GetAttr(ctx context.Context, out *fuse.AttrOut) syscall.E
type loopbackNode struct { type loopbackNode struct {
DefaultOperations DefaultOperations
}
rootNode *loopbackRoot func (n *loopbackNode) root() *loopbackRoot {
return n.Inode().Root().Operations().(*loopbackRoot)
} }
func (n *loopbackNode) path() string { func (n *loopbackNode) path() string {
path := n.Inode().Path(nil) path := n.Inode().Path(nil)
return filepath.Join(n.rootNode.root, path) return filepath.Join(n.root().rootPath, path)
} }
func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) { func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
...@@ -68,8 +63,8 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO ...@@ -68,8 +63,8 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO
} }
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := n.rootNode.newLoopbackNode() node := &loopbackNode{}
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.root().idFromStat(&st))
return ch, 0 return ch, 0
} }
...@@ -87,8 +82,8 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32 ...@@ -87,8 +82,8 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := n.rootNode.newLoopbackNode() node := &loopbackNode{}
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.root().idFromStat(&st))
return ch, 0 return ch, 0
} }
...@@ -107,8 +102,8 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out ...@@ -107,8 +102,8 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := n.rootNode.newLoopbackNode() node := &loopbackNode{}
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.root().idFromStat(&st))
return ch, 0 return ch, 0
} }
...@@ -178,8 +173,8 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo ...@@ -178,8 +173,8 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo
return nil, nil, 0, ToErrno(err) return nil, nil, 0, ToErrno(err)
} }
node := n.rootNode.newLoopbackNode() node := &loopbackNode{}
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.root().idFromStat(&st))
lf := NewLoopbackFile(fd) lf := NewLoopbackFile(fd)
return ch, lf, 0, 0 return ch, lf, 0, 0
} }
...@@ -195,8 +190,8 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu ...@@ -195,8 +190,8 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu
syscall.Unlink(p) syscall.Unlink(p)
return nil, ToErrno(err) return nil, ToErrno(err)
} }
node := n.rootNode.newLoopbackNode() node := &loopbackNode{}
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.root().idFromStat(&st))
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
return ch, 0 return ch, 0
...@@ -215,8 +210,8 @@ func (n *loopbackNode) Link(ctx context.Context, target Operations, name string, ...@@ -215,8 +210,8 @@ func (n *loopbackNode) Link(ctx context.Context, target Operations, name string,
syscall.Unlink(p) syscall.Unlink(p)
return nil, ToErrno(err) return nil, ToErrno(err)
} }
node := n.rootNode.newLoopbackNode() node := &loopbackNode{}
ch := n.inode().NewInode(ctx, node, n.rootNode.idFromStat(&st)) ch := n.inode().NewInode(ctx, node, n.root().idFromStat(&st))
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
return ch, 0 return ch, 0
...@@ -288,9 +283,8 @@ func NewLoopbackRoot(root string) (DirOperations, error) { ...@@ -288,9 +283,8 @@ func NewLoopbackRoot(root string) (DirOperations, error) {
} }
n := &loopbackRoot{ n := &loopbackRoot{
root: root, rootPath: root,
rootDev: uint64(st.Dev), rootDev: uint64(st.Dev),
} }
n.rootNode = n
return n, nil return n, nil
} }
...@@ -47,13 +47,18 @@ func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newN ...@@ -47,13 +47,18 @@ func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newN
if err := syscall.Fstat(fd1, &st); err != nil { if err := syscall.Fstat(fd1, &st); err != nil {
return ToErrno(err) return ToErrno(err)
} }
if !n.Inode().IsRoot() && n.Inode().NodeAttr().Ino != n.rootNode.idFromStat(&st).Ino {
// Double check that nodes didn't change from under us.
inode := n.Inode()
if inode.Root() != inode && inode.NodeAttr().Ino != n.root().idFromStat(&st).Ino {
return syscall.EBUSY return syscall.EBUSY
} }
if err := syscall.Fstat(fd2, &st); err != nil { if err := syscall.Fstat(fd2, &st); err != nil {
return ToErrno(err) return ToErrno(err)
} }
if !newparent.Inode().IsRoot() && newparent.Inode().NodeAttr().Ino != n.rootNode.idFromStat(&st).Ino {
newinode := newparent.Inode()
if newinode.Root() != newinode && newinode.NodeAttr().Ino != n.root().idFromStat(&st).Ino {
return syscall.EBUSY return syscall.EBUSY
} }
......
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