put something like the following into $CONFIG in config.php 'objectstore' => [ 'class' => 'OC\\Files\\Storage\\Manta', 'type' => 'IHomeStorage', 'arguments' => [ 'url' => 'https://stluc.manta.uqcloud.net', 'account' => 'eaitsync', 'subuser' => 'owncloud', 'role' => 'owncloud', 'key' => file_get_contents('/opt/owncloud/www/config/id_rsa'), 'stor' => 'eaitsync', 'proxy' => false, 'scope' => '_global', ], ], diff -ruN owncloud-9.0.2/.htaccess /opt/owncloud/www/.htaccess --- owncloud-9.0.2/.htaccess 2016-05-03 08:57:58.000000000 +0000 +++ /opt/owncloud/www/.htaccess 2016-06-10 07:25:44.010863553 +0000 @@ -26,8 +26,8 @@ - php_value upload_max_filesize 513M - php_value post_max_size 513M + php_value upload_max_filesize 512M + php_value post_max_size 512M php_value memory_limit 512M php_value mbstring.func_overload 0 php_value always_populate_raw_post_data -1 diff -ruN owncloud-9.0.2/.user.ini /opt/owncloud/www/.user.ini --- owncloud-9.0.2/.user.ini 2016-05-03 08:57:58.000000000 +0000 +++ /opt/owncloud/www/.user.ini 2016-04-19 04:34:56.000000000 +0000 @@ -1,5 +1,5 @@ -upload_max_filesize=513M -post_max_size=513M +upload_max_filesize=512M +post_max_size=512M memory_limit=512M mbstring.func_overload=0 always_populate_raw_post_data=-1 diff -ruN owncloud-9.0.2/3rdparty/guzzlehttp/ringphp/src/Client/CurlFactory.php /opt/owncloud/www/3rdparty/guzzlehttp/ringphp/src/Client/CurlFactory.php --- owncloud-9.0.2/3rdparty/guzzlehttp/ringphp/src/Client/CurlFactory.php 2016-05-03 08:58:06.000000000 +0000 +++ /opt/owncloud/www/3rdparty/guzzlehttp/ringphp/src/Client/CurlFactory.php 2016-04-18 06:37:58.000000000 +0000 @@ -208,7 +208,7 @@ case 'PUT': case 'POST': // See http://tools.ietf.org/html/rfc7230#section-3.3.2 - if (!Core::hasHeader($request, 'Content-Length')) { + if (0 && !Core::hasHeader($request, 'Content-Length')) { $options[CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; } break; diff -ruN owncloud-9.0.2/apps/files_external/appinfo/app.php /opt/owncloud/www/apps/files_external/appinfo/app.php --- owncloud-9.0.2/apps/files_external/appinfo/app.php 2016-05-03 08:57:59.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/appinfo/app.php 2016-04-22 01:51:56.000000000 +0000 @@ -35,6 +35,8 @@ OC::$CLASSPATH['OC\Files\Storage\AmazonS3'] = 'files_external/lib/amazons3.php'; OC::$CLASSPATH['OC\Files\Storage\Dropbox'] = 'files_external/lib/dropbox.php'; OC::$CLASSPATH['OC\Files\Storage\SFTP'] = 'files_external/lib/sftp.php'; +OC::$CLASSPATH['OC\Files\Storage\MantaEx'] = 'files_external/lib/manta.php'; +OC::$CLASSPATH['OC\Files\Storage\MantaUQCloud'] = 'files_external/lib/uqcloud.php'; OC::$CLASSPATH['OC_Mount_Config'] = 'files_external/lib/config.php'; OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php'; diff -ruN owncloud-9.0.2/apps/files_external/appinfo/application.php /opt/owncloud/www/apps/files_external/appinfo/application.php --- owncloud-9.0.2/apps/files_external/appinfo/application.php 2016-05-03 08:57:58.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/appinfo/application.php 2016-06-10 07:25:44.121399890 +0000 @@ -80,6 +80,8 @@ $container->query('OCA\Files_External\Lib\Backend\Google'), $container->query('OCA\Files_External\Lib\Backend\Swift'), $container->query('OCA\Files_External\Lib\Backend\SFTP_Key'), + $container->query('OCA\Files_External\Lib\Backend\Manta'), + $container->query('OCA\Files_External\Lib\Backend\Uqcloud'), ]); if (!\OC_Util::runningOnWindows()) { diff -ruN owncloud-9.0.2/apps/files_external/lib/auth/publickey/rsa.php /opt/owncloud/www/apps/files_external/lib/auth/publickey/rsa.php --- owncloud-9.0.2/apps/files_external/lib/auth/publickey/rsa.php 2016-05-03 08:57:58.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/lib/auth/publickey/rsa.php 2016-04-21 05:33:05.000000000 +0000 @@ -34,7 +34,7 @@ */ class RSA extends AuthMechanism { - const CREATE_KEY_BITS = 1024; + const CREATE_KEY_BITS = 2048; /** @var IConfig */ private $config; diff -ruN owncloud-9.0.2/apps/files_external/lib/backend/manta.php /opt/owncloud/www/apps/files_external/lib/backend/manta.php --- owncloud-9.0.2/apps/files_external/lib/backend/manta.php 1970-01-01 00:00:00.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/lib/backend/manta.php 2016-04-22 01:46:18.000000000 +0000 @@ -0,0 +1,35 @@ +setIdentifier('manta') + ->addIdentifierAlias('\OC\Files\Storage\MantaEx') // legacy compat + ->setStorageClass('\OC\Files\Storage\MantaEx') + ->setText($l->t('Manta')) + ->addParameters([ + (new DefinitionParameter('url', $l->t('URL'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('subuser', $l->t('Sub-User'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('stor', $l->t('stor Prefix'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ]) + ->addAuthScheme(AuthMechanism::SCHEME_PUBLICKEY) + ->setLegacyAuthMechanism($legacyAuth) + ; + } +} diff -ruN owncloud-9.0.2/apps/files_external/lib/backend/uqcloud.php /opt/owncloud/www/apps/files_external/lib/backend/uqcloud.php --- owncloud-9.0.2/apps/files_external/lib/backend/uqcloud.php 1970-01-01 00:00:00.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/lib/backend/uqcloud.php 2016-04-22 01:53:44.000000000 +0000 @@ -0,0 +1,33 @@ +setIdentifier('uqcloud') + ->addIdentifierAlias('\OC\Files\Storage\MantaUQCloud') // legacy compat + ->setStorageClass('\OC\Files\Storage\MantaUQCloud') + ->setText($l->t('manta.uqcloud.net')) + ->addParameters([ + (new DefinitionParameter('subuser', $l->t('Sub-User'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + (new DefinitionParameter('stor', $l->t('stor Prefix'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ]) + ->addAuthScheme(AuthMechanism::SCHEME_PUBLICKEY) + ->setLegacyAuthMechanism($legacyAuth) + ; + } +} diff -ruN owncloud-9.0.2/apps/files_external/lib/manta.php /opt/owncloud/www/apps/files_external/lib/manta.php --- owncloud-9.0.2/apps/files_external/lib/manta.php 1970-01-01 00:00:00.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/lib/manta.php 2016-04-22 02:01:57.000000000 +0000 @@ -0,0 +1,28 @@ + $exparams['url'], + 'account' => $exparams['user'], + ]; + if (strlen($exparams['stor'])) { + $params['stor'] = $exparams['stor']; + } + if (strlen($exparams['subuser'])) { + $params['subuser'] = $exparams['subuser']; + } + + $rsa = $exparams['public_key_auth']; + $rsa->setPassword(); + + $params['keyId'] = $rsa->getPublicKeyFingerprint('md5'); + $params['key'] = $rsa->getPrivateKey(); + + #$this->log(json_encode($params)); + return parent::__construct($params); + } +} diff -ruN owncloud-9.0.2/apps/files_external/lib/uqcloud.php /opt/owncloud/www/apps/files_external/lib/uqcloud.php --- owncloud-9.0.2/apps/files_external/lib/uqcloud.php 1970-01-01 00:00:00.000000000 +0000 +++ /opt/owncloud/www/apps/files_external/lib/uqcloud.php 2016-04-22 01:55:28.000000000 +0000 @@ -0,0 +1,9 @@ + + * @author Jörn Friedrich Dreyer + * @author Morris Jobke + * @author Robin Appelman + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Files\Storage; + +use phpseclib\Crypt\RSA; + +use GuzzleHttp\Client as GuzzleClient; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Stream\Stream; +use GuzzleHttp\Stream\NoSeekStream; +use GuzzleHttp\Stream\GuzzleStreamWrapper; + +use Icewind\Streams\IteratorDirectory; + +require_once('php-http-signature/http-signature-auth.php'); + +class Manta extends Common implements \OCP\Files\IHomeStorage { + + const OC_DIR_TYPE = 'httpd/unix-directory'; + const MANTA_DIR_TYPE = 'application/json; type=directory'; + const MANTA_DIR_STREAM = 'application/x-json-stream; type=directory'; + const MANTA_LINK_TYPE = 'application/json; type=link'; + + const LAST_MODIFIED = 'last-modified'; + const M_LAST_MODIFIED = 'm-last-modified'; + const M_CREATED = 'm-created'; + + private static $tmpFiles = []; + + public function __construct($params) { + $this->params = $params; + + if (!isset($params['url'])) { + $this->params['manta_url'] = 'https://us-east.manta.joyent.com'; + } + if (!isset($params['account'])) { + throw new \Exception('missing manta account in parameters'); + } + if (!isset($params['key'])) { + throw new \Exception('missing manta key in parameters'); + } + if (!isset($params['keyId'])) { + $rsa = new RSA(); + $rsa->loadKey($params['key']); + $rsa->setPassword(); + $this->params['keyId'] = $rsa->getPublicKeyFingerprint('md5'); + } + #if (!isset($params['stor'])) { + # throw new \Exception('missing manta stor in parameters'); + #} + + if (isset($params['user'])) { + $this->scope = $params['user']->getUID(); + } elseif (isset($params['scope'])) { + $this->scope = $params['scope']; + } else { + //$this->log(json_encode($params)); + } + + $options = [ + 'connect_timeout' => 2, + ]; + if (isset($params['proxy'])) { + if ($params['proxy'] === false) { + $options['proxy'] = [ 'http' => '', 'https' => '' ]; + } else { + $options['proxy'] = $this->params['proxy']; + } + } + if (isset($params['role'])) { + $options['headers'] = [ 'role-tag' => $params['role'] ]; + } + $this->client = new GuzzleClient($options); + + # pre warm cache + if (!$this->boot()) { + throw new \Exception("unable to init " . $this->uri('')); + } + } + + private function boot() { + $stat = $this->getCache()->get(''); + if ($stat !== false) { + return true; + } + $stat = $this->stat(''); + if ($stat !== false) { + $this->getCache()->put('', $stat); + return true; + } + + return $this->mkdir(''); + } + + public function getId() { + return implode('::', [ 'manta', $this->uri('') ]); + } + + private function uripath($p) { + $parts = [ '', $this->params['account'], 'stor' ]; + if (isset($this->params['stor']) && + strlen($this->params['stor'])) { + $parts[] = $this->params['stor']; + } + if (isset($this->scope) && + strlen($this->scope)) { + $parts[] = $this->scope; + } + $parts[] = $p; + + $path = implode('/', $parts); + return $path; + } + + private function uri($p) { + return sprintf("%s%s", + $this->params['url'], + $this->uripath($p)); + } + + private function keyId() { + $parts = [ '', $this->params['account'] ]; + if (isset($this->params['subuser'])) { + $parts[] = $this->params['subuser']; + } + $parts[] = 'keys'; + $parts[] = $this->params['keyId']; + return implode('/', $parts); + } + + protected function log($msg) { + \OCP\Util::writeLog('manta', $msg, \OCP\Util::ERROR); + } + + /** + * @param string $path + * @return string + */ + static private function normalizePath($path) { + $parts = explode('/', $path); + $parts = array_filter($parts, 'strlen'); + $path = implode('/', $parts); + + // dirname('/folder') returns '.' but internally (in the cache) we store the root as '' + if (!$path || $path === '.') { + $path = ''; + } + + return $path; + } + + private function sign($contentType = null) { + $options = [ + 'keyId' => $this->keyId(), + 'key' => $this->params['key'], + ]; + + if (isset($this->params['signalg'])) { + $options['algorithm'] = 'rsa-sha512'; + } + + $headers = []; + + if (!is_null($contentType)) { + $options['headers'] = [ 'date', 'content-type' ]; + $headers['content-type'] = $contentType; + } + + \HTTPSignature::sign($headers, $options); + + return ($headers); + } + + public function mkdir($path) { + \OCP\Util::writeLog('manta', "mkdir($path)", \OCP\Util::ERROR); + $path = self::normalizePath($path); + + $res = $this->client->put($this->uri($path), [ + 'headers' => $this->sign(self::MANTA_DIR_TYPE), + ]); + + return true; + } + + public function rmdir($path) { + $this->log("rmdir($path)"); + #\OCP\Util::writeLog('manta', "rmdir($path)", \OCP\Util::ERROR); + return $this->unlink($path); + } + + public function unlink($path) { + $path = self::normalizePath($path); + + try { + $res = $this->client->delete($this->uri($path), [ 'headers' => $this->sign() ]); + } catch (ClientException $e) { + $res = $e->getResponse(); + if ($res->getStatusCode() != 404) { + $this->log("unlink($path): " . $e->getMessage(), \OCP\Util::ERROR); + return false; + } + } + + $this->getCache()->remove($path); + + return true; + } + + static protected function manta2mime($type) { + return $type == self::MANTA_DIR_STREAM ? self::OC_DIR_TYPE : $type; + } + + static private function mtime($res) { + $last_modified = 'date'; + if ($res->hasHeader(self::M_LAST_MODIFIED)) { + $last_modified = self::M_LAST_MODIFIED; + } elseif ($res->hasHeader(self::LAST_MODIFIED)) { + $last_modified = self::LAST_MODIFIED; + } + + return $res->getHeader($last_modified); + } + + static private function smtime($res, $mtime = null) { + if ($res->hasHeader(self::M_CREATED)) { + return $res->getHeader(self::M_CREATED); + } + + if (is_null($mtime)) { + $mtime = self::mtime($res); + } + + return $mtime; + } + + static private function utime($time) { + $dt = \DateTimeImmutable::createFromFormat(\DateTime::RFC2822, $time); + return $dt->getTimestamp(); + } + + static private function htime($time) { + return date(\DateTime::RFC2822, $time); + } + + public function stat($path) { + $rv = $this->_stat($path); + #\OCP\Util::writeLog('manta', json_encode([ "stat($path)" => $rv ]), \OCP\Util::ERROR); + return $rv; + } + + private function _stat($path) { + $path = self::normalizePath($path); + + try { + $res = $this->client->head($this->uri($path), [ + 'headers' => $this->sign(), + ]); + } catch (ClientException $e) { + $res = $e->getResponse(); + if ($res->getStatusCode() != 404) { + \OCP\Util::writeLog('manta', "stat($path): " . $e->getMessage(), \OCP\Util::ERROR); + } + return false; + } + + $size = 0; + + + $content_type = $res->getHeader('Content-Type'); + if ($content_type === self::MANTA_DIR_STREAM) { + $mtime = $smtime = $res->getHeader('Date'); + $etag = $res->getHeader('result-set-size'); + } else { + if ($res->hasHeader('Content-Length')) { + $size = $res->getHeader('Content-Length'); + } elseif ($res->hasHeader('X-Original-Content-Length')) { + $size = $res->getHeader('X-Original-Content-Length'); + } + $mtime = self::mtime($res); + $smtime = self::smtime($res, $mtime); + $etag = $res->getHeader('Etag'); + } + + $stat = [ + 'size' => $size, + 'mtime' => self::utime($mtime), + 'storage_mtime' => self::utime($smtime), + 'mimetype' => self::manta2mime($content_type), + 'etag' => $etag, + 'permissions' => \OCP\Constants::PERMISSION_ALL, # - \OCP\Constants::PERMISSION_CREATE, + ]; + + #\OCP\Util::writeLog('manta', json_encode([ 'stat' => $stat ]), \OCP\Util::ERROR); + + return $stat; + } + + public function opendir($path) { + #$this->log("opendir($path)"); + $path = self::normalizePath($path); + + $res = $this->client->get($this->uri($path), [ 'headers' => $this->sign(), ]); + if ($res->getHeader('Content-Type') != self::MANTA_DIR_STREAM) { + return false; + } + $stream = GuzzleStreamWrapper::getResource($res->getBody()); + + $files = []; + while ($line = fgets($stream)) { + if ($line == "") { + continue; + } + + $file = json_decode($line, true); + if ($file === false) { + return false; + } + + $files[] = $file['name']; + } + + return IteratorDirectory::wrap($files); + } + + public function filetype($path) { + $type = $this->getMimeType($path); + if ($type === false) { + return false; + } + + return $type == self::OC_DIR_TYPE ? 'dir' : 'file'; + } + + public function fopen($path, $mode) { + $path = self::normalizePath($path); + //$this->log("fopen($path, $mode)"); + + switch ($mode) { + case 'r': + case 'rb': + try { + $res = $this->client->get($this->uri($path), [ 'headers' => $this->sign(), 'stream' => true ]); + $stream = $res->getBody(); + $stream->setSize($res->getHeader('Content-Length')); + return GuzzleStreamWrapper::getResource($stream); + } catch (\Exception $e) { + } catch (ClientException $e) { + $res = $e->getResponse(); + if ($res->getStatusCode() != 404) { + $this->log("fopen($path): " . $e->getMessage()); + } + } + return false; + case 'w': + case 'wb': + case 'a': + case 'ab': + case 'r+': + case 'w+': + case 'wb+': + case 'a+': + case 'x': + case 'x+': + case 'c': + case 'c+': + if (strrpos($path, '.') !== false) { + $ext = substr($path, strrpos($path, '.')); + } else { + $ext = ''; + } + $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); + + $source = $this->fopen($path, 'r'); + if ($source !== false) { + file_put_contents($tmpFile, $source); + } + + self::$tmpFiles[$tmpFile] = $path; + return fopen('close://' . $tmpFile, $mode); + } + + return false; + } + + public function file_exists($path) { + return $this->stat($path) !== false; + } + + public function rename($source, $target) { + #$l = sprintf("%s(%s, %s)", __FUNCTION__, $source, $target); + #$this->log($l); + + #$this->unlink($target); + + $headers = $this->sign(self::MANTA_LINK_TYPE); + $headers['Location'] = $this->uripath(self::normalizePath($source)); + + $res = $this->client->put($this->uri(self::normalizePath($target)), [ 'headers' => $headers ]); + #$this->log("$l: " . $res->getStatusCode()); + + $this->unlink($source); + + return true; + } + + public function getMimeType($path) { + #\OCP\Util::writeLog('manta', "getMimeType($path)", \OCP\Util::ERROR); + $stat = $this->stat($path); + if ($stat === false) { + return false; + } + + return $stat['mimetype']; + } + + public function getMetaData($path) { + $stat = $this->stat($path); + if ($stat === false) { + return false; + } + + if (isset($stat['mimetype']) && $stat['mimetype'] == self::OC_DIR_TYPE) { + $stat['size'] = -1; + } + + return $stat; + } + + public function touch($opath, $mtime = null) { + #$this->log("touch($opath)"); + + $path = self::normalizePath($opath); + $url = $this->uri($path); + + try { + $res = $this->client->head($url, [ + 'headers' => $this->sign(), + ]); + } catch (ClientException $e) { + $res = $e->getResponse(); + } + + $headers = $this->sign(\OC::$server->getMimeTypeDetector()->detectPath($opath)); + if ($res->getStatusCode() == 404) { + $headers['content-length'] = 0; + } elseif ($res->getHeader('Content-Type') == self::MANTA_DIR_STREAM) { + return false; + } else { + $url .= '?metadata=true'; + $headers = $this->sign($res->getHeader('Content-Type')); + $headers[ self::M_CREATED ] = self::smtime($res); + #$headers['Content-Cength'] = $res->getHeader('Content-Length'); + } + + if (!is_null($mtime)) { + $headers[self::M_LAST_MODIFIED] = date(\DateTime::RFC2822, $mtime); + } + + try { + $res = $this->client->put($url, [ 'headers' => $headers ]); + } catch (\Exception $e) { + $this->log("touch($opath, $mtime): " . $e->getMessage() . " " . $e->getResponse()->getBody()); + return true; + } + + return true; + } + + public function writeBack($tmpFile) { + #$this->log("writeBack($tmpFile)"); + if (!isset(self::$tmpFiles[$tmpFile])) { + return; + } + + $path = self::normalizePath(self::$tmpFiles[$tmpFile]); + $type = \OC::$server->getMimeTypeDetector()->detect($tmpFile); + + $headers = $this->sign($type); + $headers['Content-Length'] = filesize($tmpFile); + + $res = $this->client->put($this->uri($path), [ + 'headers' => $headers, + 'body' => fopen($tmpFile, 'r'), + ]); + + // update stat with new data + $mtime = \DateTimeImmutable::createFromFormat(\DateTime::RFC2822, $res->getHeader('Last-Modified')); + + $stat = [ + 'size' => filesize($tmpFile), + 'mtime' => $mtime->getTimestamp(), + 'storage_mtime' => $mtime->getTimestamp(), + 'mimetype' => $type, + 'etag' => $res->getHeader('Etag'), + 'permissions' => \OCP\Constants::PERMISSION_ALL, # - \OCP\Constants::PERMISSION_CREATE, + ]; + + $fileId = $this->getCache()->put($path, $stat); + } + + public static function checkDependencies() { + return true; + } +} diff -ruN owncloud-9.0.2/lib/private/helper.php /opt/owncloud/www/lib/private/helper.php --- owncloud-9.0.2/lib/private/helper.php 2016-05-03 08:57:59.000000000 +0000 +++ /opt/owncloud/www/lib/private/helper.php 2016-04-19 03:31:46.000000000 +0000 @@ -308,7 +308,11 @@ if (!$source or !$target) { return array(0, false); } - $bufSize = 8192; + //$bufSize = 8192; + $bufSize = 512 * 1024; + stream_set_chunk_size($source, $bufSize); + stream_set_chunk_size($target, $bufSize); + $result = true; $count = 0; while (!feof($source)) { diff -ruN owncloud-9.0.2/lib/private/util.php /opt/owncloud/www/lib/private/util.php --- owncloud-9.0.2/lib/private/util.php 2016-05-03 08:57:59.000000000 +0000 +++ /opt/owncloud/www/lib/private/util.php 2016-06-17 06:16:41.461113928 +0000 @@ -98,10 +98,12 @@ $config['arguments'] = array(); } - // instantiate object store implementation - $config['arguments']['objectstore'] = new $config['class']($config['arguments']); - // mount with plain / root object store implementation - $config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage'; + if (!isset($config['type']) || $config['type'] !== 'IHomeStorage') { + // instantiate object store implementation + $config['arguments']['objectstore'] = new $config['class']($config['arguments']); + // mount with plain / root object store implementation + $config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage'; + } // mount object storage as root \OC\Files\Filesystem::initMountManager();