From 72150d6deb896e0191c2920fdb72744ae6fbb341 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 30 Jan 2026 17:38:56 +0100 Subject: [PATCH] fix: getById: don't setup for all users with access by default Signed-off-by: Robin Appelman --- lib/private/Files/Mount/Manager.php | 4 +-- lib/private/Files/Node/Root.php | 42 ++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/lib/private/Files/Mount/Manager.php b/lib/private/Files/Mount/Manager.php index b763697387d..72b38f38575 100644 --- a/lib/private/Files/Mount/Manager.php +++ b/lib/private/Files/Mount/Manager.php @@ -230,11 +230,11 @@ class Manager implements IMountManager { } /** - * Return all mounts in a path from a specific mount provider + * Return all mounts in a path from a specific mount provider, indexed by mount point * * @param string $path * @param string[] $mountProviders - * @return IMountPoint[] + * @return array */ public function getMountsByMountProvider(string $path, array $mountProviders) { $this->getSetupManager()->setupForProvider($path, $mountProviders); diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php index c94eadcedb3..8354f382aa3 100644 --- a/lib/private/Files/Node/Root.php +++ b/lib/private/Files/Node/Root.php @@ -5,6 +5,7 @@ * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ + namespace OC\Files\Node; use OC\Files\FileInfo; @@ -19,6 +20,8 @@ use OCA\Files\ConfigLexicon; use OCP\Cache\CappedMemoryCache; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Cache\ICacheEntry; +use OCP\Files\Config\ICachedMountFileInfo; +use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IUserMountCache; use OCP\Files\Events\Node\FilesystemTornDownEvent; use OCP\Files\IRootFolder; @@ -82,10 +85,8 @@ class Root extends Folder implements IRootFolder { /** * Get the user for which the filesystem is setup - * - * @return \OC\User\User */ - public function getUser() { + public function getUser(): ?IUser { return $this->user; } @@ -411,12 +412,12 @@ class Root extends Folder implements IRootFolder { } else { $user = null; } - $mountsContainingFile = $mountCache->getMountsForFileId($id, $user); + $mountInfosContainingFiles = $mountCache->getMountsForFileId($id, $user); // if the mount isn't in the cache yet, perform a setup first, then try again - if (count($mountsContainingFile) === 0) { + if (count($mountInfosContainingFiles) === 0) { $setupManager->setupForPath($path, true); - $mountsContainingFile = $mountCache->getMountsForFileId($id, $user); + $mountInfosContainingFiles = $mountCache->getMountsForFileId($id, $user); } // when a user has access through the same storage through multiple paths @@ -428,16 +429,37 @@ class Root extends Folder implements IRootFolder { $mountRootIds = array_map(function ($mount) { return $mount->getRootId(); - }, $mountsContainingFile); + }, $mountInfosContainingFiles); $mountRootPaths = array_map(function ($mount) { return $mount->getRootInternalPath(); - }, $mountsContainingFile); + }, $mountInfosContainingFiles); $mountProviders = array_unique(array_map(function ($mount) { return $mount->getMountProvider(); - }, $mountsContainingFile)); + }, $mountInfosContainingFiles)); + $mountPoints = array_map(fn (ICachedMountInfo $mountInfo) => $mountInfo->getMountPoint(), $mountInfosContainingFiles); $mountRoots = array_combine($mountRootIds, $mountRootPaths); - $mountsContainingFile = array_filter(array_map($this->mountManager->getMountFromMountInfo(...), $mountsContainingFile)); + $mounts = $this->mountManager->getMountsByMountProvider($path, $mountProviders); + $mountsContainingFile = array_filter($mounts, fn (IMountPoint $mount) => in_array($mount->getMountPoint(), $mountPoints)); + + // if we haven't found a relevant mount that is setup, but we do have relevant mount infos + // we try to load them from the mount info. + if (count($mountsContainingFile) === 0 && count($mountInfosContainingFiles) > 0) { + // in order to minimize the cost of this, we only use the mount infos from one user. + if (!$user) { + // if we don't have a user from the path, use the user from the current filesystem setup + $user = $this->getUser()?->getUID(); + } + if (!$user) { + // if there also isn't a current filesystem user, just use the user from the first mount info + /** @var ICachedMountFileInfo $firstMount */ + $firstMount = current($mountInfosContainingFiles); + $user = $firstMount->getUser()->getUID(); + } + // get the mount infos for the user we picked, and get the mounts for it + $mountInfosContainingFiles = array_filter($mountInfosContainingFiles, fn (ICachedMountInfo $mountInfo) => $mountInfo->getUser()->getUID() === $user); + $mountsContainingFile = array_filter(array_map($this->mountManager->getMountFromMountInfo(...), $mountInfosContainingFiles)); + } if (count($mountsContainingFile) === 0) { if ($user === $this->getAppDataDirectoryName()) {