From e244d5cade23b7e02606d6e1b6f062db9bbd7f0c Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 10 Aug 2016 10:32:25 +0200 Subject: [PATCH 1/6] Get shared storage numeric id directly from DB To prevent recursions in initMountPoints which requires the numeric id to populate oc_mounts --- apps/files_sharing/lib/SharedMount.php | 9 +++++++++ lib/private/Files/Config/LazyStorageMountInfo.php | 12 ++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/SharedMount.php b/apps/files_sharing/lib/SharedMount.php index 2b066bd2d944..38c006d21621 100644 --- a/apps/files_sharing/lib/SharedMount.php +++ b/apps/files_sharing/lib/SharedMount.php @@ -223,4 +223,13 @@ public function getShare() { public function getStorageRootId() { return $this->share->getNodeId(); } + + public function getStorageNumericId() { + $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query->select('storage') + ->from('filecache') + ->where($query->expr()->eq('fileid', $query->createNamedParameter($this->share->getNodeId()))); + + return $query->execute()->fetchColumn(); + } } diff --git a/lib/private/Files/Config/LazyStorageMountInfo.php b/lib/private/Files/Config/LazyStorageMountInfo.php index 5df04c4b78ea..3af6a7fddb4f 100644 --- a/lib/private/Files/Config/LazyStorageMountInfo.php +++ b/lib/private/Files/Config/LazyStorageMountInfo.php @@ -47,11 +47,15 @@ public function __construct(IUser $user, IMountPoint $mount) { */ public function getStorageId() { if (!$this->storageId) { - $storage = $this->mount->getStorage(); - if (!$storage) { - return -1; + if (method_exists($this->mount, 'getStorageNumericId')) { + $this->storageId = $this->mount->getStorageNumericId(); + } else { + $storage = $this->mount->getStorage(); + if (!$storage) { + return -1; + } + $this->storageId = $storage->getStorageCache()->getNumericId(); } - $this->storageId = $storage->getStorageCache()->getNumericId(); } return parent::getStorageId(); } From 2af98ef583a94b7961c95ae558aaff6fd220e708 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 10 Aug 2016 08:26:00 +0200 Subject: [PATCH 2/6] Lazy init shared storage by tweaking jail --- apps/files_sharing/lib/sharedstorage.php | 29 +++--- lib/private/Files/Storage/Wrapper/Jail.php | 88 ++++++++++--------- lib/private/Files/Storage/Wrapper/Wrapper.php | 51 ++++++----- 3 files changed, 90 insertions(+), 78 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index b5b5e4168842..c4fd66013527 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -79,13 +79,9 @@ public function __construct($arguments) { $this->newShare = $arguments['newShare']; $this->user = $arguments['user']; - Filesystem::initMountPoints($this->newShare->getShareOwner()); - $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); - list($storage, $internalPath) = $this->ownerView->resolvePath($sourcePath); - parent::__construct([ - 'storage' => $storage, - 'root' => $internalPath, + 'storage' => null, // init later + 'root' => null, // init later ]); } @@ -94,14 +90,13 @@ private function init() { return; } $this->initialized = true; - try { - Filesystem::initMountPoints($this->newShare->getShareOwner()); - $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); - list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); - $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); - } catch (\Exception $e) { - $this->logger->logException($e); - } + Filesystem::initMountPoints($this->newShare->getShareOwner()); + $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); + list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); + $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); + // adjust jail + $this->storage = $this->sourceStorage; + $this->rootPath = $sourceInternalPath; } private function isValid() { @@ -433,4 +428,10 @@ public function file_put_contents($path, $data) { return parent::file_put_contents($path, $data); } + public function getWrapperStorage() { + $this->init(); + + return $this->sourceStorage; + } + } diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php index 1df28e9a7477..fde1144f7a4b 100644 --- a/lib/private/Files/Storage/Wrapper/Jail.php +++ b/lib/private/Files/Storage/Wrapper/Jail.php @@ -45,10 +45,15 @@ class Jail extends Wrapper { */ public function __construct($arguments) { parent::__construct($arguments); + // null value is allowed for lazy init, but it must set at earliest + // before the first file operation $this->rootPath = $arguments['root']; } public function getSourcePath($path) { + if ($this->rootPath === null) { + throw new \InvalidArgumentException('Jail rootPath is null'); + } if ($path === '') { return $this->rootPath; } else { @@ -67,7 +72,7 @@ public function getId() { * @return bool */ public function mkdir($path) { - return $this->storage->mkdir($this->getSourcePath($path)); + return $this->getWrapperStorage()->mkdir($this->getSourcePath($path)); } /** @@ -77,7 +82,7 @@ public function mkdir($path) { * @return bool */ public function rmdir($path) { - return $this->storage->rmdir($this->getSourcePath($path)); + return $this->getWrapperStorage()->rmdir($this->getSourcePath($path)); } /** @@ -87,7 +92,7 @@ public function rmdir($path) { * @return resource */ public function opendir($path) { - return $this->storage->opendir($this->getSourcePath($path)); + return $this->getWrapperStorage()->opendir($this->getSourcePath($path)); } /** @@ -97,7 +102,7 @@ public function opendir($path) { * @return bool */ public function is_dir($path) { - return $this->storage->is_dir($this->getSourcePath($path)); + return $this->getWrapperStorage()->is_dir($this->getSourcePath($path)); } /** @@ -107,7 +112,7 @@ public function is_dir($path) { * @return bool */ public function is_file($path) { - return $this->storage->is_file($this->getSourcePath($path)); + return $this->getWrapperStorage()->is_file($this->getSourcePath($path)); } /** @@ -118,7 +123,7 @@ public function is_file($path) { * @return array */ public function stat($path) { - return $this->storage->stat($this->getSourcePath($path)); + return $this->getWrapperStorage()->stat($this->getSourcePath($path)); } /** @@ -128,7 +133,7 @@ public function stat($path) { * @return bool */ public function filetype($path) { - return $this->storage->filetype($this->getSourcePath($path)); + return $this->getWrapperStorage()->filetype($this->getSourcePath($path)); } /** @@ -139,7 +144,7 @@ public function filetype($path) { * @return int */ public function filesize($path) { - return $this->storage->filesize($this->getSourcePath($path)); + return $this->getWrapperStorage()->filesize($this->getSourcePath($path)); } /** @@ -149,7 +154,7 @@ public function filesize($path) { * @return bool */ public function isCreatable($path) { - return $this->storage->isCreatable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isCreatable($this->getSourcePath($path)); } /** @@ -159,7 +164,7 @@ public function isCreatable($path) { * @return bool */ public function isReadable($path) { - return $this->storage->isReadable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isReadable($this->getSourcePath($path)); } /** @@ -169,7 +174,7 @@ public function isReadable($path) { * @return bool */ public function isUpdatable($path) { - return $this->storage->isUpdatable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isUpdatable($this->getSourcePath($path)); } /** @@ -179,7 +184,7 @@ public function isUpdatable($path) { * @return bool */ public function isDeletable($path) { - return $this->storage->isDeletable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isDeletable($this->getSourcePath($path)); } /** @@ -189,7 +194,7 @@ public function isDeletable($path) { * @return bool */ public function isSharable($path) { - return $this->storage->isSharable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isSharable($this->getSourcePath($path)); } /** @@ -200,7 +205,7 @@ public function isSharable($path) { * @return int */ public function getPermissions($path) { - return $this->storage->getPermissions($this->getSourcePath($path)); + return $this->getWrapperStorage()->getPermissions($this->getSourcePath($path)); } /** @@ -210,7 +215,7 @@ public function getPermissions($path) { * @return bool */ public function file_exists($path) { - return $this->storage->file_exists($this->getSourcePath($path)); + return $this->getWrapperStorage()->file_exists($this->getSourcePath($path)); } /** @@ -220,7 +225,7 @@ public function file_exists($path) { * @return int */ public function filemtime($path) { - return $this->storage->filemtime($this->getSourcePath($path)); + return $this->getWrapperStorage()->filemtime($this->getSourcePath($path)); } /** @@ -230,7 +235,7 @@ public function filemtime($path) { * @return string */ public function file_get_contents($path) { - return $this->storage->file_get_contents($this->getSourcePath($path)); + return $this->getWrapperStorage()->file_get_contents($this->getSourcePath($path)); } /** @@ -241,7 +246,7 @@ public function file_get_contents($path) { * @return bool */ public function file_put_contents($path, $data) { - return $this->storage->file_put_contents($this->getSourcePath($path), $data); + return $this->getWrapperStorage()->file_put_contents($this->getSourcePath($path), $data); } /** @@ -251,7 +256,7 @@ public function file_put_contents($path, $data) { * @return bool */ public function unlink($path) { - return $this->storage->unlink($this->getSourcePath($path)); + return $this->getWrapperStorage()->unlink($this->getSourcePath($path)); } /** @@ -262,7 +267,7 @@ public function unlink($path) { * @return bool */ public function rename($path1, $path2) { - return $this->storage->rename($this->getSourcePath($path1), $this->getSourcePath($path2)); + return $this->getWrapperStorage()->rename($this->getSourcePath($path1), $this->getSourcePath($path2)); } /** @@ -273,7 +278,7 @@ public function rename($path1, $path2) { * @return bool */ public function copy($path1, $path2) { - return $this->storage->copy($this->getSourcePath($path1), $this->getSourcePath($path2)); + return $this->getWrapperStorage()->copy($this->getSourcePath($path1), $this->getSourcePath($path2)); } /** @@ -284,7 +289,7 @@ public function copy($path1, $path2) { * @return resource */ public function fopen($path, $mode) { - return $this->storage->fopen($this->getSourcePath($path), $mode); + return $this->getWrapperStorage()->fopen($this->getSourcePath($path), $mode); } /** @@ -295,7 +300,7 @@ public function fopen($path, $mode) { * @return string */ public function getMimeType($path) { - return $this->storage->getMimeType($this->getSourcePath($path)); + return $this->getWrapperStorage()->getMimeType($this->getSourcePath($path)); } /** @@ -307,7 +312,7 @@ public function getMimeType($path) { * @return string */ public function hash($type, $path, $raw = false) { - return $this->storage->hash($type, $this->getSourcePath($path), $raw); + return $this->getWrapperStorage()->hash($type, $this->getSourcePath($path), $raw); } /** @@ -317,7 +322,7 @@ public function hash($type, $path, $raw = false) { * @return int */ public function free_space($path) { - return $this->storage->free_space($this->getSourcePath($path)); + return $this->getWrapperStorage()->free_space($this->getSourcePath($path)); } /** @@ -327,7 +332,7 @@ public function free_space($path) { * @return array */ public function search($query) { - return $this->storage->search($query); + return $this->getWrapperStorage()->search($query); } /** @@ -339,7 +344,7 @@ public function search($query) { * @return bool */ public function touch($path, $mtime = null) { - return $this->storage->touch($this->getSourcePath($path), $mtime); + return $this->getWrapperStorage()->touch($this->getSourcePath($path), $mtime); } /** @@ -350,7 +355,7 @@ public function touch($path, $mtime = null) { * @return string */ public function getLocalFile($path) { - return $this->storage->getLocalFile($this->getSourcePath($path)); + return $this->getWrapperStorage()->getLocalFile($this->getSourcePath($path)); } /** @@ -364,7 +369,7 @@ public function getLocalFile($path) { * returning true for other changes in the folder is optional */ public function hasUpdated($path, $time) { - return $this->storage->hasUpdated($this->getSourcePath($path), $time); + return $this->getWrapperStorage()->hasUpdated($this->getSourcePath($path), $time); } /** @@ -375,10 +380,13 @@ public function hasUpdated($path, $time) { * @return \OC\Files\Cache\Cache */ public function getCache($path = '', $storage = null) { + if ($this->rootPath === null) { + throw new \InvalidArgumentException('Jail rootPath is null'); + } if (!$storage) { $storage = $this; } - $sourceCache = $this->storage->getCache($this->getSourcePath($path), $storage); + $sourceCache = $this->getWrapperStorage()->getCache($this->getSourcePath($path), $storage); return new CacheJail($sourceCache, $this->rootPath); } @@ -389,7 +397,7 @@ public function getCache($path = '', $storage = null) { * @return string */ public function getOwner($path) { - return $this->storage->getOwner($this->getSourcePath($path)); + return $this->getWrapperStorage()->getOwner($this->getSourcePath($path)); } /** @@ -403,7 +411,7 @@ public function getWatcher($path = '', $storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getWatcher($this->getSourcePath($path), $storage); + return $this->getWrapperStorage()->getWatcher($this->getSourcePath($path), $storage); } /** @@ -413,7 +421,7 @@ public function getWatcher($path = '', $storage = null) { * @return string */ public function getETag($path) { - return $this->storage->getETag($this->getSourcePath($path)); + return $this->getWrapperStorage()->getETag($this->getSourcePath($path)); } /** @@ -421,7 +429,7 @@ public function getETag($path) { * @return array */ public function getMetaData($path) { - return $this->storage->getMetaData($this->getSourcePath($path)); + return $this->getWrapperStorage()->getMetaData($this->getSourcePath($path)); } /** @@ -431,7 +439,7 @@ public function getMetaData($path) { * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type, ILockingProvider $provider) { - $this->storage->acquireLock($this->getSourcePath($path), $type, $provider); + $this->getWrapperStorage()->acquireLock($this->getSourcePath($path), $type, $provider); } /** @@ -440,7 +448,7 @@ public function acquireLock($path, $type, ILockingProvider $provider) { * @param \OCP\Lock\ILockingProvider $provider */ public function releaseLock($path, $type, ILockingProvider $provider) { - $this->storage->releaseLock($this->getSourcePath($path), $type, $provider); + $this->getWrapperStorage()->releaseLock($this->getSourcePath($path), $type, $provider); } /** @@ -449,7 +457,7 @@ public function releaseLock($path, $type, ILockingProvider $provider) { * @param \OCP\Lock\ILockingProvider $provider */ public function changeLock($path, $type, ILockingProvider $provider) { - $this->storage->changeLock($this->getSourcePath($path), $type, $provider); + $this->getWrapperStorage()->changeLock($this->getSourcePath($path), $type, $provider); } /** @@ -459,7 +467,7 @@ public function changeLock($path, $type, ILockingProvider $provider) { * @return array */ public function resolvePath($path) { - return [$this->storage, $this->getSourcePath($path)]; + return [$this->getWrapperStorage(), $this->getSourcePath($path)]; } /** @@ -472,7 +480,7 @@ public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceIntern if ($sourceStorage === $this) { return $this->copy($sourceInternalPath, $targetInternalPath); } - return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); + return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); } /** @@ -485,6 +493,6 @@ public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceIntern if ($sourceStorage === $this) { return $this->rename($sourceInternalPath, $targetInternalPath); } - return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); + return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); } } diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index 21d7db1099be..2a4f7aff29d3 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -63,7 +63,7 @@ public function getWrapperStorage() { * @return string */ public function getId() { - return $this->storage->getId(); + return $this->getWrapperStorage()->getId(); } /** @@ -73,7 +73,7 @@ public function getId() { * @return bool */ public function mkdir($path) { - return $this->storage->mkdir($path); + return $this->getWrapperStorage()->mkdir($path); } /** @@ -423,28 +423,28 @@ public function getWatcher($path = '', $storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getWatcher($path, $storage); + return $this->getWrapperStorage()->getWatcher($path, $storage); } public function getPropagator($storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getPropagator($storage); + return $this->getWrapperStorage()->getPropagator($storage); } public function getUpdater($storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getUpdater($storage); + return $this->getWrapperStorage()->getUpdater($storage); } /** * @return \OC\Files\Cache\Storage */ public function getStorageCache() { - return $this->storage->getStorageCache(); + return $this->getWrapperStorage()->getStorageCache(); } /** @@ -454,7 +454,7 @@ public function getStorageCache() { * @return string */ public function getETag($path) { - return $this->storage->getETag($path); + return $this->getWrapperStorage()->getETag($path); } /** @@ -463,7 +463,7 @@ public function getETag($path) { * @return true */ public function test() { - return $this->storage->test(); + return $this->getWrapperStorage()->test(); } /** @@ -472,7 +472,7 @@ public function test() { * @return bool wrapped storage's isLocal() value */ public function isLocal() { - return $this->storage->isLocal(); + return $this->getWrapperStorage()->isLocal(); } /** @@ -482,7 +482,7 @@ public function isLocal() { * @return bool */ public function instanceOfStorage($class) { - return is_a($this, $class) or $this->storage->instanceOfStorage($class); + return is_a($this, $class) or $this->getWrapperStorage()->instanceOfStorage($class); } /** @@ -493,7 +493,7 @@ public function instanceOfStorage($class) { * @return mixed */ public function __call($method, $args) { - return call_user_func_array(array($this->storage, $method), $args); + return call_user_func_array(array($this->getWrapperStorage(), $method), $args); } /** @@ -505,7 +505,7 @@ public function __call($method, $args) { * @return array */ public function getDirectDownload($path) { - return $this->storage->getDirectDownload($path); + return $this->getWrapperStorage()->getDirectDownload($path); } /** @@ -514,7 +514,7 @@ public function getDirectDownload($path) { * @return array [ available, last_checked ] */ public function getAvailability() { - return $this->storage->getAvailability(); + return $this->getWrapperStorage()->getAvailability(); } /** @@ -523,7 +523,7 @@ public function getAvailability() { * @param bool $isAvailable */ public function setAvailability($isAvailable) { - $this->storage->setAvailability($isAvailable); + $this->getWrapperStorage()->setAvailability($isAvailable); } /** @@ -533,7 +533,7 @@ public function setAvailability($isAvailable) { * @throws InvalidPathException */ public function verifyPath($path, $fileName) { - $this->storage->verifyPath($path, $fileName); + $this->getWrapperStorage()->verifyPath($path, $fileName); } /** @@ -547,7 +547,7 @@ public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceIntern return $this->copy($sourceInternalPath, $targetInternalPath); } - return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } /** @@ -561,7 +561,7 @@ public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceIntern return $this->rename($sourceInternalPath, $targetInternalPath); } - return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } /** @@ -569,7 +569,7 @@ public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceIntern * @return array */ public function getMetaData($path) { - return $this->storage->getMetaData($path); + return $this->getWrapperStorage()->getMetaData($path); } /** @@ -579,8 +579,9 @@ public function getMetaData($path) { * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type, ILockingProvider $provider) { - if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $this->storage->acquireLock($path, $type, $provider); + $storage = $this->getWrapperStorage(); + if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $storage->acquireLock($path, $type, $provider); } } @@ -590,8 +591,9 @@ public function acquireLock($path, $type, ILockingProvider $provider) { * @param \OCP\Lock\ILockingProvider $provider */ public function releaseLock($path, $type, ILockingProvider $provider) { - if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $this->storage->releaseLock($path, $type, $provider); + $storage = $this->getWrapperStorage(); + if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $storage->releaseLock($path, $type, $provider); } } @@ -601,8 +603,9 @@ public function releaseLock($path, $type, ILockingProvider $provider) { * @param \OCP\Lock\ILockingProvider $provider */ public function changeLock($path, $type, ILockingProvider $provider) { - if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $this->storage->changeLock($path, $type, $provider); + $storage = $this->getWrapperStorage(); + if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $storage->changeLock($path, $type, $provider); } } } From ef5f36a96fad0da297d013d5c59c972b1fce9b8f Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 11 Aug 2016 09:29:48 +0200 Subject: [PATCH 3/6] More wrapper storage --- lib/private/Files/Storage/Wrapper/Wrapper.php | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index 2a4f7aff29d3..1e9e14129854 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -83,7 +83,7 @@ public function mkdir($path) { * @return bool */ public function rmdir($path) { - return $this->storage->rmdir($path); + return $this->getWrapperStorage()->rmdir($path); } /** @@ -93,7 +93,7 @@ public function rmdir($path) { * @return resource */ public function opendir($path) { - return $this->storage->opendir($path); + return $this->getWrapperStorage()->opendir($path); } /** @@ -103,7 +103,7 @@ public function opendir($path) { * @return bool */ public function is_dir($path) { - return $this->storage->is_dir($path); + return $this->getWrapperStorage()->is_dir($path); } /** @@ -113,7 +113,7 @@ public function is_dir($path) { * @return bool */ public function is_file($path) { - return $this->storage->is_file($path); + return $this->getWrapperStorage()->is_file($path); } /** @@ -124,7 +124,7 @@ public function is_file($path) { * @return array */ public function stat($path) { - return $this->storage->stat($path); + return $this->getWrapperStorage()->stat($path); } /** @@ -134,7 +134,7 @@ public function stat($path) { * @return bool */ public function filetype($path) { - return $this->storage->filetype($path); + return $this->getWrapperStorage()->filetype($path); } /** @@ -145,7 +145,7 @@ public function filetype($path) { * @return int */ public function filesize($path) { - return $this->storage->filesize($path); + return $this->getWrapperStorage()->filesize($path); } /** @@ -155,7 +155,7 @@ public function filesize($path) { * @return bool */ public function isCreatable($path) { - return $this->storage->isCreatable($path); + return $this->getWrapperStorage()->isCreatable($path); } /** @@ -165,7 +165,7 @@ public function isCreatable($path) { * @return bool */ public function isReadable($path) { - return $this->storage->isReadable($path); + return $this->getWrapperStorage()->isReadable($path); } /** @@ -175,7 +175,7 @@ public function isReadable($path) { * @return bool */ public function isUpdatable($path) { - return $this->storage->isUpdatable($path); + return $this->getWrapperStorage()->isUpdatable($path); } /** @@ -185,7 +185,7 @@ public function isUpdatable($path) { * @return bool */ public function isDeletable($path) { - return $this->storage->isDeletable($path); + return $this->getWrapperStorage()->isDeletable($path); } /** @@ -195,7 +195,7 @@ public function isDeletable($path) { * @return bool */ public function isSharable($path) { - return $this->storage->isSharable($path); + return $this->getWrapperStorage()->isSharable($path); } /** @@ -206,7 +206,7 @@ public function isSharable($path) { * @return int */ public function getPermissions($path) { - return $this->storage->getPermissions($path); + return $this->getWrapperStorage()->getPermissions($path); } /** @@ -216,7 +216,7 @@ public function getPermissions($path) { * @return bool */ public function file_exists($path) { - return $this->storage->file_exists($path); + return $this->getWrapperStorage()->file_exists($path); } /** @@ -226,7 +226,7 @@ public function file_exists($path) { * @return int */ public function filemtime($path) { - return $this->storage->filemtime($path); + return $this->getWrapperStorage()->filemtime($path); } /** @@ -236,7 +236,7 @@ public function filemtime($path) { * @return string */ public function file_get_contents($path) { - return $this->storage->file_get_contents($path); + return $this->getWrapperStorage()->file_get_contents($path); } /** @@ -247,7 +247,7 @@ public function file_get_contents($path) { * @return bool */ public function file_put_contents($path, $data) { - return $this->storage->file_put_contents($path, $data); + return $this->getWrapperStorage()->file_put_contents($path, $data); } /** @@ -257,7 +257,7 @@ public function file_put_contents($path, $data) { * @return bool */ public function unlink($path) { - return $this->storage->unlink($path); + return $this->getWrapperStorage()->unlink($path); } /** @@ -268,7 +268,7 @@ public function unlink($path) { * @return bool */ public function rename($path1, $path2) { - return $this->storage->rename($path1, $path2); + return $this->getWrapperStorage()->rename($path1, $path2); } /** @@ -279,7 +279,7 @@ public function rename($path1, $path2) { * @return bool */ public function copy($path1, $path2) { - return $this->storage->copy($path1, $path2); + return $this->getWrapperStorage()->copy($path1, $path2); } /** @@ -290,7 +290,7 @@ public function copy($path1, $path2) { * @return resource */ public function fopen($path, $mode) { - return $this->storage->fopen($path, $mode); + return $this->getWrapperStorage()->fopen($path, $mode); } /** @@ -301,7 +301,7 @@ public function fopen($path, $mode) { * @return string */ public function getMimeType($path) { - return $this->storage->getMimeType($path); + return $this->getWrapperStorage()->getMimeType($path); } /** @@ -313,7 +313,7 @@ public function getMimeType($path) { * @return string */ public function hash($type, $path, $raw = false) { - return $this->storage->hash($type, $path, $raw); + return $this->getWrapperStorage()->hash($type, $path, $raw); } /** @@ -323,7 +323,7 @@ public function hash($type, $path, $raw = false) { * @return int */ public function free_space($path) { - return $this->storage->free_space($path); + return $this->getWrapperStorage()->free_space($path); } /** @@ -333,7 +333,7 @@ public function free_space($path) { * @return array */ public function search($query) { - return $this->storage->search($query); + return $this->getWrapperStorage()->search($query); } /** @@ -345,7 +345,7 @@ public function search($query) { * @return bool */ public function touch($path, $mtime = null) { - return $this->storage->touch($path, $mtime); + return $this->getWrapperStorage()->touch($path, $mtime); } /** @@ -356,7 +356,7 @@ public function touch($path, $mtime = null) { * @return string */ public function getLocalFile($path) { - return $this->storage->getLocalFile($path); + return $this->getWrapperStorage()->getLocalFile($path); } /** @@ -370,7 +370,7 @@ public function getLocalFile($path) { * returning true for other changes in the folder is optional */ public function hasUpdated($path, $time) { - return $this->storage->hasUpdated($path, $time); + return $this->getWrapperStorage()->hasUpdated($path, $time); } /** @@ -384,7 +384,7 @@ public function getCache($path = '', $storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getCache($path, $storage); + return $this->getWrapperStorage()->getCache($path, $storage); } /** @@ -398,7 +398,7 @@ public function getScanner($path = '', $storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getScanner($path, $storage); + return $this->getWrapperStorage()->getScanner($path, $storage); } @@ -409,7 +409,7 @@ public function getScanner($path = '', $storage = null) { * @return string */ public function getOwner($path) { - return $this->storage->getOwner($path); + return $this->getWrapperStorage()->getOwner($path); } /** From 79e16d7d10d5a52b84b4cf6282acefacb0ad1fc1 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 11 Aug 2016 09:30:16 +0200 Subject: [PATCH 4/6] Bring back exception swallowing to prevent storagenotavailable exception from shared storage --- apps/files_sharing/lib/sharedstorage.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index c4fd66013527..1d50532dd43c 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -90,13 +90,17 @@ private function init() { return; } $this->initialized = true; - Filesystem::initMountPoints($this->newShare->getShareOwner()); - $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); - list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); - $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); - // adjust jail - $this->storage = $this->sourceStorage; - $this->rootPath = $sourceInternalPath; + try { + Filesystem::initMountPoints($this->newShare->getShareOwner()); + $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); + list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); + $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); + // adjust jail + $this->storage = $this->sourceStorage; + $this->rootPath = $sourceInternalPath; + } catch (\Exception $e) { + $this->logger->logException($e); + } } private function isValid() { From d08f97cb1c12d55dfbd8ae4fb30b044842b5a59a Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 11 Aug 2016 10:45:05 +0200 Subject: [PATCH 5/6] Flag to not recurse into shared mounts in getPath --- apps/files_sharing/lib/sharedstorage.php | 2 +- lib/private/Files/View.php | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 1d50532dd43c..7f813ad52f85 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -92,7 +92,7 @@ private function init() { $this->initialized = true; try { Filesystem::initMountPoints($this->newShare->getShareOwner()); - $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); + $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId(), false); list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); // adjust jail diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 7d9771e6394d..f81e3b4ca7e9 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -61,6 +61,7 @@ use OCP\IUser; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; +use OCA\Files_Sharing\SharedMount; /** * Class to provide access to ownCloud filesystem via a "view", and methods for @@ -1669,10 +1670,11 @@ public function getETag($path) { * 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 bool $includeShares whether to recurse into shared mounts * @throws NotFoundException * @return string */ - public function getPath($id) { + public function getPath($id, $includeShares = true) { $id = (int)$id; $manager = Filesystem::getMountManager(); $mounts = $manager->findIn($this->fakeRoot); @@ -1684,6 +1686,11 @@ public function getPath($id) { /** * @var \OC\Files\Mount\MountPoint $mount */ + if (!$includeShares && $mount instanceof SharedMount) { + // prevent potential infinite loop when instantiating shared storages + // recursively + continue; + } if ($mount->getStorage()) { $cache = $mount->getStorage()->getCache(); $internalPath = $cache->getPathById($id); From b0cba4e43e15b21af9e4b162dc97c16a7a931e88 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 11 Aug 2016 11:13:50 +0200 Subject: [PATCH 6/6] Use FailedStorage when share is invalid --- apps/files_sharing/lib/sharedstorage.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 7f813ad52f85..92220760fd75 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -37,6 +37,7 @@ use OCP\Files\Cache\ICacheEntry; use OCP\Files\Storage\IStorage; use OCP\Lock\ILockingProvider; +use OC\Files\Storage\FailedStorage; /** * Convert target path to source path and pass the function call to the correct storage provider @@ -96,11 +97,12 @@ private function init() { list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); // adjust jail - $this->storage = $this->sourceStorage; $this->rootPath = $sourceInternalPath; } catch (\Exception $e) { + $this->sourceStorage = new FailedStorage(['exception' => $e]); $this->logger->logException($e); } + $this->storage = $this->sourceStorage; } private function isValid() { @@ -311,7 +313,7 @@ public function getItemType() { public function getCache($path = '', $storage = null) { $this->init(); - if (is_null($this->sourceStorage)) { + if (is_null($this->sourceStorage) || $this->sourceStorage instanceof FailedStorage) { return new FailedCache(false); } if (!$storage) { @@ -437,5 +439,4 @@ public function getWrapperStorage() { return $this->sourceStorage; } - }