From d04922de7c7f24b57ae61d6294cc6a816e4f8486 Mon Sep 17 00:00:00 2001 From: Git'Fellow <12234510+solracsf@users.noreply.github.com> Date: Sat, 14 Feb 2026 08:55:40 +0100 Subject: [PATCH 1/4] refactor(SetupManager): user ID retrieval once Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com> --- lib/private/Files/SetupManager.php | 83 ++++++++++++++++++------------ 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index c8945de7caed1..603e081de8827 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -265,20 +265,23 @@ public function setupForUser(IUser $user): void { if ($this->isSetupComplete($user)) { return; } - $this->setupUsersComplete[] = $user->getUID(); + + $userId = $user->getUID(); + + $this->setupUsersComplete[] = $userId; $this->eventLogger->start('fs:setup:user:full', 'Setup full filesystem for user'); $this->dropPartialMountsForUser($user); - $this->setupUserMountProviders[$user->getUID()] ??= []; - $previouslySetupProviders = $this->setupUserMountProviders[$user->getUID()]; + $this->setupUserMountProviders[$userId] ??= []; + $previouslySetupProviders = $this->setupUserMountProviders[$userId]; $this->setupForUserWith($user, function () use ($user): void { $this->mountProviderCollection->addMountForUser($user, $this->mountManager, function ( string $providerClass, ) use ($user) { - return !in_array($providerClass, $this->setupUserMountProviders[$user->getUID()]); + return !in_array($providerClass, $this->setupUserMountProviders[$userId]); }); }); $this->afterUserFullySetup($user, $previouslySetupProviders); @@ -292,7 +295,10 @@ private function oneTimeUserSetup(IUser $user) { if ($this->isSetupStarted($user)) { return; } - $this->setupUsers[] = $user->getUID(); + + $userId = $user->getUID(); + + $this->setupUsers[] = $userId; $this->setupRoot(); @@ -303,14 +309,14 @@ private function oneTimeUserSetup(IUser $user) { $prevLogging = Filesystem::logWarningWhenAddingStorageWrapper(false); // TODO remove hook - OC_Hook::emit('OC_Filesystem', 'preSetup', ['user' => $user->getUID()]); + OC_Hook::emit('OC_Filesystem', 'preSetup', ['user' => $userId]); $event = new BeforeFileSystemSetupEvent($user); $this->eventDispatcher->dispatchTyped($event); Filesystem::logWarningWhenAddingStorageWrapper($prevLogging); - $userDir = '/' . $user->getUID() . '/files'; + $userDir = '/' . $userId . '/files'; Filesystem::initInternal($userDir); @@ -330,13 +336,13 @@ private function oneTimeUserSetup(IUser $user) { } else { $this->mountManager->addMount(new MountPoint( new NullStorage([]), - '/' . $user->getUID() + '/' . $userId )); $this->mountManager->addMount(new MountPoint( new NullStorage([]), - '/' . $user->getUID() . '/files' + '/' . $userId . '/files' )); - $this->setupUsersComplete[] = $user->getUID(); + $this->setupUsersComplete[] = $userId; } $this->listenForNewMountProviders(); @@ -374,8 +380,9 @@ private function afterUserFullySetup(IUser $user, array $previouslySetupProvider private function markUserMountsCached(IUser $user): void { $cacheDuration = $this->config->getSystemValueInt('fs_mount_cache_duration', 5 * 60); if ($cacheDuration > 0) { - $this->cache->set($user->getUID(), true, $cacheDuration); - $this->fullSetupRequired[$user->getUID()] = false; + $userId = $user->getUID(); + $this->cache->set($userId, true, $cacheDuration); + $this->fullSetupRequired[$userId] = false; } } @@ -393,13 +400,16 @@ private function setupForUserWith(IUser $user, callable $mountCallback): void { if ($this->lockdownManager->canAccessFilesystem()) { $mountCallback(); } + + $userId = $user->getUID(); + $this->eventLogger->start('fs:setup:user:post-init-mountpoint', 'post_initMountPoints legacy hook'); - \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', ['user' => $user->getUID()]); + \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', ['user' => $userId]); $this->eventLogger->end('fs:setup:user:post-init-mountpoint'); - $userDir = '/' . $user->getUID() . '/files'; + $userDir = '/' . $userId . '/files'; $this->eventLogger->start('fs:setup:user:setup-hook', 'setup legacy hook'); - OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $user->getUID(), 'user_dir' => $userDir]); + OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $userId, 'user_dir' => $userDir]); $this->eventLogger->end('fs:setup:user:setup-hook'); } @@ -407,7 +417,7 @@ private function setupForUserWith(IUser $user, callable $mountCallback): void { * Set up the root filesystem */ public function setupRoot(): void { - //setting up the filesystem twice can only lead to trouble + // setting up the filesystem twice can only lead to trouble if ($this->rootSetup) { return; } @@ -440,9 +450,8 @@ private function getUserForPath(string $path, bool $includeChildren = false): ?I } elseif (substr_count($path, '/') < 2) { if ($user = $this->userSession->getUser()) { return $user; - } else { - return null; } + return null; } elseif (str_starts_with($path, '/appdata_' . \OC_Util::getInstanceId()) || str_starts_with($path, '/files_external/')) { return null; } else { @@ -455,7 +464,7 @@ private function getUserForPath(string $path, bool $includeChildren = false): ?I #[Override] public function setupForPath(string $path, bool $includeChildren = false): void { $user = $this->getUserForPath($path, $includeChildren); - if (!$user) { + if ($user === null) { $this->setupRoot(); return; } @@ -474,16 +483,18 @@ public function setupForPath(string $path, bool $includeChildren = false): void } } - // for the user's home folder, and includes children we need everything always - if (rtrim($path) === '/' . $user->getUID() . '/files' && $includeChildren) { + $userId = $user->getUID(); + + // For user's home folder with children, always perform full setup + if (rtrim($path) === '/' . $userId . '/files' && $includeChildren) { $this->setupForUser($user); return; } - if (!isset($this->setupUserMountProviders[$user->getUID()])) { - $this->setupUserMountProviders[$user->getUID()] = []; + if (!isset($this->setupUserMountProviders[$userId])) { + $this->setupUserMountProviders[$userId] = []; } - $setupProviders = &$this->setupUserMountProviders[$user->getUID()]; + $setupProviders = &$this->setupUserMountProviders[$userId]; $currentProviders = []; try { @@ -647,10 +658,11 @@ private function fullSetupRequired(IUser $user): bool { // we perform a "cached" setup only after having done the full setup recently // this is also used to trigger a full setup after handling events that are likely // to change the available mounts - if (!isset($this->fullSetupRequired[$user->getUID()])) { - $this->fullSetupRequired[$user->getUID()] = !$this->cache->get($user->getUID()); + $userId = $user->getUID(); + if (!isset($this->fullSetupRequired[$userId])) { + $this->fullSetupRequired[$userId] = !$this->cache->get($userId); } - return $this->fullSetupRequired[$user->getUID()]; + return $this->fullSetupRequired[$userId]; } /** @@ -697,7 +709,10 @@ public function setupForProvider(string $path, array $providers): void { $this->setupForUser($user); return; } - $setupProviders = $this->setupUserMountProviders[$user->getUID()] ?? []; + + $userId = $user->getUID(); + + $setupProviders = $this->setupUserMountProviders[$userId] ?? []; $providers = array_diff($providers, $setupProviders); if (count($providers) === 0) { @@ -708,7 +723,7 @@ public function setupForProvider(string $path, array $providers): void { return; } else { $this->dropPartialMountsForUser($user, $providers); - $this->setupUserMountProviders[$user->getUID()] = array_merge($setupProviders, $providers); + $this->setupUserMountProviders[$userId] = array_merge($setupProviders, $providers); $mounts = $this->mountProviderCollection->getUserMountsForProviderClasses($user, $providers); } @@ -753,8 +768,8 @@ private function listenForNewMountProviders() { } private function setupListeners() { - // note that this event handling is intentionally pessimistic - // clearing the cache to often is better than not enough + // Note that this event handling is intentionally pessimistic + // clearing the cache too often is better than not enough $this->eventDispatcher->addListener(UserAddedEvent::class, function (UserAddedEvent $event): void { $this->cache->remove($event->getUser()->getUID()); @@ -809,16 +824,18 @@ private function registerMounts(IUser $user, array $mounts, ?array $mountProvide * * @param class-string[] $providers */ - public function dropPartialMountsForUser(IUser $user, array $providers = []): void { + public function dropPartialMountsForUser(IUser $user, array $providers = []): void // mounts are cached by mount-point $mounts = $this->mountManager->getAll(); + $userDir = '/' . $user->getUID() . '/files'; + $partialMounts = array_filter($this->setupMountProviderPaths, static function (string $mountPoint) use ( $providers, $user, $mounts ) { - $isUserMount = str_starts_with($mountPoint, '/' . $user->getUID() . '/files'); + $isUserMount = str_starts_with($mountPoint, $userDir); if (!$isUserMount) { return false; From c131d79ef1c395fea8139707a12a0d22da37c04b Mon Sep 17 00:00:00 2001 From: Git'Fellow <12234510+solracsf@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:01:06 +0100 Subject: [PATCH 2/4] fix: typo Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com> --- lib/private/Files/SetupManager.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index 603e081de8827..22de0194cd7db 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -267,7 +267,7 @@ public function setupForUser(IUser $user): void { } $userId = $user->getUID(); - + $this->setupUsersComplete[] = $userId; $this->eventLogger->start('fs:setup:user:full', 'Setup full filesystem for user'); @@ -824,11 +824,12 @@ private function registerMounts(IUser $user, array $mounts, ?array $mountProvide * * @param class-string[] $providers */ - public function dropPartialMountsForUser(IUser $user, array $providers = []): void + public function dropPartialMountsForUser(IUser $user, array $providers = []): void { // mounts are cached by mount-point $mounts = $this->mountManager->getAll(); + $userDir = '/' . $user->getUID() . '/files'; - + $partialMounts = array_filter($this->setupMountProviderPaths, static function (string $mountPoint) use ( $providers, From d9f33530a1ffe6e70a34747089290b4846b79637 Mon Sep 17 00:00:00 2001 From: Git'Fellow <12234510+solracsf@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:06:59 +0100 Subject: [PATCH 3/4] fix: TypeError Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com> --- lib/private/Files/SetupManager.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index 22de0194cd7db..4f1332abd41d6 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -266,9 +266,7 @@ public function setupForUser(IUser $user): void { return; } - $userId = $user->getUID(); - - $this->setupUsersComplete[] = $userId; + $this->setupUsersComplete[] = $user->getUID(); $this->eventLogger->start('fs:setup:user:full', 'Setup full filesystem for user'); @@ -281,7 +279,7 @@ public function setupForUser(IUser $user): void { $this->mountProviderCollection->addMountForUser($user, $this->mountManager, function ( string $providerClass, ) use ($user) { - return !in_array($providerClass, $this->setupUserMountProviders[$userId]); + return !in_array($providerClass, $this->setupUserMountProviders[$user->getUID()]); }); }); $this->afterUserFullySetup($user, $previouslySetupProviders); From 610ced9a03a8f7f9033d5b945a5c30c19515ecb0 Mon Sep 17 00:00:00 2001 From: Git'Fellow <12234510+solracsf@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:10:30 +0100 Subject: [PATCH 4/4] fix: TypeError Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com> --- lib/private/Files/SetupManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index 4f1332abd41d6..9c0cb0cccbb24 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -266,7 +266,9 @@ public function setupForUser(IUser $user): void { return; } - $this->setupUsersComplete[] = $user->getUID(); + $userId = $user->getUID(); + + $this->setupUsersComplete[] = $userId; $this->eventLogger->start('fs:setup:user:full', 'Setup full filesystem for user');