diff --git a/cmd/mount/dir.go b/cmd/mount/dir.go index cf83da13b..f03e3baf6 100644 --- a/cmd/mount/dir.go +++ b/cmd/mount/dir.go @@ -181,6 +181,15 @@ func (d *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) (err error) { return nil } +// Invalidate a leaf in a directory +func (d *Dir) invalidateEntry(dirNode fusefs.Node, leaf string) { + fs.Debugf(dirNode, "Invalidating %q", leaf) + err := d.fsys.server.InvalidateEntry(dirNode, leaf) + if err != nil { + fs.Debugf(dirNode, "Failed to invalidate %q: %v", leaf, err) + } +} + // Check interface satisfied var _ fusefs.NodeRenamer = (*Dir)(nil) @@ -197,6 +206,13 @@ func (d *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fusefs return translateError(err) } + // Invalidate the new directory entry so it gets re-read (in + // the background otherwise we cause a deadlock) + // + // See https://github.com/rclone/rclone/issues/4977 for why + go d.invalidateEntry(newDir, req.NewName) + //go d.invalidateEntry(d, req.OldName) + return nil } diff --git a/cmd/mount/fs.go b/cmd/mount/fs.go index 78a99a6fc..5dbd74efe 100644 --- a/cmd/mount/fs.go +++ b/cmd/mount/fs.go @@ -20,8 +20,9 @@ import ( // FS represents the top level filing system type FS struct { *vfs.VFS - f fs.Fs - opt *mountlib.Options + f fs.Fs + opt *mountlib.Options + server *fusefs.Server } // Check interface satisfied diff --git a/cmd/mount/mount.go b/cmd/mount/mount.go index 88aac32de..2b42af472 100644 --- a/cmd/mount/mount.go +++ b/cmd/mount/mount.go @@ -91,12 +91,12 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (<-chan error } filesys := NewFS(VFS, opt) - server := fusefs.New(c, nil) + filesys.server = fusefs.New(c, nil) // Serve the mount point in the background returning error to errChan errChan := make(chan error, 1) go func() { - err := server.Serve(filesys) + err := filesys.server.Serve(filesys) closeErr := c.Close() if err == nil { err = closeErr