From 5190cc09bbc8afca75986dbb14f09e62eda33b61 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 6 Aug 2017 21:59:15 +0200 Subject: nametransform: move diriv cache into it's own package Needs some space to grow. renamed: internal/nametransform/diriv_cache.go -> internal/nametransform/dirivcache/dirivcache.go --- internal/nametransform/diriv.go | 6 +-- internal/nametransform/diriv_cache.go | 63 ------------------------- internal/nametransform/dirivcache/dirivcache.go | 63 +++++++++++++++++++++++++ internal/nametransform/names.go | 3 +- 4 files changed, 68 insertions(+), 67 deletions(-) delete mode 100644 internal/nametransform/diriv_cache.go create mode 100644 internal/nametransform/dirivcache/dirivcache.go (limited to 'internal') diff --git a/internal/nametransform/diriv.go b/internal/nametransform/diriv.go index 5fca1ef..6746f04 100644 --- a/internal/nametransform/diriv.go +++ b/internal/nametransform/diriv.go @@ -125,7 +125,7 @@ func (be *NameTransform) EncryptPathDirIV(plainPath string, rootDir string) (cip // Check if the DirIV is cached. This catches the case of the user iterating // over files in a directory pretty well. parentDir := filepath.Dir(plainPath) - iv, cParentDir := be.DirIVCache.lookup(parentDir) + iv, cParentDir := be.DirIVCache.Lookup(parentDir) if iv != nil { cBaseName := be.encryptAndHashName(baseName, iv) return filepath.Join(cParentDir, cBaseName), nil @@ -138,7 +138,7 @@ func (be *NameTransform) EncryptPathDirIV(plainPath string, rootDir string) (cip // cached. Then we can skip a few items in the directory walk. // This catches the case of walking directories recursively. parentDir2 := filepath.Dir(parentDir) - iv, cParentDir = be.DirIVCache.lookup(parentDir2) + iv, cParentDir = be.DirIVCache.Lookup(parentDir2) if iv != nil { parentDirBase := filepath.Base(parentDir) cBaseName := be.encryptAndHashName(parentDirBase, iv) @@ -159,6 +159,6 @@ func (be *NameTransform) EncryptPathDirIV(plainPath string, rootDir string) (cip } // Cache the final DirIV cParentDir = filepath.Dir(cipherPath) - be.DirIVCache.store(parentDir, iv, cParentDir) + be.DirIVCache.Store(parentDir, iv, cParentDir) return cipherPath, nil } diff --git a/internal/nametransform/diriv_cache.go b/internal/nametransform/diriv_cache.go deleted file mode 100644 index 82c5bd3..0000000 --- a/internal/nametransform/diriv_cache.go +++ /dev/null @@ -1,63 +0,0 @@ -package nametransform - -import ( - "sync" - "time" -) - -// Single-entry DirIV cache. Stores the directory IV and the encrypted -// path. -type dirIVCache struct { - // Directory the DirIV belongs to - dir string - // Time the entry expires. - // The cached entry my become out-of-date if the ciphertext directory is - // modifed behind the back of gocryptfs. Having an expiry time limits the - // inconstency to one second, like attr_timeout does for the kernel - // getattr cache. - expiry time.Time - - // The DirIV - iv []byte - // Ecrypted version of "dir" - cDir string - - // Invalidated? - cleared bool - sync.RWMutex -} - -// lookup - fetch entry for "dir" from the cache -func (c *dirIVCache) lookup(dir string) ([]byte, string) { - c.RLock() - defer c.RUnlock() - if c.cleared || c.dir != dir { - return nil, "" - } - if time.Since(c.expiry) > 0 { - c.cleared = true - return nil, "" - } - return c.iv, c.cDir -} - -// store - write entry for "dir" into the cache -func (c *dirIVCache) store(dir string, iv []byte, cDir string) { - c.Lock() - defer c.Unlock() - c.cleared = false - c.iv = iv - c.dir = dir - c.cDir = cDir - // Set expiry time one second into the future - c.expiry = time.Now().Add(1 * time.Second) -} - -// Clear ... clear the cache. -// Exported because it is called from fusefrontend when directories are -// renamed or deleted. -func (c *dirIVCache) Clear() { - c.Lock() - defer c.Unlock() - c.cleared = true -} diff --git a/internal/nametransform/dirivcache/dirivcache.go b/internal/nametransform/dirivcache/dirivcache.go new file mode 100644 index 0000000..890ebac --- /dev/null +++ b/internal/nametransform/dirivcache/dirivcache.go @@ -0,0 +1,63 @@ +package dirivcache + +import ( + "sync" + "time" +) + +// Single-entry DirIV cache. Stores the directory IV and the encrypted +// path. +type DirIVCache struct { + // Directory the DirIV belongs to + dir string + // Time the entry expires. + // The cached entry my become out-of-date if the ciphertext directory is + // modifed behind the back of gocryptfs. Having an expiry time limits the + // inconstency to one second, like attr_timeout does for the kernel + // getattr cache. + expiry time.Time + + // The DirIV + iv []byte + // Ecrypted version of "dir" + cDir string + + // Invalidated? + cleared bool + sync.RWMutex +} + +// lookup - fetch entry for "dir" from the cache +func (c *DirIVCache) Lookup(dir string) ([]byte, string) { + c.RLock() + defer c.RUnlock() + if c.cleared || c.dir != dir { + return nil, "" + } + if time.Since(c.expiry) > 0 { + c.cleared = true + return nil, "" + } + return c.iv, c.cDir +} + +// store - write entry for "dir" into the cache +func (c *DirIVCache) Store(dir string, iv []byte, cDir string) { + c.Lock() + defer c.Unlock() + c.cleared = false + c.iv = iv + c.dir = dir + c.cDir = cDir + // Set expiry time one second into the future + c.expiry = time.Now().Add(1 * time.Second) +} + +// Clear ... clear the cache. +// Exported because it is called from fusefrontend when directories are +// renamed or deleted. +func (c *DirIVCache) Clear() { + c.Lock() + defer c.Unlock() + c.cleared = true +} diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go index 3447583..94fa453 100644 --- a/internal/nametransform/names.go +++ b/internal/nametransform/names.go @@ -9,6 +9,7 @@ import ( "github.com/rfjakob/eme" + "github.com/rfjakob/gocryptfs/internal/nametransform/dirivcache" "github.com/rfjakob/gocryptfs/internal/tlog" ) @@ -16,7 +17,7 @@ import ( type NameTransform struct { emeCipher *eme.EMECipher longNames bool - DirIVCache dirIVCache + DirIVCache dirivcache.DirIVCache // B64 = either base64.URLEncoding or base64.RawURLEncoding, depeding // on the Raw64 feature flag B64 *base64.Encoding -- cgit v1.2.3