From 24d5d39300629de48bb5a3700b0c219f741da028 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 3 Apr 2021 13:08:28 +0200 Subject: fs: add initial dirfd caching dirfd caching was temporarily removed when moving to the v2api. Add it back to gain back some lost speed. --- internal/fusefrontend/node_helpers.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'internal/fusefrontend/node_helpers.go') diff --git a/internal/fusefrontend/node_helpers.go b/internal/fusefrontend/node_helpers.go index a8d1ebe..c44a559 100644 --- a/internal/fusefrontend/node_helpers.go +++ b/internal/fusefrontend/node_helpers.go @@ -9,6 +9,7 @@ import ( "github.com/hanwen/go-fuse/v2/fuse" + "github.com/rfjakob/gocryptfs/internal/nametransform" "github.com/rfjakob/gocryptfs/internal/syscallcompat" "github.com/rfjakob/gocryptfs/internal/tlog" ) @@ -83,11 +84,28 @@ func (n *Node) rootNode() *RootNode { // a child of this node. // If `child` is empty, the (dirfd, cName) pair refers to this node itself. func (n *Node) prepareAtSyscall(child string) (dirfd int, cName string, errno syscall.Errno) { + rn := n.rootNode() + + // Cache lookup + // TODO: also handle caching for root node & plaintextnames + cacheable := (child != "" && !rn.args.PlaintextNames) + if cacheable { + var iv []byte + dirfd, iv = rn.dirCache.Lookup(n) + if dirfd > 0 { + cName, err := rn.nameTransform.EncryptAndHashName(child, iv) + if err != nil { + return -1, "", fs.ToErrno(err) + } + return dirfd, cName, 0 + } + } + + // Slowpath p := n.Path() if child != "" { p = filepath.Join(p, child) } - rn := n.rootNode() if rn.isFiltered(p) { errno = syscall.EPERM return @@ -96,6 +114,18 @@ func (n *Node) prepareAtSyscall(child string) (dirfd int, cName string, errno sy if err != nil { errno = fs.ToErrno(err) } + + // Cache store + // TODO: also handle caching for root node & plaintextnames + if cacheable { + // TODO: openBackingDir already calls ReadDirIVAt(). Get the data out. + iv, err := nametransform.ReadDirIVAt(dirfd) + if err != nil { + syscall.Close(dirfd) + return -1, "", fs.ToErrno(err) + } + rn.dirCache.Store(n, dirfd, iv) + } return } -- cgit v1.2.3