diff --git a/cmd/cmount/mount.go b/cmd/cmount/mount.go index 6515b33b4..d044a4e79 100644 --- a/cmd/cmount/mount.go +++ b/cmd/cmount/mount.go @@ -170,8 +170,6 @@ func mount(VFS *vfs.VFS, mountPath string, opt *mountlib.Options) (<-chan error, // unmount unmount := func() error { - // Shutdown the VFS - fsys.VFS.Shutdown() var umountOK bool if fsys.destroyed.Load() != 0 { fs.Debugf(nil, "Not calling host.Unmount as mount already Destroyed") diff --git a/cmd/mount/mount.go b/cmd/mount/mount.go index c86aebbb3..b700f0645 100644 --- a/cmd/mount/mount.go +++ b/cmd/mount/mount.go @@ -103,8 +103,6 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (<-chan error }() unmount := func() error { - // Shutdown the VFS - filesys.VFS.Shutdown() return fuse.Unmount(mountpoint) } diff --git a/cmd/mount2/mount.go b/cmd/mount2/mount.go index 5b2714025..1b0f17c65 100644 --- a/cmd/mount2/mount.go +++ b/cmd/mount2/mount.go @@ -241,8 +241,6 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (<-chan error // } umount := func() error { - // Shutdown the VFS - fsys.VFS.Shutdown() return server.Unmount() } diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index ff1969c18..10ae5eb8e 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -210,16 +210,26 @@ type ( // MountPoint represents a mount with options and runtime state type MountPoint struct { - Ctx context.Context - MountPoint string - MountedOn time.Time - MountOpt Options - VFSOpt vfscommon.Options - Fs fs.Fs - VFS *vfs.VFS - MountFn MountFn - UnmountFn UnmountFn - ErrChan <-chan error + Ctx context.Context + MountPoint string + MountedOn time.Time + MountOpt Options + VFSOpt vfscommon.Options + Fs fs.Fs + VFS *vfs.VFS + MountFn MountFn + UnmountFn UnmountFn + ErrChan <-chan error + vfsShutdownOnce sync.Once +} + +// shutdownVFS shuts down the VFS instance exactly once +func (m *MountPoint) shutdownVFS() { + m.vfsShutdownOnce.Do(func() { + if m.VFS != nil { + m.VFS.Shutdown() + } + }) } // NewMountPoint makes a new mounting structure @@ -386,6 +396,7 @@ func (m *MountPoint) Mount() (mountDaemon *os.Process, err error) { var actualMountpoint string m.ErrChan, m.UnmountFn, actualMountpoint, err = m.MountFn(m.VFS, m.MountPoint, &m.MountOpt) if err != nil { + m.shutdownVFS() if len(os.Args) > 0 && strings.HasPrefix(os.Args[0], "/snap/") { return nil, fmt.Errorf("mounting is not supported when running from snap") } @@ -404,6 +415,7 @@ func (m *MountPoint) Wait() error { var finaliseOnce sync.Once finalise := func() { finaliseOnce.Do(func() { + defer m.shutdownVFS() // Unmount only if directory was mounted by rclone, e.g. don't unmount autofs hooks. if err := CheckMountReady(m.MountPoint); err != nil { fs.Debugf(m.MountPoint, "Unmounted externally. Just exit now.") @@ -431,5 +443,9 @@ func (m *MountPoint) Wait() error { // Unmount the specified mountpoint func (m *MountPoint) Unmount() (err error) { - return m.UnmountFn() + defer m.shutdownVFS() + if m.UnmountFn != nil { + return m.UnmountFn() + } + return nil } diff --git a/cmd/nfsmount/nfsmount.go b/cmd/nfsmount/nfsmount.go index b33fb2d04..493c2bf79 100644 --- a/cmd/nfsmount/nfsmount.go +++ b/cmd/nfsmount/nfsmount.go @@ -117,7 +117,6 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (asyncerrors out, umountErr = exec.Command(cmd[0], cmd[1:]...).CombinedOutput() } shutdownErr := s.Shutdown() - VFS.Shutdown() if umountErr != nil { out = bytes.TrimSpace(out) return fmt.Errorf("%s: failed to umount the NFS volume %e", out, umountErr) @@ -130,7 +129,6 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (asyncerrors nfs.OnUnmountFunc = func() { s.UnmountedExternally = true errChan <- nil - VFS.Shutdown() } actualMountpoint = mountpoint