Merge pull request #22867 from nextcloud/shared-storage-init-less

Shared storage optimizations
This commit is contained in:
Roeland Jago Douma 2020-09-17 08:55:35 +02:00 committed by GitHub
commit b0c04a3e0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 21 deletions

View File

@ -33,6 +33,7 @@
namespace OCA\Files_Sharing; namespace OCA\Files_Sharing;
use OC\Files\Cache\FailedCache; use OC\Files\Cache\FailedCache;
use OC\Files\Cache\NullWatcher;
use OC\Files\Filesystem; use OC\Files\Filesystem;
use OC\Files\Storage\FailedStorage; use OC\Files\Storage\FailedStorage;
use OC\Files\Storage\Wrapper\PermissionsMask; use OC\Files\Storage\Wrapper\PermissionsMask;
@ -125,11 +126,12 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
$this->initialized = true; $this->initialized = true;
try { try {
Filesystem::initMountPoints($this->superShare->getShareOwner()); Filesystem::initMountPoints($this->superShare->getShareOwner());
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId()); $storageId = $this->superShare->getNodeCacheEntry() ? $this->superShare->getNodeCacheEntry()->getStorageId() : null;
list($this->nonMaskedStorage, $this->rootPath) = $this->ownerView->resolvePath($sourcePath); $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId(), $storageId);
[$this->nonMaskedStorage, $this->rootPath] = $this->ownerView->resolvePath($sourcePath);
$this->storage = new PermissionsMask([ $this->storage = new PermissionsMask([
'storage' => $this->nonMaskedStorage, 'storage' => $this->nonMaskedStorage,
'mask' => $this->superShare->getPermissions() 'mask' => $this->superShare->getPermissions(),
]); ]);
} catch (NotFoundException $e) { } catch (NotFoundException $e) {
// original file not accessible or deleted, set FailedStorage // original file not accessible or deleted, set FailedStorage
@ -160,7 +162,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
if ($class === '\OC\Files\Storage\Common') { if ($class === '\OC\Files\Storage\Common') {
return true; return true;
} }
if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage'])) { if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage', '\OCP\Files\IHomeStorage'])) {
return false; return false;
} }
return parent::instanceOfStorage($class); return parent::instanceOfStorage($class);
@ -223,7 +225,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
} }
/** @var IStorage $storage */ /** @var IStorage $storage */
/** @var string $internalPath */ /** @var string $internalPath */
list($storage, $internalPath) = $this->resolvePath($path); [$storage, $internalPath] = $this->resolvePath($path);
return $storage->isReadable($internalPath); return $storage->isReadable($internalPath);
} }
@ -377,7 +379,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
if (!$storage) { if (!$storage) {
$storage = $this; $storage = $this;
} }
$sourceRoot = $this->getSourceRootInfo(); $sourceRoot = $this->getSourceRootInfo();
if ($this->storage instanceof FailedStorage) { if ($this->storage instanceof FailedStorage) {
return new FailedCache(); return new FailedCache();
} }
@ -397,6 +399,11 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
return $this->superShare->getShareOwner(); return $this->superShare->getShareOwner();
} }
public function getWatcher($path = '', $storage = null) {
// cache updating is handled by the share source
return new NullWatcher();
}
/** /**
* unshare complete storage, also the grouped shares * unshare complete storage, also the grouped shares
* *
@ -417,7 +424,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
*/ */
public function acquireLock($path, $type, ILockingProvider $provider) { public function acquireLock($path, $type, ILockingProvider $provider) {
/** @var \OCP\Files\Storage $targetStorage */ /** @var \OCP\Files\Storage $targetStorage */
list($targetStorage, $targetInternalPath) = $this->resolvePath($path); [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
$targetStorage->acquireLock($targetInternalPath, $type, $provider); $targetStorage->acquireLock($targetInternalPath, $type, $provider);
// lock the parent folders of the owner when locking the share as recipient // lock the parent folders of the owner when locking the share as recipient
if ($path === '') { if ($path === '') {
@ -433,7 +440,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
*/ */
public function releaseLock($path, $type, ILockingProvider $provider) { public function releaseLock($path, $type, ILockingProvider $provider) {
/** @var \OCP\Files\Storage $targetStorage */ /** @var \OCP\Files\Storage $targetStorage */
list($targetStorage, $targetInternalPath) = $this->resolvePath($path); [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
$targetStorage->releaseLock($targetInternalPath, $type, $provider); $targetStorage->releaseLock($targetInternalPath, $type, $provider);
// unlock the parent folders of the owner when unlocking the share as recipient // unlock the parent folders of the owner when unlocking the share as recipient
if ($path === '') { if ($path === '') {
@ -449,7 +456,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
*/ */
public function changeLock($path, $type, ILockingProvider $provider) { public function changeLock($path, $type, ILockingProvider $provider) {
/** @var \OCP\Files\Storage $targetStorage */ /** @var \OCP\Files\Storage $targetStorage */
list($targetStorage, $targetInternalPath) = $this->resolvePath($path); [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
$targetStorage->changeLock($targetInternalPath, $type, $provider); $targetStorage->changeLock($targetInternalPath, $type, $provider);
} }
@ -460,7 +467,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
// shares do not participate in availability logic // shares do not participate in availability logic
return [ return [
'available' => true, 'available' => true,
'last_checked' => 0 'last_checked' => 0,
]; ];
} }

View File

@ -1011,6 +1011,7 @@ return array(
'OC\\Files\\Cache\\HomePropagator' => $baseDir . '/lib/private/Files/Cache/HomePropagator.php', 'OC\\Files\\Cache\\HomePropagator' => $baseDir . '/lib/private/Files/Cache/HomePropagator.php',
'OC\\Files\\Cache\\LocalRootScanner' => $baseDir . '/lib/private/Files/Cache/LocalRootScanner.php', 'OC\\Files\\Cache\\LocalRootScanner' => $baseDir . '/lib/private/Files/Cache/LocalRootScanner.php',
'OC\\Files\\Cache\\MoveFromCacheTrait' => $baseDir . '/lib/private/Files/Cache/MoveFromCacheTrait.php', 'OC\\Files\\Cache\\MoveFromCacheTrait' => $baseDir . '/lib/private/Files/Cache/MoveFromCacheTrait.php',
'OC\\Files\\Cache\\NullWatcher' => $baseDir . '/lib/private/Files/Cache/NullWatcher.php',
'OC\\Files\\Cache\\Propagator' => $baseDir . '/lib/private/Files/Cache/Propagator.php', 'OC\\Files\\Cache\\Propagator' => $baseDir . '/lib/private/Files/Cache/Propagator.php',
'OC\\Files\\Cache\\QuerySearchHelper' => $baseDir . '/lib/private/Files/Cache/QuerySearchHelper.php', 'OC\\Files\\Cache\\QuerySearchHelper' => $baseDir . '/lib/private/Files/Cache/QuerySearchHelper.php',
'OC\\Files\\Cache\\Scanner' => $baseDir . '/lib/private/Files/Cache/Scanner.php', 'OC\\Files\\Cache\\Scanner' => $baseDir . '/lib/private/Files/Cache/Scanner.php',

View File

@ -1040,6 +1040,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Files\\Cache\\HomePropagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/HomePropagator.php', 'OC\\Files\\Cache\\HomePropagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/HomePropagator.php',
'OC\\Files\\Cache\\LocalRootScanner' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/LocalRootScanner.php', 'OC\\Files\\Cache\\LocalRootScanner' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/LocalRootScanner.php',
'OC\\Files\\Cache\\MoveFromCacheTrait' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/MoveFromCacheTrait.php', 'OC\\Files\\Cache\\MoveFromCacheTrait' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/MoveFromCacheTrait.php',
'OC\\Files\\Cache\\NullWatcher' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/NullWatcher.php',
'OC\\Files\\Cache\\Propagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Propagator.php', 'OC\\Files\\Cache\\Propagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Propagator.php',
'OC\\Files\\Cache\\QuerySearchHelper' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/QuerySearchHelper.php', 'OC\\Files\\Cache\\QuerySearchHelper' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/QuerySearchHelper.php',
'OC\\Files\\Cache\\Scanner' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Scanner.php', 'OC\\Files\\Cache\\Scanner' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Scanner.php',

View File

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl>
*
* @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\Files\Cache;
class NullWatcher extends Watcher {
private $policy;
public function __construct() {
}
public function setPolicy($policy) {
$this->policy = $policy;
}
public function getPolicy() {
return $this->policy;
}
public function checkUpdate($path, $cachedEntry = null) {
return false;
}
public function update($path, $cachedData) {
}
public function needsUpdate($path, $cachedData) {
return false;
}
public function cleanFolder($path) {
}
}

View File

@ -239,7 +239,7 @@ class View {
public function getLocalFile($path) { public function getLocalFile($path) {
$parent = substr($path, 0, strrpos($path, '/')); $parent = substr($path, 0, strrpos($path, '/'));
$path = $this->getAbsolutePath($path); $path = $this->getAbsolutePath($path);
list($storage, $internalPath) = Filesystem::resolvePath($path); [$storage, $internalPath] = Filesystem::resolvePath($path);
if (Filesystem::isValidPath($parent) and $storage) { if (Filesystem::isValidPath($parent) and $storage) {
return $storage->getLocalFile($internalPath); return $storage->getLocalFile($internalPath);
} else { } else {
@ -254,7 +254,7 @@ class View {
public function getLocalFolder($path) { public function getLocalFolder($path) {
$parent = substr($path, 0, strrpos($path, '/')); $parent = substr($path, 0, strrpos($path, '/'));
$path = $this->getAbsolutePath($path); $path = $this->getAbsolutePath($path);
list($storage, $internalPath) = Filesystem::resolvePath($path); [$storage, $internalPath] = Filesystem::resolvePath($path);
if (Filesystem::isValidPath($parent) and $storage) { if (Filesystem::isValidPath($parent) and $storage) {
return $storage->getLocalFolder($internalPath); return $storage->getLocalFolder($internalPath);
} else { } else {
@ -668,10 +668,10 @@ class View {
$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
/** @var \OC\Files\Storage\Storage $storage */ /** @var \OC\Files\Storage\Storage $storage */
list($storage, $internalPath) = $this->resolvePath($path); [$storage, $internalPath] = $this->resolvePath($path);
$target = $storage->fopen($internalPath, 'w'); $target = $storage->fopen($internalPath, 'w');
if ($target) { if ($target) {
list(, $result) = \OC_Helper::streamCopy($data, $target); [, $result] = \OC_Helper::streamCopy($data, $target);
fclose($target); fclose($target);
fclose($data); fclose($data);
@ -1089,7 +1089,7 @@ class View {
[Filesystem::signal_param_path => $this->getHookPath($path)] [Filesystem::signal_param_path => $this->getHookPath($path)]
); );
} }
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); [$storage, $internalPath] = Filesystem::resolvePath($absolutePath . $postFix);
if ($storage) { if ($storage) {
return $storage->hash($type, $internalPath, $raw); return $storage->hash($type, $internalPath, $raw);
} }
@ -1143,7 +1143,7 @@ class View {
$run = $this->runHooks($hooks, $path); $run = $this->runHooks($hooks, $path);
/** @var \OC\Files\Storage\Storage $storage */ /** @var \OC\Files\Storage\Storage $storage */
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); [$storage, $internalPath] = Filesystem::resolvePath($absolutePath . $postFix);
if ($run and $storage) { if ($run and $storage) {
if (in_array('write', $hooks) || in_array('delete', $hooks)) { if (in_array('write', $hooks) || in_array('delete', $hooks)) {
try { try {
@ -1568,7 +1568,7 @@ class View {
* @var \OC\Files\Storage\Storage $storage * @var \OC\Files\Storage\Storage $storage
* @var string $internalPath * @var string $internalPath
*/ */
list($storage, $internalPath) = Filesystem::resolvePath($path); [$storage, $internalPath] = Filesystem::resolvePath($path);
if ($storage) { if ($storage) {
$cache = $storage->getCache($path); $cache = $storage->getCache($path);
@ -1705,7 +1705,7 @@ class View {
* @var Storage\Storage $storage * @var Storage\Storage $storage
* @var string $internalPath * @var string $internalPath
*/ */
list($storage, $internalPath) = $this->resolvePath($path); [$storage, $internalPath] = $this->resolvePath($path);
if ($storage) { if ($storage) {
return $storage->getETag($internalPath); return $storage->getETag($internalPath);
} else { } else {
@ -1719,10 +1719,11 @@ class View {
* Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file
* *
* @param int $id * @param int $id
* @throws NotFoundException * @param int|null $storageId
* @return string * @return string
* @throws NotFoundException
*/ */
public function getPath($id) { public function getPath($id, int $storageId = null) {
$id = (int)$id; $id = (int)$id;
$manager = Filesystem::getMountManager(); $manager = Filesystem::getMountManager();
$mounts = $manager->findIn($this->fakeRoot); $mounts = $manager->findIn($this->fakeRoot);
@ -1737,6 +1738,12 @@ class View {
return $a instanceof SharedMount && (!$b instanceof SharedMount) ? 1 : -1; return $a instanceof SharedMount && (!$b instanceof SharedMount) ? 1 : -1;
}); });
if (!is_null($storageId)) {
$mounts = array_filter($mounts, function (IMountPoint $mount) use ($storageId) {
return $mount->getNumericStorageId() === $storageId;
});
}
foreach ($mounts as $mount) { foreach ($mounts as $mount) {
/** /**
* @var \OC\Files\Mount\MountPoint $mount * @var \OC\Files\Mount\MountPoint $mount
@ -1844,7 +1851,7 @@ class View {
public function verifyPath($path, $fileName) { public function verifyPath($path, $fileName) {
try { try {
/** @type \OCP\Files\Storage $storage */ /** @type \OCP\Files\Storage $storage */
list($storage, $internalPath) = $this->resolvePath($path); [$storage, $internalPath] = $this->resolvePath($path);
$storage->verifyPath($internalPath, $fileName); $storage->verifyPath($internalPath, $fileName);
} catch (ReservedWordException $ex) { } catch (ReservedWordException $ex) {
$l = \OC::$server->getL10N('lib'); $l = \OC::$server->getL10N('lib');