diff options
author | Jakob Unterwurzacher | 2019-01-02 22:32:21 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2019-01-03 15:31:13 +0100 |
commit | 4f66d66755da63c78b09201c6c72353009251cf2 (patch) | |
tree | 9eb4e937419e7255c56df04d3c30d36185e1a337 /internal/fusefrontend/openbackingdir.go | |
parent | f6dad8d0fae25b5d88ad036b841fea10b7296ccb (diff) |
fusefrontend: add dirCache
Diffstat (limited to 'internal/fusefrontend/openbackingdir.go')
-rw-r--r-- | internal/fusefrontend/openbackingdir.go | 15 |
1 files changed, 12 insertions, 3 deletions
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. |