From fb1095f0f6530cbeb270cc98645b68a617523587 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 22 Feb 2023 18:03:38 +0100 Subject: [PATCH] do onetime user setup before getting any mount from providers this fixes a race condition where wrappers weren't properly applied if when a mount provider creates the storage instance one mountpoint creation instead of lazily Signed-off-by: Robin Appelman --- lib/private/Files/SetupManager.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index 4cbd0328d76..01ce4a1cc59 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -235,11 +235,13 @@ class SetupManager { * part of the user setup that is run only once per user */ private function oneTimeUserSetup(IUser $user) { - if (in_array($user->getUID(), $this->setupUsers, true)) { + if ($this->isSetupStarted($user)) { return; } $this->setupUsers[] = $user->getUID(); + $this->setupRoot(); + $this->eventLogger->start('fs:setup:user:onetime', 'Onetime filesystem for user'); $this->setupBuiltinWrappers(); @@ -319,11 +321,7 @@ class SetupManager { * @throws \OC\ServerNotAvailableException */ private function setupForUserWith(IUser $user, callable $mountCallback): void { - $this->setupRoot(); - - if (!$this->isSetupStarted($user)) { - $this->oneTimeUserSetup($user); - } + $this->oneTimeUserSetup($user); if ($this->lockdownManager->canAccessFilesystem()) { $mountCallback(); @@ -422,9 +420,7 @@ class SetupManager { return; } - if (!$this->isSetupStarted($user)) { - $this->oneTimeUserSetup($user); - } + $this->oneTimeUserSetup($user); $this->eventLogger->start('fs:setup:user:path', "Setup $path filesystem for user"); $this->eventLogger->start('fs:setup:user:path:find', "Find mountpoint for $path"); @@ -513,6 +509,8 @@ class SetupManager { $this->eventLogger->start('fs:setup:user:providers', "Setup filesystem for " . implode(', ', $providers)); + $this->oneTimeUserSetup($user); + // home providers are always used $providers = array_filter($providers, function (string $provider) { return !is_subclass_of($provider, IHomeMountProvider::class);