]> source.dussan.org Git - nextcloud-server.git/commitdiff
allow storing multiple mounts for the same rootid in the mount cache
authorRobin Appelman <robin@icewind.nl>
Tue, 14 Jun 2022 13:57:59 +0000 (15:57 +0200)
committerRobin Appelman <robin@icewind.nl>
Fri, 28 Apr 2023 13:08:08 +0000 (15:08 +0200)
currently `[$userId, $rootId]` is used as the unique key for storing mounts in the mount cache,
however there are cases where the same rootid is mounted in multiple places for a user which currently leads to not all of those mounts being added to the cache.

Previously this didn't matter as the mount cache was only used to list users with access to a specific file, so a user having access to the file multiple times didn' change anything.

With 24 the mount cache is used for more cases and multiple mounts for the same id becomes relevant.
While I think there isn't a real negative effect atm besides missing the optimized path we should ensure that the mounts are properly listed

Signed-off-by: Robin Appelman <robin@icewind.nl>
core/Migrations/Version13000Date20170718121200.php
core/Migrations/Version27000Date20220613163520.php [new file with mode: 0644]
lib/composer/composer/autoload_classmap.php
lib/composer/composer/autoload_static.php
lib/private/Files/Config/UserMountCache.php
version.php

index 0924e0590d364891a1fa8440a4db25a2b0b6d93f..34a249814fbc2b0d6314c20507ae1de670176e79 100644 (file)
@@ -149,7 +149,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep {
                        $table->addIndex(['storage_id'], 'mounts_storage_index');
                        $table->addIndex(['root_id'], 'mounts_root_index');
                        $table->addIndex(['mount_id'], 'mounts_mount_id_index');
-                       $table->addUniqueIndex(['user_id', 'root_id'], 'mounts_user_root_index');
+                       $table->addIndex(['user_id', 'root_id', 'mount_point'], 'mounts_user_root_path_index', [], ['lengths' => [null, null, 128]]);
                } else {
                        $table = $schema->getTable('mounts');
                        $table->addColumn('mount_id', Types::BIGINT, [
diff --git a/core/Migrations/Version27000Date20220613163520.php b/core/Migrations/Version27000Date20220613163520.php
new file mode 100644 (file)
index 0000000..5f327e6
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2022 Your name <your@email.com>
+ *
+ * @author Your name <your@email.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Migrations;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version27000Date20220613163520 extends SimpleMigrationStep {
+       public function name(): string {
+               return "Add mountpoint path to mounts table unique index";
+       }
+
+       public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
+               /** @var ISchemaWrapper $schema */
+               $schema = $schemaClosure();
+
+               $table = $schema->getTable('mounts');
+               if ($table->hasIndex('mounts_user_root_index')) {
+                       $table->dropIndex('mounts_user_root_index');
+                       $table->addIndex(['user_id', 'root_id', 'mount_point'], 'mounts_user_root_path_index', [], ['lengths' => [null, null, 128]]);
+               }
+
+               return $schema;
+       }
+}
index eb2f3e463546df717d0094f058a12d8c95512df8..90164534da1a64b9a512b820484a834e2bf1b574 100644 (file)
@@ -1108,6 +1108,7 @@ return array(
     'OC\\Core\\Migrations\\Version25000Date20220602190540' => $baseDir . '/core/Migrations/Version25000Date20220602190540.php',
     'OC\\Core\\Migrations\\Version25000Date20220905140840' => $baseDir . '/core/Migrations/Version25000Date20220905140840.php',
     'OC\\Core\\Migrations\\Version25000Date20221007010957' => $baseDir . '/core/Migrations/Version25000Date20221007010957.php',
+    'OC\\Core\\Migrations\\Version27000Date20220613163520' => $baseDir . '/core/Migrations/Version27000Date20220613163520.php',
     'OC\\Core\\Migrations\\Version27000Date20230309104325' => $baseDir . '/core/Migrations/Version27000Date20230309104325.php',
     'OC\\Core\\Migrations\\Version27000Date20230309104802' => $baseDir . '/core/Migrations/Version27000Date20230309104802.php',
     'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php',
index 9343231a55b56eacc11d583e785ebd05f79d60c7..43cdde517342df9cf3b6b1a83d1cc3e15a70f934 100644 (file)
@@ -1141,6 +1141,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
         'OC\\Core\\Migrations\\Version25000Date20220602190540' => __DIR__ . '/../../..' . '/core/Migrations/Version25000Date20220602190540.php',
         'OC\\Core\\Migrations\\Version25000Date20220905140840' => __DIR__ . '/../../..' . '/core/Migrations/Version25000Date20220905140840.php',
         'OC\\Core\\Migrations\\Version25000Date20221007010957' => __DIR__ . '/../../..' . '/core/Migrations/Version25000Date20221007010957.php',
+        'OC\\Core\\Migrations\\Version27000Date20220613163520' => __DIR__ . '/../../..' . '/core/Migrations/Version27000Date20220613163520.php',
         'OC\\Core\\Migrations\\Version27000Date20230309104325' => __DIR__ . '/../../..' . '/core/Migrations/Version27000Date20230309104325.php',
         'OC\\Core\\Migrations\\Version27000Date20230309104802' => __DIR__ . '/../../..' . '/core/Migrations/Version27000Date20230309104802.php',
         'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php',
index a60b39823c5786cbbee432b8b8a50871064810e3..9838b0a213cf06731bf2d9b3418023a00a627d5e 100644 (file)
@@ -92,38 +92,39 @@ class UserMountCache implements IUserMountCache {
                        }
                }, $mounts);
                $newMounts = array_values(array_filter($newMounts));
-               $newMountRootIds = array_map(function (ICachedMountInfo $mount) {
-                       return $mount->getRootId();
+               $newMountKeys = array_map(function (ICachedMountInfo $mount) {
+                       return $mount->getRootId() . '::' . $mount->getMountPoint();
                }, $newMounts);
-               $newMounts = array_combine($newMountRootIds, $newMounts);
+               $newMounts = array_combine($newMountKeys, $newMounts);
 
                $cachedMounts = $this->getMountsForUser($user);
                if (is_array($mountProviderClasses)) {
                        $cachedMounts = array_filter($cachedMounts, function (ICachedMountInfo $mountInfo) use ($mountProviderClasses, $newMounts) {
                                // for existing mounts that didn't have a mount provider set
                                // we still want the ones that map to new mounts
-                               if ($mountInfo->getMountProvider() === '' && isset($newMounts[$mountInfo->getRootId()])) {
+                               $mountKey = $mountInfo->getRootId() . '::' . $mountInfo->getMountPoint();
+                               if ($mountInfo->getMountProvider() === '' && isset($newMounts[$mountKey])) {
                                        return true;
                                }
                                return in_array($mountInfo->getMountProvider(), $mountProviderClasses);
                        });
                }
-               $cachedMountRootIds = array_map(function (ICachedMountInfo $mount) {
-                       return $mount->getRootId();
+               $cachedRootKeys = array_map(function (ICachedMountInfo $mount) {
+                       return $mount->getRootId() . '::' . $mount->getMountPoint();
                }, $cachedMounts);
-               $cachedMounts = array_combine($cachedMountRootIds, $cachedMounts);
+               $cachedMounts = array_combine($cachedRootKeys, $cachedMounts);
 
                $addedMounts = [];
                $removedMounts = [];
 
-               foreach ($newMounts as $rootId => $newMount) {
-                       if (!isset($cachedMounts[$rootId])) {
+               foreach ($newMounts as $mountKey => $newMount) {
+                       if (!isset($cachedMounts[$mountKey])) {
                                $addedMounts[] = $newMount;
                        }
                }
 
-               foreach ($cachedMounts as $rootId => $cachedMount) {
-                       if (!isset($newMounts[$rootId])) {
+               foreach ($cachedMounts as $mountKey => $cachedMount) {
+                       if (!isset($newMounts[$mountKey])) {
                                $removedMounts[] = $cachedMount;
                        }
                }
@@ -161,13 +162,13 @@ class UserMountCache implements IUserMountCache {
        private function findChangedMounts(array $newMounts, array $cachedMounts) {
                $new = [];
                foreach ($newMounts as $mount) {
-                       $new[$mount->getRootId()] = $mount;
+                       $new[$mount->getRootId() . '::' . $mount->getMountPoint()] = $mount;
                }
                $changed = [];
                foreach ($cachedMounts as $cachedMount) {
-                       $rootId = $cachedMount->getRootId();
-                       if (isset($new[$rootId])) {
-                               $newMount = $new[$rootId];
+                       $key = $cachedMount->getRootId() . '::' . $cachedMount->getMountPoint();
+                       if (isset($new[$key])) {
+                               $newMount = $new[$key];
                                if (
                                        $newMount->getMountPoint() !== $cachedMount->getMountPoint() ||
                                        $newMount->getStorageId() !== $cachedMount->getStorageId() ||
@@ -190,7 +191,7 @@ class UserMountCache implements IUserMountCache {
                                'mount_point' => $mount->getMountPoint(),
                                'mount_id' => $mount->getMountId(),
                                'mount_provider_class' => $mount->getMountProvider(),
-                       ], ['root_id', 'user_id']);
+                       ], ['root_id', 'user_id', 'mount_point']);
                } else {
                        // in some cases this is legitimate, like orphaned shares
                        $this->logger->debug('Could not get storage info for mount at ' . $mount->getMountPoint());
@@ -216,7 +217,8 @@ class UserMountCache implements IUserMountCache {
 
                $query = $builder->delete('mounts')
                        ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
-                       ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
+                       ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)))
+                       ->andWhere($builder->expr()->eq('mount_point', $builder->createNamedParameter($mount->getMountPoint())));
                $query->execute();
        }
 
index d20714276b16248d57e0395a5cae8bed1039a808..44889f77860a5bad96ba724a5f395141f041fc02 100644 (file)
@@ -30,7 +30,7 @@
 // between betas, final and RCs. This is _not_ the public version number. Reset minor/patch level
 // when updating major/minor version number.
 
-$OC_Version = [27, 0, 0, 0];
+$OC_Version = [27, 0, 0, 1];
 
 // The human-readable string
 $OC_VersionString = '27.0.0 dev';