vfs: fix a VFS being reused while it is being shut down

When the last user of a VFS shut it down at the same time as a new
user of the same remote asked for one, the new user could be given the
VFS being shut down, with its cache and background tasks stopped.

Only a VFS which is still in use is now reused, otherwise a new one is
made.

(cherry picked from commit c62aa2adc9)
This commit is contained in:
Nick Craig-Wood committed 2026-10-08 17:17:11 +01:00
1 parent 5977137b3b
commit b4cb0426a3
2 files changed
+19 -2

No files matched your search

+3 -2
View File
@@ -234,9 +234,10 @@ func New(ctx context.Context, f fs.Fs, opt *vfscommon.Options) *VFS {
defer activeMu.Unlock()
configName := fs.ConfigString(f)
for _, activeVFS := range active[configName] {
if vfs.Opt == activeVFS.Opt {
// A VFS whose last reference has gone is being shut down
// but may not have removed itself from the cache yet.
if vfs.Opt == activeVFS.Opt && activeVFS.Hold() {
fs.Debugf(f, "Reusing VFS from active cache")
activeVFS.inUse.Add(1)
cancel()
return activeVFS
}
+16
View File
@@ -174,6 +174,22 @@ func TestVFSHold(t *testing.T) {
assert.False(t, vfs.Hold(), "VFS held after being shut down")
}
// TestVFSNewShuttingDown checks New doesn't reuse a VFS which is being
// shut down but hasn't yet removed itself from the active cache.
func TestVFSNewShuttingDown(t *testing.T) {
r := fstest.NewRun(t)
vfs := New(context.Background(), r.Fremote, nil)
// The state Shutdown leaves the VFS in while it waits for activeMu
vfs.inUse.Store(0)
vfs2 := New(context.Background(), r.Fremote, nil)
assert.NotSame(t, vfs, vfs2, "reused a VFS being shut down")
assert.Equal(t, int32(0), vfs.inUse.Load())
vfs.Shutdown()
vfs2.Shutdown()
}
// TestVFSNewWithOpts sees if the New command works properly
func TestVFSNewWithOpts(t *testing.T) {
var opt = vfscommon.Opt