From 6aa9f5636f03392b5da5fc19dc4ea908e2e55e26 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 11 Jun 2020 23:39:27 +0200 Subject: v2api: implement Lookup() Compiles, but untested otherwise. No caching. --- internal/fusefrontend/node.go | 54 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) (limited to 'internal/fusefrontend/node.go') diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go index fde6a1a..f246408 100644 --- a/internal/fusefrontend/node.go +++ b/internal/fusefrontend/node.go @@ -2,13 +2,18 @@ package fusefrontend import ( "context" + "path/filepath" "syscall" + "golang.org/x/sys/unix" + "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" "github.com/rfjakob/gocryptfs/internal/contentenc" + "github.com/rfjakob/gocryptfs/internal/inomap" "github.com/rfjakob/gocryptfs/internal/nametransform" + "github.com/rfjakob/gocryptfs/internal/syscallcompat" ) // Node is a file or directory in the filesystem tree @@ -20,25 +25,66 @@ type Node struct { // RootNode is the root of the filesystem tree of Nodes. type RootNode struct { Node - - // This flag is set to zero each time fs.isFiltered() is called + // args stores configuration arguments + args Args + // Filename encryption helper + nameTransform nametransform.NameTransformer + // Content encryption helper + contentEnc *contentenc.ContentEnc + // IsIdle flag is set to zero each time fs.isFiltered() is called // (uint32 so that it can be reset with CompareAndSwapUint32). // When -idle was used when mounting, idleMonitor() sets it to 1 // periodically. IsIdle uint32 + + // inoMap translates inode numbers from different devices to unique inode + // numbers. + inoMap *inomap.InoMap } func NewRootNode(args Args, c *contentenc.ContentEnc, n nametransform.NameTransformer) *RootNode { // TODO - return &RootNode{} + return &RootNode{ + args: args, + nameTransform: n, + contentEnc: c, + inoMap: inomap.New(), + } } +// path returns the relative plaintext path of this node func (n *Node) path() string { return n.Path(n.Root()) } +func (n *Node) rootNode() *RootNode { + return n.Root().Operations().(*RootNode) +} + func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - return nil, 1 + rn := n.rootNode() + p := filepath.Join(n.path(), name) + dirfd, cName, err := rn.openBackingDir(p) + if err != nil { + return nil, fs.ToErrno(err) + } + // Get device number and inode number into `st` + st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + return nil, fs.ToErrno(err) + } + // Get unique inode number + rn.inoMap.TranslateStat(st) + out.Attr.FromStat(st) + // Create child node + id := fs.StableAttr{ + Mode: uint32(st.Mode), + Gen: 1, + Ino: st.Ino, + } + node := &Node{} + ch := n.NewInode(ctx, node, id) + return ch, 0 } func (n *Node) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) syscall.Errno { -- cgit v1.2.3