aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Klehr <mklehr@gmx.net>2025-07-07 15:54:30 +0200
committerMarcel Klehr <mklehr@gmx.net>2025-07-15 09:15:16 +0200
commit43be97de0846c25b5098d0b355ef1aa8408dbca5 (patch)
tree174e5e09894865cbf207ff12a326de3feb31ec0e
parent3a96f8e53345dd578b00119f9bdd541adec12a8e (diff)
downloadnextcloud-server-43be97de0846c25b5098d0b355ef1aa8408dbca5.tar.gz
nextcloud-server-43be97de0846c25b5098d0b355ef1aa8408dbca5.zip
fix(FileAccess): Use one param for rewriting home dirs and excluding non-user files mountsfeat/getByAncestorInStorage
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
-rw-r--r--lib/private/Files/Cache/FileAccess.php17
-rw-r--r--lib/public/Files/Cache/IFileAccess.php4
-rw-r--r--tests/lib/Files/Cache/FileAccessTest.php45
3 files changed, 57 insertions, 9 deletions
diff --git a/lib/private/Files/Cache/FileAccess.php b/lib/private/Files/Cache/FileAccess.php
index a7a6e3a222f..c3f3614f3ca 100644
--- a/lib/private/Files/Cache/FileAccess.php
+++ b/lib/private/Files/Cache/FileAccess.php
@@ -158,12 +158,23 @@ class FileAccess implements IFileAccess {
$files->closeCursor();
}
- public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeDirectories = true): \Generator {
+ public function getDistinctMounts(array $mountProviders = [], bool $onlyUserFilesMounts = true): \Generator {
$qb = $this->connection->getQueryBuilder();
$qb->selectDistinct(['root_id', 'storage_id', 'mount_provider_class'])
->from('mounts');
+ if ($onlyUserFilesMounts) {
+ $qb->andWhere(
+ $qb->expr()->orX(
+ $qb->expr()->like('mount_point', $qb->createNamedParameter('/%/files/%')),
+ $qb->expr()->in('mount_provider_class', $qb->createNamedParameter([
+ \OC\Files\Mount\LocalHomeMountProvider::class,
+ \OC\Files\Mount\ObjectHomeMountProvider::class,
+ ], IQueryBuilder::PARAM_STR_ARRAY))
+ )
+ );
+ }
if (count($mountProviders) > 0) {
- $qb->where($qb->expr()->in('mount_provider_class', $qb->createPositionalParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY)));
+ $qb->andWhere($qb->expr()->in('mount_provider_class', $qb->createNamedParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY)));
}
$qb->orderBy('root_id', 'ASC');
$result = $qb->executeQuery();
@@ -177,7 +188,7 @@ class FileAccess implements IFileAccess {
$overrideRoot = $rootId;
// LocalHomeMountProvider is the default provider for user home directories
// ObjectHomeMountProvider is the home directory provider for when S3 primary storage is used
- if ($rewriteHomeDirectories && in_array($row['mount_provider_class'], [
+ if ($onlyUserFilesMounts && in_array($row['mount_provider_class'], [
\OC\Files\Mount\LocalHomeMountProvider::class,
\OC\Files\Mount\ObjectHomeMountProvider::class,
], true)) {
diff --git a/lib/public/Files/Cache/IFileAccess.php b/lib/public/Files/Cache/IFileAccess.php
index be6257382ad..7a993d81e7a 100644
--- a/lib/public/Files/Cache/IFileAccess.php
+++ b/lib/public/Files/Cache/IFileAccess.php
@@ -104,11 +104,11 @@ interface IFileAccess {
* Optionally rewrites home directory root paths to avoid cache and trashbin.
*
* @param list<string> $mountProviders An array of mount provider class names to filter. If empty, all providers will be included.
- * @param bool $rewriteHomeDirectories Whether to rewrite the root path IDs for home directories to only include user files.
+ * @param bool $onlyUserFilesMounts Whether to rewrite the root IDs for home directories to only include user files and to only consider mounts with mount points in the user files.
* @return \Generator<array{storage_id: int, root_id: int, overridden_root: int}> A generator yielding mount configurations as an array containing 'storage_id', 'root_id', and 'override_root'.
* @throws \OCP\DB\Exception
*
* @since 32.0.0
*/
- public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeDirectories = true): \Generator;
+ public function getDistinctMounts(array $mountProviders = [], bool $onlyUserFilesMounts = true): \Generator;
}
diff --git a/tests/lib/Files/Cache/FileAccessTest.php b/tests/lib/Files/Cache/FileAccessTest.php
index e856488f176..59fa2494ea8 100644
--- a/tests/lib/Files/Cache/FileAccessTest.php
+++ b/tests/lib/Files/Cache/FileAccessTest.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -71,15 +72,25 @@ class FileAccessTest extends TestCase {
'user_id' => $queryBuilder->createNamedParameter('test'),
])
->executeStatement();
+
+ $queryBuilder->insert('mounts')
+ ->values([
+ 'storage_id' => $queryBuilder->createNamedParameter(4, IQueryBuilder::PARAM_INT),
+ 'root_id' => $queryBuilder->createNamedParameter(31, IQueryBuilder::PARAM_INT),
+ 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass2'),
+ 'mount_point' => $queryBuilder->createNamedParameter('/foobar'),
+ 'user_id' => $queryBuilder->createNamedParameter('test'),
+ ])
+ ->executeStatement();
}
/**
* Test that getDistinctMounts returns all mounts without filters
*/
public function testGetDistinctMountsWithoutFilters(): void {
- $result = iterator_to_array($this->fileAccess->getDistinctMounts());
+ $result = iterator_to_array($this->fileAccess->getDistinctMounts([], false));
- $this->assertCount(2, $result);
+ $this->assertCount(3, $result);
$this->assertEquals([
'storage_id' => 1,
@@ -92,13 +103,19 @@ class FileAccessTest extends TestCase {
'root_id' => 30,
'overridden_root' => 30,
], $result[1]);
+
+ $this->assertEquals([
+ 'storage_id' => 4,
+ 'root_id' => 31,
+ 'overridden_root' => 31,
+ ], $result[2]);
}
/**
* Test that getDistinctMounts applies filtering by mount providers
*/
public function testGetDistinctMountsWithMountProviderFilter(): void {
- $result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1']));
+ $result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1'], false));
$this->assertCount(2, $result);
@@ -131,6 +148,18 @@ class FileAccessTest extends TestCase {
])
->executeStatement();
+ // Add a mount that is mounted in the home directory
+ $queryBuilder = $this->dbConnection->getQueryBuilder();
+ $queryBuilder->insert('mounts')
+ ->values([
+ 'storage_id' => $queryBuilder->createNamedParameter(5, IQueryBuilder::PARAM_INT),
+ 'root_id' => $queryBuilder->createNamedParameter(41, IQueryBuilder::PARAM_INT),
+ 'mount_provider_class' => $queryBuilder->createNamedParameter('TestMountProvider3'),
+ 'mount_point' => $queryBuilder->createNamedParameter('/test/files/foobar'),
+ 'user_id' => $queryBuilder->createNamedParameter('test'),
+ ])
+ ->executeStatement();
+
// Simulate adding a "files" directory to the filecache table
$queryBuilder = $this->dbConnection->getQueryBuilder()->runAcrossAllShards();
$queryBuilder->delete('filecache')->executeStatement();
@@ -148,11 +177,19 @@ class FileAccessTest extends TestCase {
$result = iterator_to_array($this->fileAccess->getDistinctMounts());
+ $this->assertCount(2, $result);
+
$this->assertEquals([
'storage_id' => 4,
'root_id' => 40,
'overridden_root' => 99,
- ], end($result));
+ ], $result[0]);
+
+ $this->assertEquals([
+ 'storage_id' => 5,
+ 'root_id' => 41,
+ 'overridden_root' => 41,
+ ], $result[1]);
}
private function setUpTestDatabaseForGetByAncestorInStorage(): void {