diff options
Diffstat (limited to 'internal/nametransform/dirivcache')
| -rw-r--r-- | internal/nametransform/dirivcache/dirivcache.go | 63 | 
1 files changed, 63 insertions, 0 deletions
| 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 +} | 
