From 2b7957cc74dcbbdab8e5b600fa6994207f32dbd6 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 16 Apr 2018 16:38:32 +0100 Subject: [PATCH] vfs: Only make the VFS cache if --vfs-cache-mode > Off This stops the cache cleaner running unnecessarily and saves resources. This also helps with issue #2227 which was caused by a second mount deleting objects in the first mounts cache. --- cmd/mountlib/mounttest/fs.go | 2 +- vfs/file.go | 3 +-- vfs/read_write_test.go | 15 +++++++++------ vfs/vfs.go | 31 ++++++++++++++++++++++--------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/cmd/mountlib/mounttest/fs.go b/cmd/mountlib/mounttest/fs.go index 7f5043317..489a66d29 100644 --- a/cmd/mountlib/mounttest/fs.go +++ b/cmd/mountlib/mounttest/fs.go @@ -215,7 +215,7 @@ func (r *Run) cacheMode(cacheMode vfs.CacheMode) { log.Printf("Failed to cleanup the VFS cache: %v", err) } // Reset the cache mode - r.vfs.Opt.CacheMode = cacheMode + r.vfs.SetCacheMode(cacheMode) // Flush the directory cache r.vfs.FlushDirCache() diff --git a/vfs/file.go b/vfs/file.go index c556fb5d8..95c11216b 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -481,8 +481,7 @@ func (f *File) Open(flags int) (fd Handle, err error) { // Open the correct sort of handle CacheMode := f.d.vfs.Opt.CacheMode - opens := f.d.vfs.cache.opens(f.Path()) - if CacheMode >= CacheModeMinimal && opens > 0 { + if CacheMode >= CacheModeMinimal && f.d.vfs.cache.opens(f.Path()) > 0 { fd, err = f.openRW(flags) } else if read && write { if CacheMode >= CacheModeMinimal { diff --git a/vfs/read_write_test.go b/vfs/read_write_test.go index b42aca7d0..63fb1beaf 100644 --- a/vfs/read_write_test.go +++ b/vfs/read_write_test.go @@ -21,8 +21,9 @@ func cleanup(t *testing.T, r *fstest.Run, vfs *VFS) { // Open a file for write func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) { - vfs := New(r.Fremote, nil) - vfs.Opt.CacheMode = CacheModeFull + opt := DefaultOpt + opt.CacheMode = CacheModeFull + vfs := New(r.Fremote, &opt) file1 := r.WriteObject("dir/file1", "0123456789abcdef", t1) fstest.CheckItems(t, r.Fremote, file1) @@ -37,8 +38,9 @@ func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) { // Open a file for write func rwHandleCreateWriteOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) { - vfs := New(r.Fremote, nil) - vfs.Opt.CacheMode = CacheModeFull + opt := DefaultOpt + opt.CacheMode = CacheModeFull + vfs := New(r.Fremote, &opt) h, err := vfs.OpenFile("file1", os.O_WRONLY|os.O_CREATE, 0777) require.NoError(t, err) @@ -555,10 +557,11 @@ func testRWFileHandleOpenTest(t *testing.T, vfs *VFS, test *openTest) { func TestRWFileHandleOpenTests(t *testing.T) { r := fstest.NewRun(t) - vfs := New(r.Fremote, nil) + opt := DefaultOpt + opt.CacheMode = CacheModeFull + vfs := New(r.Fremote, &opt) defer cleanup(t, r, vfs) - vfs.Opt.CacheMode = CacheModeFull for _, test := range openTests { testRWFileHandleOpenTest(t, vfs, &test) } diff --git a/vfs/vfs.go b/vfs/vfs.go index 52cb15e6b..923b3e8a6 100644 --- a/vfs/vfs.go +++ b/vfs/vfs.go @@ -224,21 +224,31 @@ func New(f fs.Fs, opt *Options) *VFS { } } - // Create the cache - ctx, cancel := context.WithCancel(context.Background()) - vfs.cancel = cancel - cache, err := newCache(ctx, f, &vfs.Opt) // FIXME pass on context or get from Opt? - if err != nil { - // FIXME - panic(fmt.Sprintf("failed to create local cache: %v", err)) - } - vfs.cache = cache + vfs.SetCacheMode(vfs.Opt.CacheMode) // add the remote control vfs.addRC() return vfs } +// SetCacheMode change the cache mode +func (vfs *VFS) SetCacheMode(cacheMode CacheMode) { + vfs.Shutdown() + vfs.cache = nil + if vfs.Opt.CacheMode > CacheModeOff { + ctx, cancel := context.WithCancel(context.Background()) + cache, err := newCache(ctx, vfs.f, &vfs.Opt) // FIXME pass on context or get from Opt? + if err != nil { + fs.Errorf(nil, "Failed to create vfs cache - disabling: %v", err) + vfs.Opt.CacheMode = CacheModeOff + cancel() + return + } + vfs.cancel = cancel + vfs.cache = cache + } +} + // Shutdown stops any background go-routines func (vfs *VFS) Shutdown() { if vfs.cancel != nil { @@ -249,6 +259,9 @@ func (vfs *VFS) Shutdown() { // CleanUp deletes the contents of the on disk cache func (vfs *VFS) CleanUp() error { + if vfs.Opt.CacheMode == CacheModeOff { + return nil + } return vfs.cache.cleanUp() }