From 4f66d66755da63c78b09201c6c72353009251cf2 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Wed, 2 Jan 2019 22:32:21 +0100 Subject: fusefrontend: add dirCache --- internal/fusefrontend/openbackingdir.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'internal/fusefrontend/openbackingdir.go') diff --git a/internal/fusefrontend/openbackingdir.go b/internal/fusefrontend/openbackingdir.go index 849a486..4da7fd6 100644 --- a/internal/fusefrontend/openbackingdir.go +++ b/internal/fusefrontend/openbackingdir.go @@ -10,7 +10,8 @@ import ( ) // openBackingDir opens the parent ciphertext directory of plaintext path -// "relPath" and returns the dirfd and the encrypted basename. +// "relPath". It returns the dirfd (opened with O_PATH) and the encrypted +// basename. // // The caller should then use Openat(dirfd, cName, ...) and friends. // For convenience, if relPath is "", cName is going to be ".". @@ -18,10 +19,10 @@ import ( // openBackingDir is secure against symlink races by using Openat and // ReadDirIVAt. func (fs *FS) openBackingDir(relPath string) (dirfd int, cName string, err error) { + dirRelPath := nametransform.Dir(relPath) // With PlaintextNames, we don't need to read DirIVs. Easy. if fs.args.PlaintextNames { - dir := nametransform.Dir(relPath) - dirfd, err = syscallcompat.OpenDirNofollow(fs.args.Cipherdir, dir) + dirfd, err = syscallcompat.OpenDirNofollow(fs.args.Cipherdir, dirRelPath) if err != nil { return -1, "", err } @@ -29,6 +30,13 @@ func (fs *FS) openBackingDir(relPath string) (dirfd int, cName string, err error cName = filepath.Base(relPath) return dirfd, cName, nil } + // Cache lookup + dirfd, iv := fs.dirCache.Lookup(dirRelPath) + if dirfd > 0 { + name := filepath.Base(relPath) + cName = fs.nameTransform.EncryptAndHashName(name, iv) + return dirfd, cName, nil + } // Open cipherdir (following symlinks) dirfd, err = syscall.Open(fs.args.Cipherdir, syscall.O_RDONLY|syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) if err != nil { @@ -49,6 +57,7 @@ func (fs *FS) openBackingDir(relPath string) (dirfd int, cName string, err error cName = fs.nameTransform.EncryptAndHashName(name, iv) // Last part? We are done. if i == len(parts)-1 { + fs.dirCache.Store(dirRelPath, dirfd, iv) break } // Not the last part? Descend into next directory. -- cgit v1.2.3