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
This commit is contained in:
Hakan İSMAİL
2026-07-30 11:02:25 +01:00
committed by GitHub
parent bd4c6571ec
commit f47ea6eb4a
3 changed files with 72 additions and 1 deletions
+3 -1
View File
@@ -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)
+1
View File
@@ -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)
+68
View File
@@ -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))
})
}