diff --git a/core/Application.php b/core/Application.php
index 4ebbada95e666..2e35461015472 100644
--- a/core/Application.php
+++ b/core/Application.php
@@ -239,6 +239,9 @@ function (GenericEvent $event) use ($container) {
if (!$table->hasIndex('mounts_class_index')) {
$subject->addHintForMissingSubject($table->getName(), 'mounts_class_index');
}
+ if (!$table->hasIndex('mounts_user_root_path_index')) {
+ $subject->addHintForMissingSubject($table->getName(), 'mounts_user_root_path_index');
+ }
}
}
);
diff --git a/core/Command/Db/AddMissingIndices.php b/core/Command/Db/AddMissingIndices.php
index e22d0fddeca34..b317f44b49930 100644
--- a/core/Command/Db/AddMissingIndices.php
+++ b/core/Command/Db/AddMissingIndices.php
@@ -465,6 +465,14 @@ private function addCoreIndexes(OutputInterface $output, bool $dryRun): void {
$updated = true;
$output->writeln('oc_mounts table updated successfully.');
}
+ if (!$table->hasIndex('mounts_user_root_path_index')) {
+ $output->writeln('Adding mounts_user_root_path_index index to the oc_mounts table, this can take some time...');
+
+ $table->addIndex(['user_id', 'root_id', 'mount_point'], 'mounts_user_root_path_index', [], ['lengths' => [null, null, 128]]);
+ $this->connection->migrateToSchema($schema->getWrappedSchema());
+ $updated = true;
+ $output->writeln('oc_mounts table updated successfully.');
+ }
}
if (!$updated) {
diff --git a/core/Migrations/Version13000Date20170718121200.php b/core/Migrations/Version13000Date20170718121200.php
index 0924e0590d364..34a249814fbc2 100644
--- a/core/Migrations/Version13000Date20170718121200.php
+++ b/core/Migrations/Version13000Date20170718121200.php
@@ -149,7 +149,7 @@ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $op
$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
index 0000000000000..4217f3b3270aa
--- /dev/null
+++ b/core/Migrations/Version27000Date20220613163520.php
@@ -0,0 +1,51 @@
+
+ *
+ * @author Your name
+ *
+ * @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 .
+ *
+ */
+
+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');
+ // new index gets added with "add missing indexes"
+ }
+
+ return $schema;
+ }
+}
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index be8b6fd89d0dc..0ae7613b8fd0c 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1090,6 +1090,7 @@
'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',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 5a71fc211da3f..1efe2ab556fc2 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1123,6 +1123,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',
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index fe677c5ea52fd..aa362b0e9707e 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -92,38 +92,39 @@ public function registerMounts(IUser $user, array $mounts, array $mountProviderC
}
}, $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;
}
}
@@ -154,13 +155,13 @@ public function registerMounts(IUser $user, array $mounts, array $mountProviderC
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() ||
@@ -183,7 +184,7 @@ private function addToCache(ICachedMountInfo $mount) {
'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());
@@ -209,7 +210,8 @@ private function removeFromCache(ICachedMountInfo $mount) {
$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();
}