mountlib: fix VFS instance leaks on mount failures and unmounts

This commit is contained in:
Hakan İSMAİL
2026-08-18 09:03:12 +01:00
committed by Nick Craig-Wood
parent f425f8d466
commit 45ddf3a5f2
5 changed files with 27 additions and 19 deletions
-2
View File
@@ -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")
-2
View File
@@ -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)
}
-2
View File
@@ -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()
}
+27 -11
View File
@@ -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
}
-2
View File
@@ -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