store mountprovider for each mount in the mounts table

this enabled more fine grained filesystem setup

Signed-off-by: Robin Appelman <robin@icewind.nl>
pull/30978/head
Robin Appelman 3 years ago
parent 692da9236b
commit cfb7923e08
No known key found for this signature in database
GPG Key ID: 42B69D8A64526EFB
  1. 2
      apps/files_external/lib/Config/ExternalMountPoint.php
  2. 2
      apps/files_sharing/lib/External/Mount.php
  3. 2
      apps/files_sharing/lib/SharedMount.php
  4. 37
      core/Migrations/Version240000Date20220202150027.php
  5. 1
      lib/composer/composer/autoload_classmap.php
  6. 1
      lib/composer/composer/autoload_static.php
  7. 17
      lib/private/Files/Config/CachedMountFileInfo.php
  8. 21
      lib/private/Files/Config/CachedMountInfo.php
  9. 4
      lib/private/Files/Config/LazyStorageMountInfo.php
  10. 34
      lib/private/Files/Config/UserMountCache.php
  11. 4
      lib/private/Files/Mount/CacheMountProvider.php
  12. 2
      lib/private/Files/Mount/LocalHomeMountProvider.php
  13. 25
      lib/private/Files/Mount/MountPoint.php
  14. 2
      lib/private/Files/Mount/ObjectHomeMountProvider.php
  15. 10
      lib/private/Files/Mount/ObjectStorePreviewCacheMountProvider.php
  16. 2
      lib/private/Files/Node/LazyFolder.php
  17. 13
      lib/private/Files/Node/Root.php
  18. 8
      lib/public/Files/Config/ICachedMountInfo.php
  19. 8
      lib/public/Files/Mount/IMountPoint.php
  20. 4
      tests/lib/Files/Node/FolderTest.php
  21. 2
      version.php

