From f47ea6eb4a322f955044464d678524e5d74bb190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hakan=20=C4=B0SMA=C4=B0L?= <93117749+Hakanbaban53@users.noreply.github.com> Date: Thu, 30 Jul 2026 13:02:25 +0300 Subject: [PATCH] rc: fix _filter and _config parameters being ignored by mount/* commands This resolves an issue where mount filters supplied to the rc API (such as `_filter` in remote control requests) were ignored during FUSE mounts. By passing the request context containing the parsed filter config to `vfs.New`, the VFS layer now correctly respects the active filter rules. Fixes #8838 --- cmd/mountlib/mount.go | 4 ++- cmd/mountlib/rc.go | 1 + cmd/mountlib/rc_test.go | 68 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index c645655fa..ff1969c18 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -210,6 +210,7 @@ type ( // MountPoint represents a mount with options and runtime state type MountPoint struct { + Ctx context.Context MountPoint string MountedOn time.Time MountOpt Options @@ -224,6 +225,7 @@ type MountPoint struct { // NewMountPoint makes a new mounting structure func NewMountPoint(mount MountFn, mountPoint string, f fs.Fs, mountOpt *Options, vfsOpt *vfscommon.Options) *MountPoint { return &MountPoint{ + Ctx: context.Background(), MountFn: mount, MountPoint: mountPoint, Fs: f, @@ -379,7 +381,7 @@ func (m *MountPoint) Mount() (mountDaemon *os.Process, err error) { } } - m.VFS = vfs.New(context.Background(), m.Fs, &m.VFSOpt) + m.VFS = vfs.New(m.Ctx, m.Fs, &m.VFSOpt) var actualMountpoint string m.ErrChan, m.UnmountFn, actualMountpoint, err = m.MountFn(m.VFS, m.MountPoint, &m.MountOpt) diff --git a/cmd/mountlib/rc.go b/cmd/mountlib/rc.go index aab0daabe..884e9125c 100644 --- a/cmd/mountlib/rc.go +++ b/cmd/mountlib/rc.go @@ -149,6 +149,7 @@ func mountRc(ctx context.Context, in rc.Params) (out rc.Params, err error) { } mnt := NewMountPoint(mountFn, mountPoint, fdst, &mountOpt, &vfsOpt) + mnt.Ctx = ctx _, err = mnt.Mount() if err != nil { fs.Logf(nil, "mount FAILED: %v", err) diff --git a/cmd/mountlib/rc_test.go b/cmd/mountlib/rc_test.go index d646cbc94..c1c040b18 100644 --- a/cmd/mountlib/rc_test.go +++ b/cmd/mountlib/rc_test.go @@ -13,8 +13,10 @@ import ( _ "github.com/rclone/rclone/cmd/mount" _ "github.com/rclone/rclone/cmd/mount2" "github.com/rclone/rclone/cmd/mountlib" + "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configfile" "github.com/rclone/rclone/fs/rc" + "github.com/rclone/rclone/fstest" "github.com/rclone/rclone/fstest/testy" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -26,6 +28,7 @@ func TestRc(t *testing.T) { testy.SkipUnreliable(t) } ctx := context.Background() + fstest.Initialise() configfile.Install() mount := rc.Calls.Get("mount/mount") assert.NotNil(t, mount) @@ -128,4 +131,69 @@ func TestRc(t *testing.T) { assert.Equal(t, 0, len(checkMountList())) }) }) + + t.Run("MountWithFilterAndConfig", func(t *testing.T) { + if len(mountTypes) == 0 { + t.Skip("Can't mount") + } + filterDir := t.TempDir() + err := os.WriteFile(filepath.Join(filterDir, "allowed.txt"), []byte("allow"), 0666) + require.NoError(t, err) + err = os.WriteFile(filepath.Join(filterDir, "excluded.txt"), []byte("exclude"), 0666) + require.NoError(t, err) + + filterMountPoint := t.TempDir() + if runtime.GOOS == "windows" { + require.NoError(t, os.RemoveAll(filterMountPoint)) + } + + in := rc.Params{ + "fs": filterDir, + "mountPoint": filterMountPoint, + "_filter": rc.Params{ + "ExcludeRule": []string{"excluded.txt"}, + }, + "_config": rc.Params{ + "LowLevelRetries": 99, + }, + } + + // mount + ctxWithConfig, err := rc.AddConfig(ctx, in) + require.NoError(t, err) + ctxWithFilter, err := rc.AddFilter(ctxWithConfig, in) + require.NoError(t, err) + + ci := fs.GetConfig(ctxWithConfig) + assert.Equal(t, 99, ci.LowLevelRetries) + + out, err := mount.Fn(ctxWithFilter, in) + if err != nil { + t.Skipf("Mount failed - skipping test: %v", err) + } + t.Cleanup(func() { + _, err = unmount.Fn(ctx, rc.Params{ + "mountPoint": filterMountPoint, + }) + assert.NoError(t, err) + + // FIXME wait a moment for the OS to release the mount point + time.Sleep(100 * time.Millisecond) + }) + + returnedMountPoint, err := out.GetString("mountPoint") + require.NoError(t, err) + assert.Equal(t, filterMountPoint, returnedMountPoint) + + // check allowed.txt is visible in mount point + allowedPath := filepath.Join(filterMountPoint, "allowed.txt") + _, err = os.Stat(allowedPath) + require.NoError(t, err) + + // check excluded.txt is not visible in mount point due to the filter + excludedPath := filepath.Join(filterMountPoint, "excluded.txt") + _, err = os.Stat(excludedPath) + require.Error(t, err) + require.True(t, os.IsNotExist(err)) + }) }