vfs: fix cache cleaning on startup

Previous to this fix the vfs cache wasn't being cleaned properly on
startup as the atimes of the existing files were being ignored.
This commit is contained in:
Nick Craig-Wood 2018-02-02 12:06:42 +00:00
parent fc8641809e
commit 3f8d286a75
2 changed files with 24 additions and 11 deletions

View File

@ -145,16 +145,20 @@ func (c *cache) mkdir(name string) (string, error) {
// _get gets name from the cache or creates a new one // _get gets name from the cache or creates a new one
// //
// It returns the item and found as to whether this item was found in
// the cache (or just created).
//
// name should be a remote path not an osPath // name should be a remote path not an osPath
// //
// must be called with itemMu held // must be called with itemMu held
func (c *cache) _get(isFile bool, name string) *cacheItem { func (c *cache) _get(isFile bool, name string) (item *cacheItem, found bool) {
item := c.item[name] item = c.item[name]
if item == nil { found = item != nil
if !found {
item = newCacheItem(isFile) item = newCacheItem(isFile)
c.item[name] = item c.item[name] = item
} }
return item return item, found
} }
// get gets name from the cache or creates a new one // get gets name from the cache or creates a new one
@ -162,7 +166,7 @@ func (c *cache) _get(isFile bool, name string) *cacheItem {
// name should be a remote path not an osPath // name should be a remote path not an osPath
func (c *cache) get(name string) *cacheItem { func (c *cache) get(name string) *cacheItem {
c.itemMu.Lock() c.itemMu.Lock()
item := c._get(true, name) item, _ := c._get(true, name)
c.itemMu.Unlock() c.itemMu.Unlock()
return item return item
} }
@ -173,8 +177,8 @@ func (c *cache) get(name string) *cacheItem {
// name should be a remote path not an osPath // name should be a remote path not an osPath
func (c *cache) updateTime(name string, when time.Time) { func (c *cache) updateTime(name string, when time.Time) {
c.itemMu.Lock() c.itemMu.Lock()
item := c._get(true, name) item, found := c._get(true, name)
if when.Sub(item.atime) > 0 { if !found || when.Sub(item.atime) > 0 {
fs.Debugf(name, "updateTime: setting atime to %v", when) fs.Debugf(name, "updateTime: setting atime to %v", when)
item.atime = when item.atime = when
} }
@ -186,7 +190,7 @@ func (c *cache) updateTime(name string, when time.Time) {
// name should be a remote path not an osPath // name should be a remote path not an osPath
func (c *cache) _open(isFile bool, name string) { func (c *cache) _open(isFile bool, name string) {
for { for {
item := c._get(isFile, name) item, _ := c._get(isFile, name)
item.opens++ item.opens++
item.atime = time.Now() item.atime = time.Now()
if name == "" { if name == "" {
@ -228,7 +232,7 @@ func (c *cache) cacheDir(name string) {
// _close marks name as closed - must be called with the lock held // _close marks name as closed - must be called with the lock held
func (c *cache) _close(isFile bool, name string) { func (c *cache) _close(isFile bool, name string) {
for { for {
item := c._get(isFile, name) item, _ := c._get(isFile, name)
item.opens-- item.opens--
item.atime = time.Now() item.atime = time.Now()
if item.opens < 0 { if item.opens < 0 {

View File

@ -3,7 +3,6 @@ package vfs
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@ -123,7 +122,6 @@ name="potato" isFile=true opens=1`, itemAsString(c))
atime := times.Get(fi).AccessTime() atime := times.Get(fi).AccessTime()
// updateAtimes // updateAtimes
log.Printf("updateAtimes")
item = c.get("potato") item = c.get("potato")
item.atime = time.Now().Add(-24 * time.Hour) item.atime = time.Now().Add(-24 * time.Hour)
err = c.updateAtimes() err = c.updateAtimes()
@ -133,6 +131,17 @@ name="potato" isFile=true opens=1`, itemAsString(c))
item = c.get("potato") item = c.get("potato")
assert.Equal(t, atime, item.atime) assert.Equal(t, atime, item.atime)
// updateAtimes - not in the cache
oldItem := item
delete(c.item, "potato") // remove from cache
err = c.updateAtimes()
require.NoError(t, err)
assert.Equal(t, `name="" isFile=false opens=1
name="potato" isFile=true opens=0`, itemAsString(c))
item = c.get("potato")
assert.Equal(t, atime, item.atime)
c.item["potato"] = oldItem // restore to cache
// try purging with file open // try purging with file open
c.purgeOld(10 * time.Second) c.purgeOld(10 * time.Second)
_, err = os.Stat(p) _, err = os.Stat(p)