diff options
author | Jakob Unterwurzacher | 2021-04-03 13:08:28 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2021-04-03 13:08:28 +0200 |
commit | 24d5d39300629de48bb5a3700b0c219f741da028 (patch) | |
tree | 4706420655f30382027e0dd4943d4df5667de41f /internal/fusefrontend/node_helpers.go | |
parent | 6aae2aad97aee1d269fdbafab6eafa6ff997a73a (diff) |
fs: add initial dirfd caching
dirfd caching was temporarily removed when moving
to the v2api. Add it back to gain back some lost speed.
Diffstat (limited to 'internal/fusefrontend/node_helpers.go')
-rw-r--r-- | internal/fusefrontend/node_helpers.go | 32 |
1 files changed, 31 insertions, 1 deletions
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 } |