@ -34,7 +34,7 @@ class ExternalMountPoint extends MountPoint {
public function __construct(StorageConfig $storageConfig, $storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null, $mountId = null) {
$this->storageConfig = $storageConfig;
parent::__construct($storage, $mountpoint, $arguments, $loader, $mountOptions, $mountId);
parent::__construct($storage, $mountpoint, $arguments, $loader, $mountOptions, $mountId, ConfigAdapter::class);
}
public function getMountType() {

@ -42,7 +42,7 @@ class Mount extends MountPoint implements MoveableMount {
* @param \OC\Files\Storage\StorageFactory $loader
*/
public function __construct($storage, $mountpoint, $options, $manager, $loader = null) {
parent::__construct($storage, $mountpoint, $options, $loader);
parent::__construct($storage, $mountpoint, $options, $loader, null, null, MountProvider::class);
$this->manager = $manager;
}

@ -78,7 +78,7 @@ class SharedMount extends MountPoint implements MoveableMount {
$newMountPoint = $this->verifyMountPoint($this->superShare, $mountpoints, $folderExistCache);
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
parent::__construct($storage, $absMountPoint, $arguments, $loader);
parent::__construct($storage, $absMountPoint, $arguments, $loader, null, null, MountProvider::class);
}
/**

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace OC\Core\Migrations;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Auto-generated migration step: Please modify to your needs!
*/
class Version240000Date20220202150027 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('mounts');
if (!$table->hasColumn('mount_provider_class')) {
$table->addColumn('mount_provider_class', Types::STRING, [
'notnull' => false,
'length' => 128,
]);
return $schema;
}
return null;
}
}

@ -1001,6 +1001,7 @@ return array(
'OC\\Core\\Migrations\\Version23000Date20210930122352' => $baseDir . '/core/Migrations/Version23000Date20210930122352.php',
'OC\\Core\\Migrations\\Version23000Date20211203110726' => $baseDir . '/core/Migrations/Version23000Date20211203110726.php',
'OC\\Core\\Migrations\\Version23000Date20211213203940' => $baseDir . '/core/Migrations/Version23000Date20211213203940.php',
'OC\\Core\\Migrations\\Version240000Date20220202150027' => $baseDir . '/core/Migrations/Version240000Date20220202150027.php',
'OC\\Core\\Migrations\\Version24000Date20211210141942' => $baseDir . '/core/Migrations/Version24000Date20211210141942.php',
'OC\\Core\\Migrations\\Version24000Date20211213081506' => $baseDir . '/core/Migrations/Version24000Date20211213081506.php',
'OC\\Core\\Migrations\\Version24000Date20211213081604' => $baseDir . '/core/Migrations/Version24000Date20211213081604.php',

@ -1030,6 +1030,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Migrations\\Version23000Date20210930122352' => __DIR__ . '/../../..' . '/core/Migrations/Version23000Date20210930122352.php',
'OC\\Core\\Migrations\\Version23000Date20211203110726' => __DIR__ . '/../../..' . '/core/Migrations/Version23000Date20211203110726.php',
'OC\\Core\\Migrations\\Version23000Date20211213203940' => __DIR__ . '/../../..' . '/core/Migrations/Version23000Date20211213203940.php',
'OC\\Core\\Migrations\\Version240000Date20220202150027' => __DIR__ . '/../../..' . '/core/Migrations/Version240000Date20220202150027.php',
'OC\\Core\\Migrations\\Version24000Date20211210141942' => __DIR__ . '/../../..' . '/core/Migrations/Version24000Date20211210141942.php',
'OC\\Core\\Migrations\\Version24000Date20211213081506' => __DIR__ . '/../../..' . '/core/Migrations/Version24000Date20211213081506.php',
'OC\\Core\\Migrations\\Version24000Date20211213081604' => __DIR__ . '/../../..' . '/core/Migrations/Version24000Date20211213081604.php',

@ -30,12 +30,21 @@ class CachedMountFileInfo extends CachedMountInfo implements ICachedMountFileInf
/** @var string */
private $internalPath;
public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId, $rootInternalPath, $internalPath) {
parent::__construct($user, $storageId, $rootId, $mountPoint, $mountId, $rootInternalPath);
public function __construct(
IUser $user,
int $storageId,
int $rootId,
string $mountPoint,
?int $mountId,
string $mountProvider,
string $rootInternalPath,
string $internalPath
) {
parent::__construct($user, $storageId, $rootId, $mountPoint, $mountProvider, $mountId, $rootInternalPath);
$this->internalPath = $internalPath;
}
public function getInternalPath() {
public function getInternalPath(): string {
if ($this->getRootInternalPath()) {
return substr($this->internalPath, strlen($this->getRootInternalPath()) + 1);
} else {
@ -43,7 +52,7 @@ class CachedMountFileInfo extends CachedMountInfo implements ICachedMountFileInf
}
}
public function getPath() {
public function getPath(): string {
return $this->getMountPoint() . $this->getInternalPath();
}
}

@ -58,6 +58,9 @@ class CachedMountInfo implements ICachedMountInfo {
*/
protected $rootInternalPath;
/** @var string */
protected $mountProvider;
/**
* CachedMountInfo constructor.
*
@ -68,13 +71,25 @@ class CachedMountInfo implements ICachedMountInfo {
* @param int|null $mountId
* @param string $rootInternalPath
*/
public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null, $rootInternalPath = '') {
public function __construct(
IUser $user,
int $storageId,
int $rootId,
string $mountPoint,
string $mountProvider,
int $mountId = null,
string $rootInternalPath = ''
) {
$this->user = $user;
$this->storageId = $storageId;
$this->rootId = $rootId;
$this->mountPoint = $mountPoint;
$this->mountId = $mountId;
$this->rootInternalPath = $rootInternalPath;
if (strlen($mountProvider) > 128) {
throw new \Exception("Mount provider $mountProvider name exceeds the limit of 128 characters");
}
$this->mountProvider = $mountProvider;
}
/**
@ -138,4 +153,8 @@ class CachedMountInfo implements ICachedMountInfo {
public function getRootInternalPath() {
return $this->rootInternalPath;
}
public function getMountProvider(): string {
return $this->mountProvider;
}
}

@ -81,4 +81,8 @@ class LazyStorageMountInfo extends CachedMountInfo {
public function getRootInternalPath() {
return $this->mount->getInternalPath($this->mount->getMountPoint());
}
public function getMountProvider(): string {
return $this->mount->getMountProvider();
}
}

@ -164,7 +164,8 @@ class UserMountCache implements IUserMountCache {
if (
$newMount->getMountPoint() !== $cachedMount->getMountPoint() ||
$newMount->getStorageId() !== $cachedMount->getStorageId() ||
$newMount->getMountId() !== $cachedMount->getMountId()
$newMount->getMountId() !== $cachedMount->getMountId() ||
$newMount->getMountProvider() !== $cachedMount->getMountProvider()
) {
$changed[] = $newMount;
}
@ -180,7 +181,8 @@ class UserMountCache implements IUserMountCache {
'root_id' => $mount->getRootId(),
'user_id' => $mount->getUser()->getUID(),
'mount_point' => $mount->getMountPoint(),
'mount_id' => $mount->getMountId()
'mount_id' => $mount->getMountId(),
'mount_provider_class' => $mount->getMountProvider(),
], ['root_id', 'user_id']);
} else {
// in some cases this is legitimate, like orphaned shares
@ -195,6 +197,7 @@ class UserMountCache implements IUserMountCache {
->set('storage_id', $builder->createNamedParameter($mount->getStorageId()))
->set('mount_point', $builder->createNamedParameter($mount->getMountPoint()))
->set('mount_id', $builder->createNamedParameter($mount->getMountId(), IQueryBuilder::PARAM_INT))
->set('mount_provider_class', $builder->createNamedParameter($mount->getMountProvider()))
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
@ -219,7 +222,15 @@ class UserMountCache implements IUserMountCache {
if (!is_null($mount_id)) {
$mount_id = (int)$mount_id;
}
return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $mount_id, isset($row['path']) ? $row['path'] : '');
return new CachedMountInfo(
$user,
(int)$row['storage_id'],
(int)$row['root_id'],
$row['mount_point'],
$row['mount_provider_class'] ?? '',
$mount_id,
isset($row['path']) ? $row['path'] : '',
);
}
/**
@ -229,7 +240,7 @@ class UserMountCache implements IUserMountCache {
public function getMountsForUser(IUser $user) {
if (!isset($this->mountsForUsers[$user->getUID()])) {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID())));
@ -250,7 +261,7 @@ class UserMountCache implements IUserMountCache {
*/
public function getMountsForStorageId($numericStorageId, $user = null) {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
@ -272,7 +283,7 @@ class UserMountCache implements IUserMountCache {
*/
public function getMountsForRootId($rootFileId) {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT)));
@ -286,10 +297,10 @@ class UserMountCache implements IUserMountCache {
/**
* @param $fileId
* @return array
* @return array{int, string, int}
* @throws \OCP\Files\NotFoundException
*/
private function getCacheInfoFromFileId($fileId) {
private function getCacheInfoFromFileId($fileId): array {
if (!isset($this->cacheInfoCache[$fileId])) {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage', 'path', 'mimetype')
@ -303,7 +314,7 @@ class UserMountCache implements IUserMountCache {
if (is_array($row)) {
$this->cacheInfoCache[$fileId] = [
(int)$row['storage'],
$row['path'],
(string)$row['path'],
(int)$row['mimetype']
];
} else {
@ -326,7 +337,7 @@ class UserMountCache implements IUserMountCache {
return [];
}
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($storageId, IQueryBuilder::PARAM_INT)));
@ -343,7 +354,7 @@ class UserMountCache implements IUserMountCache {
if ($fileId === (int)$row['root_id']) {
return true;
}
$internalMountPath = isset($row['path']) ? $row['path'] : '';
$internalMountPath = $row['path'] ?? '';
return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
});
@ -356,6 +367,7 @@ class UserMountCache implements IUserMountCache {
$mount->getRootId(),
$mount->getMountPoint(),
$mount->getMountId(),
$mount->getMountProvider(),
$mount->getRootInternalPath(),
$internalPath
);

@ -61,8 +61,8 @@ class CacheMountProvider implements IMountProvider {
}
return [
new MountPoint('\OC\Files\Storage\Local', '/' . $user->getUID() . '/cache', ['datadir' => $cacheDir, $loader]),
new MountPoint('\OC\Files\Storage\Local', '/' . $user->getUID() . '/uploads', ['datadir' => $cacheDir . '/uploads', $loader])
new MountPoint('\OC\Files\Storage\Local', '/' . $user->getUID() . '/cache', ['datadir' => $cacheDir], $loader, null, null, self::class),
new MountPoint('\OC\Files\Storage\Local', '/' . $user->getUID() . '/uploads', ['datadir' => $cacheDir . '/uploads'], $loader, null, null, self::class)
];
} else {
return [];

@ -38,6 +38,6 @@ class LocalHomeMountProvider implements IHomeMountProvider {
*/
public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
$arguments = ['user' => $user];
return new MountPoint('\OC\Files\Storage\Home', '/' . $user->getUID(), $arguments, $loader);
return new MountPoint('\OC\Files\Storage\Home', '/' . $user->getUID(), $arguments, $loader, null, null, self::class);
}
}

@ -34,6 +34,7 @@ use OC\Files\Filesystem;
use OC\Files\Storage\Storage;
use OC\Files\Storage\StorageFactory;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorageFactory;
use OCP\ILogger;
class MountPoint implements IMountPoint {
@ -76,6 +77,9 @@ class MountPoint implements IMountPoint {
/** @var int|null */
protected $mountId;
/** @var string */
protected $mountProvider;
/**
* @param string|\OC\Files\Storage\Storage $storage
* @param string $mountpoint
@ -83,9 +87,18 @@ class MountPoint implements IMountPoint {
* @param \OCP\Files\Storage\IStorageFactory $loader
* @param array $mountOptions mount specific options
* @param int|null $mountId
* @param string|null $mountProvider
* @throws \Exception
*/
public function __construct($storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null, $mountId = null) {
public function __construct(
$storage,
string $mountpoint,
array $arguments = null,
IStorageFactory $loader = null,
array $mountOptions = null,
int $mountId = null,
string $mountProvider = null
) {
if (is_null($arguments)) {
$arguments = [];
}
@ -113,6 +126,12 @@ class MountPoint implements IMountPoint {
$this->class = $storage;
$this->arguments = $arguments;
}
if ($mountProvider) {
if (strlen($mountProvider) > 128) {
throw new \Exception("Mount provider $mountProvider name exceeds the limit of 128 characters");
}
}
$this->mountProvider = $mountProvider ?? '';
}
/**
@ -286,4 +305,8 @@ class MountPoint implements IMountPoint {
public function getMountType() {
return '';
}
public function getMountProvider(): string {
return $this->mountProvider;
}
}

@ -65,7 +65,7 @@ class ObjectHomeMountProvider implements IHomeMountProvider {
return null;
}
return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader);
return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader, null, null, self::class);
}
/**

@ -69,7 +69,10 @@ class ObjectStorePreviewCacheMountProvider implements IRootMountProvider {
AppdataPreviewObjectStoreStorage::class,
'/appdata_' . $instanceId . '/preview/' . $parent . '/' . $child,
$this->getMultiBucketObjectStore($i),
$loader
$loader,
null,
null,
self::class
);
$i++;
}
@ -87,7 +90,10 @@ class ObjectStorePreviewCacheMountProvider implements IRootMountProvider {
$fakeRootStorageJail,
'/appdata_' . $instanceId . '/preview/old-multibucket',
null,
$loader
$loader,
null,
null,
self::class
);
return $mountPoints;

@ -38,7 +38,7 @@ class LazyFolder implements \OCP\Files\Folder {
private $folderClosure;
/** @var LazyFolder | null */
private $folder = null;
protected $folder = null;
/**
* LazyFolder constructor.

@ -29,6 +29,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Files\Node;
use OC\Cache\CappedMemoryCache;
@ -87,8 +88,8 @@ class Root extends Folder implements IRootFolder {
* @param IUserManager $userManager
*/
public function __construct($manager,
$view,
$user,
$view,
$user,
IUserMountCache $userMountCache,
ILogger $logger,
IUserManager $userManager) {
@ -189,9 +190,9 @@ class Root extends Folder implements IRootFolder {
/**
* @param string $path
* @throws \OCP\Files\NotFoundException
* @throws \OCP\Files\NotPermittedException
* @return Node
* @throws \OCP\Files\NotPermittedException
* @throws \OCP\Files\NotFoundException
*/
public function get($path) {
$path = $this->normalizePath($path);
@ -212,8 +213,8 @@ class Root extends Folder implements IRootFolder {
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
* @throws \OCP\Files\NotPermittedException
*/
public function rename($targetPath) {
throw new NotPermittedException();
@ -225,8 +226,8 @@ class Root extends Folder implements IRootFolder {
/**
* @param string $targetPath
* @throws \OCP\Files\NotPermittedException
* @return \OC\Files\Node\Node
* @throws \OCP\Files\NotPermittedException
*/
public function copy($targetPath) {
throw new NotPermittedException();

@ -76,4 +76,12 @@ interface ICachedMountInfo {
* @since 11.0.0
*/
public function getRootInternalPath();
/**
* Get the class of the mount provider that this mount originates from
*
* @return string
* @since 24.0.0
*/
public function getMountProvider(): string;
}

@ -128,4 +128,12 @@ interface IMountPoint {
* @since 12.0.0
*/
public function getMountType();
/**
* Get the class of the mount provider that this mount originates from
*
* @return string
* @since 24.0.0
*/
public function getMountProvider(): string;
}

@ -499,6 +499,7 @@ class FolderTest extends NodeTest {
1,
0,
'/bar/',
'test',
1,
''
)]);
@ -549,6 +550,7 @@ class FolderTest extends NodeTest {
1,
0,
'/bar/',
'test',
1,
''
)]);
@ -595,6 +597,7 @@ class FolderTest extends NodeTest {
1,
0,
'/bar/',
'test',
1,
''
)]);
@ -645,6 +648,7 @@ class FolderTest extends NodeTest {
1,
0,
'/bar/',
'test',
1,
''
),

@ -30,7 +30,7 @@
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
$OC_Version = [24, 0, 0, 4];
$OC_Version = [24, 0, 0, 5];
// The human readable string
$OC_VersionString = '24.0.0 dev';

Loading…
Cancel
Save