Commit da0be912 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys Committed by Han-Wen Nienhuys

fs: prepare for exposing loopback types

Document LoopbackNode, LoopbackRoot. Use loopbackRoot.newNode() for
creating new nodes

Change-Id: I625c7706
parent cb685274
...@@ -13,9 +13,30 @@ import ( ...@@ -13,9 +13,30 @@ import (
"github.com/hanwen/go-fuse/v2/fuse" "github.com/hanwen/go-fuse/v2/fuse"
) )
// loopbackRoot holds the parameters for creating a new loopback
// filesystem. Loopback filesystem delegate their operations to an
// underlying POSIX file system.
type loopbackRoot struct { type loopbackRoot struct {
rootPath string // The path to the root of the underlying file system.
rootDev uint64 Path string
// The device on which the Path resides. This must be set if
// the underlying filesystem crosses file systems.
Dev uint64
// NewNode returns a new InodeEmbedder to be used to respond
// to a LOOKUP/CREATE/MKDIR/MKNOD opcode. If not set, use a
// LoopbackNode.
NewNode func(rootData *loopbackRoot) InodeEmbedder
}
func (r *loopbackRoot) newNode() InodeEmbedder {
if r.NewNode != nil {
return r.NewNode(r)
}
return &loopbackNode{
RootData: r,
}
} }
func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) StableAttr { func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) StableAttr {
...@@ -27,7 +48,7 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) StableAttr { ...@@ -27,7 +48,7 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) StableAttr {
// encompass multiple mounts will reflect the inode numbers of // encompass multiple mounts will reflect the inode numbers of
// the underlying filesystem // the underlying filesystem
swapped := (uint64(st.Dev) << 32) | (uint64(st.Dev) >> 32) swapped := (uint64(st.Dev) << 32) | (uint64(st.Dev) >> 32)
swappedRootDev := (r.rootDev << 32) | (r.rootDev >> 32) swappedRootDev := (r.Dev << 32) | (r.Dev >> 32)
return StableAttr{ return StableAttr{
Mode: uint32(st.Mode), Mode: uint32(st.Mode),
Gen: 1, Gen: 1,
...@@ -37,10 +58,11 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) StableAttr { ...@@ -37,10 +58,11 @@ func (r *loopbackRoot) idFromStat(st *syscall.Stat_t) StableAttr {
} }
} }
// LoopbackNode is a filesystem node in a loopback file system.
type loopbackNode struct { type loopbackNode struct {
Inode Inode
rootData *loopbackRoot RootData *loopbackRoot
} }
var _ = (NodeStatfser)((*loopbackNode)(nil)) var _ = (NodeStatfser)((*loopbackNode)(nil))
...@@ -76,7 +98,7 @@ func (n *loopbackNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall. ...@@ -76,7 +98,7 @@ func (n *loopbackNode) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.
func (n *loopbackNode) path() string { func (n *loopbackNode) path() string {
path := n.Path(n.Root()) path := n.Path(n.Root())
return filepath.Join(n.rootData.rootPath, path) return filepath.Join(n.RootData.Path, 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) {
...@@ -89,8 +111,8 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO ...@@ -89,8 +111,8 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO
} }
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := &loopbackNode{rootData: n.rootData} node := n.RootData.newNode()
ch := n.NewInode(ctx, node, n.rootData.idFromStat(&st)) ch := n.NewInode(ctx, node, n.RootData.idFromStat(&st))
return ch, 0 return ch, 0
} }
...@@ -122,8 +144,8 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32 ...@@ -122,8 +144,8 @@ func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := &loopbackNode{rootData: n.rootData} node := n.RootData.newNode()
ch := n.NewInode(ctx, node, n.rootData.idFromStat(&st)) ch := n.NewInode(ctx, node, n.RootData.idFromStat(&st))
return ch, 0 return ch, 0
} }
...@@ -143,8 +165,8 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out ...@@ -143,8 +165,8 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
node := &loopbackNode{rootData: n.rootData} node := n.RootData.newNode()
ch := n.NewInode(ctx, node, n.rootData.idFromStat(&st)) ch := n.NewInode(ctx, node, n.RootData.idFromStat(&st))
return ch, 0 return ch, 0
} }
...@@ -167,7 +189,7 @@ func (n *loopbackNode) Rename(ctx context.Context, name string, newParent InodeE ...@@ -167,7 +189,7 @@ func (n *loopbackNode) Rename(ctx context.Context, name string, newParent InodeE
} }
p1 := filepath.Join(n.path(), name) p1 := filepath.Join(n.path(), name)
p2 := filepath.Join(n.rootData.rootPath, newParent.EmbeddedInode().Path(nil), newName) p2 := filepath.Join(n.RootData.Path, newParent.EmbeddedInode().Path(nil), newName)
err := syscall.Rename(p1, p2) err := syscall.Rename(p1, p2)
return ToErrno(err) return ToErrno(err)
...@@ -189,8 +211,8 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo ...@@ -189,8 +211,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 := &loopbackNode{rootData: n.rootData} node := n.RootData.newNode()
ch := n.NewInode(ctx, node, n.rootData.idFromStat(&st)) ch := n.NewInode(ctx, node, n.RootData.idFromStat(&st))
lf := NewLoopbackFile(fd) lf := NewLoopbackFile(fd)
out.FromStat(&st) out.FromStat(&st)
...@@ -209,8 +231,8 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu ...@@ -209,8 +231,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 := &loopbackNode{rootData: n.rootData} node := n.RootData.newNode()
ch := n.NewInode(ctx, node, n.rootData.idFromStat(&st)) ch := n.NewInode(ctx, node, n.RootData.idFromStat(&st))
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
return ch, 0 return ch, 0
...@@ -219,7 +241,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu ...@@ -219,7 +241,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu
func (n *loopbackNode) Link(ctx context.Context, target InodeEmbedder, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) { func (n *loopbackNode) Link(ctx context.Context, target InodeEmbedder, name string, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := syscall.Link(filepath.Join(n.rootData.rootPath, target.EmbeddedInode().Path(nil)), p) err := syscall.Link(filepath.Join(n.RootData.Path, target.EmbeddedInode().Path(nil)), p)
if err != nil { if err != nil {
return nil, ToErrno(err) return nil, ToErrno(err)
} }
...@@ -228,8 +250,8 @@ func (n *loopbackNode) Link(ctx context.Context, target InodeEmbedder, name stri ...@@ -228,8 +250,8 @@ func (n *loopbackNode) Link(ctx context.Context, target InodeEmbedder, name stri
syscall.Unlink(p) syscall.Unlink(p)
return nil, ToErrno(err) return nil, ToErrno(err)
} }
node := &loopbackNode{rootData: n.rootData} node := n.RootData.newNode()
ch := n.NewInode(ctx, node, n.rootData.idFromStat(&st)) ch := n.NewInode(ctx, node, n.RootData.idFromStat(&st))
out.Attr.FromStat(&st) out.Attr.FromStat(&st)
return ch, 0 return ch, 0
...@@ -381,12 +403,9 @@ func NewLoopbackRoot(rootPath string) (InodeEmbedder, error) { ...@@ -381,12 +403,9 @@ func NewLoopbackRoot(rootPath string) (InodeEmbedder, error) {
} }
root := &loopbackRoot{ root := &loopbackRoot{
rootPath: rootPath, Path: rootPath,
rootDev: uint64(st.Dev), Dev: uint64(st.Dev),
} }
n := &loopbackNode{ return root.newNode(), nil
rootData: root,
}
return n, nil
} }
...@@ -40,7 +40,7 @@ func (n *loopbackNode) renameExchange(name string, newparent InodeEmbedder, newN ...@@ -40,7 +40,7 @@ func (n *loopbackNode) renameExchange(name string, newparent InodeEmbedder, newN
return ToErrno(err) return ToErrno(err)
} }
defer syscall.Close(fd1) defer syscall.Close(fd1)
p2 := filepath.Join(n.rootData.rootPath, newparent.EmbeddedInode().Path(nil)) p2 := filepath.Join(n.RootData.Path, newparent.EmbeddedInode().Path(nil))
fd2, err := syscall.Open(p2, syscall.O_DIRECTORY, 0) fd2, err := syscall.Open(p2, syscall.O_DIRECTORY, 0)
defer syscall.Close(fd2) defer syscall.Close(fd2)
if err != nil { if err != nil {
...@@ -54,7 +54,7 @@ func (n *loopbackNode) renameExchange(name string, newparent InodeEmbedder, newN ...@@ -54,7 +54,7 @@ func (n *loopbackNode) renameExchange(name string, newparent InodeEmbedder, newN
// Double check that nodes didn't change from under us. // Double check that nodes didn't change from under us.
inode := &n.Inode inode := &n.Inode
if inode.Root() != inode && inode.StableAttr().Ino != n.rootData.idFromStat(&st).Ino { if inode.Root() != inode && inode.StableAttr().Ino != n.RootData.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 {
...@@ -62,7 +62,7 @@ func (n *loopbackNode) renameExchange(name string, newparent InodeEmbedder, newN ...@@ -62,7 +62,7 @@ func (n *loopbackNode) renameExchange(name string, newparent InodeEmbedder, newN
} }
newinode := newparent.EmbeddedInode() newinode := newparent.EmbeddedInode()
if newinode.Root() != newinode && newinode.StableAttr().Ino != n.rootData.idFromStat(&st).Ino { if newinode.Root() != newinode && newinode.StableAttr().Ino != n.RootData.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