diff options
Diffstat (limited to 'lib/private/files')
-rw-r--r-- | lib/private/files/cache/backgroundwatcher.php | 107 | ||||
-rw-r--r-- | lib/private/files/cache/cache.php | 17 | ||||
-rw-r--r-- | lib/private/files/cache/changepropagator.php | 98 | ||||
-rw-r--r-- | lib/private/files/cache/homecache.php | 2 | ||||
-rw-r--r-- | lib/private/files/cache/permissions.php | 156 | ||||
-rw-r--r-- | lib/private/files/cache/scanner.php | 106 | ||||
-rw-r--r-- | lib/private/files/filesystem.php | 4 | ||||
-rw-r--r-- | lib/private/files/node/folder.php | 5 | ||||
-rw-r--r-- | lib/private/files/storage/common.php | 7 | ||||
-rw-r--r-- | lib/private/files/storage/loader.php | 4 | ||||
-rw-r--r-- | lib/private/files/storage/storage.php | 8 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/wrapper.php | 10 | ||||
-rw-r--r-- | lib/private/files/stream/quota.php | 2 | ||||
-rw-r--r-- | lib/private/files/utils/scanner.php | 21 | ||||
-rw-r--r-- | lib/private/files/view.php | 27 |
15 files changed, 192 insertions, 382 deletions
diff --git a/lib/private/files/cache/backgroundwatcher.php b/lib/private/files/cache/backgroundwatcher.php deleted file mode 100644 index 2194651233d..00000000000 --- a/lib/private/files/cache/backgroundwatcher.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files\Cache; - -use \OC\Files\Mount; -use \OC\Files\Filesystem; - -class BackgroundWatcher { - static $folderMimetype = null; - - static private function getFolderMimetype() { - if (!is_null(self::$folderMimetype)) { - return self::$folderMimetype; - } - $sql = 'SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'; - $result = \OC_DB::executeAudited($sql, array('httpd/unix-directory')); - $row = $result->fetchRow(); - return $row['id']; - } - - /** - * @param integer $id - */ - static private function checkUpdate($id) { - $cacheItem = Cache::getById($id); - if (is_null($cacheItem)) { - return; - } - list($storageId, $internalPath) = $cacheItem; - $mounts = Filesystem::getMountByStorageId($storageId); - - if (count($mounts) === 0) { - //if the storage we need isn't mounted on default, try to find a user that has access to the storage - $permissionsCache = new Permissions($storageId); - $users = $permissionsCache->getUsers($id); - if (count($users) === 0) { - return; - } - Filesystem::initMountPoints($users[0]); - $mounts = Filesystem::getMountByStorageId($storageId); - if (count($mounts) === 0) { - return; - } - } - $storage = $mounts[0]->getStorage(); - $watcher = new Watcher($storage); - $watcher->checkUpdate($internalPath); - } - - /** - * get the next fileid in the cache - * - * @param int $previous - * @param bool $folder - * @return int - */ - static private function getNextFileId($previous, $folder) { - if ($folder) { - $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` = ? ORDER BY `fileid` ASC', 1); - } else { - $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` != ? ORDER BY `fileid` ASC', 1); - } - $result = \OC_DB::executeAudited($stmt, array($previous,self::getFolderMimetype())); - if ($row = $result->fetchRow()) { - return $row['fileid']; - } else { - return 0; - } - } - - static public function checkNext() { - // check both 1 file and 1 folder, this way new files are detected quicker because there are less folders than files usually - $previousFile = \OC_Appconfig::getValue('files', 'backgroundwatcher_previous_file', 0); - $previousFolder = \OC_Appconfig::getValue('files', 'backgroundwatcher_previous_folder', 0); - $nextFile = self::getNextFileId($previousFile, false); - $nextFolder = self::getNextFileId($previousFolder, true); - \OC_Appconfig::setValue('files', 'backgroundwatcher_previous_file', $nextFile); - \OC_Appconfig::setValue('files', 'backgroundwatcher_previous_folder', $nextFolder); - if ($nextFile > 0) { - self::checkUpdate($nextFile); - } - if ($nextFolder > 0) { - self::checkUpdate($nextFolder); - } - } - - static public function checkAll() { - $previous = 0; - $next = 1; - while ($next != 0) { - $next = self::getNextFileId($previous, true); - self::checkUpdate($next); - } - $previous = 0; - $next = 1; - while ($next != 0) { - $next = self::getNextFileId($previous, false); - self::checkUpdate($next); - } - } -} diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 59963f41e3d..bfd280a91a1 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -123,7 +123,7 @@ class Cache { $params = array($file); } $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` + `storage_mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` ' . $where; $result = \OC_DB::executeAudited($sql, $params); $data = $result->fetchRow(); @@ -153,6 +153,7 @@ class Cache { if ($data['storage_mtime'] == 0) { $data['storage_mtime'] = $data['mtime']; } + $data['permissions'] = (int)$data['permissions']; } return $data; @@ -178,7 +179,7 @@ class Cache { public function getFolderContentsById($fileId) { if ($fileId > -1) { $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` + `storage_mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'; $result = \OC_DB::executeAudited($sql,array($fileId)); $files = $result->fetchAll(); @@ -192,6 +193,7 @@ class Cache { $file['encrypted_size'] = $file['size']; $file['size'] = $file['unencrypted_size']; } + $file['permissions'] = (int)$file['permissions']; } return $files; } else { @@ -277,7 +279,9 @@ class Cache { * @return array */ function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'unencrypted_size', 'etag'); + $fields = array( + 'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'unencrypted_size', + 'etag', 'permissions'); $params = array(); $queryParts = array(); foreach ($data as $name => $value) { @@ -370,9 +374,6 @@ class Cache { $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'; \OC_DB::executeAudited($sql, array($entry['fileid'])); - - $permissionsCache = new Permissions($this->storageId); - $permissionsCache->remove($entry['fileid']); } /** @@ -457,7 +458,7 @@ class Cache { // normalize pattern $pattern = $this->normalize($pattern); - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'; $result = \OC_DB::executeAudited($sql, array($pattern, $this->getNumericStorageId())); $files = array(); @@ -481,7 +482,7 @@ class Cache { } else { $where = '`mimepart` = ?'; } - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'; $mimetype = $this->getMimetypeId($mimetype); $result = \OC_DB::executeAudited($sql, array($mimetype, $this->getNumericStorageId())); diff --git a/lib/private/files/cache/changepropagator.php b/lib/private/files/cache/changepropagator.php new file mode 100644 index 00000000000..30f2e675e2e --- /dev/null +++ b/lib/private/files/cache/changepropagator.php @@ -0,0 +1,98 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +/** + * Propagates changes in etag and mtime up the filesystem tree + * + * @package OC\Files\Cache + */ +class ChangePropagator { + /** + * @var string[] + */ + protected $changedFiles = array(); + + /** + * @var \OC\Files\View + */ + protected $view; + + /** + * @param \OC\Files\View $view + */ + public function __construct(\OC\Files\View $view) { + $this->view = $view; + } + + public function addChange($path) { + $this->changedFiles[] = $path; + } + + public function getChanges() { + return $this->changedFiles; + } + + /** + * propagate the registered changes to their parent folders + * + * @param int $time (optional) the mtime to set for the folders, if not set the current time is used + */ + public function propagateChanges($time = null) { + $parents = $this->getAllParents(); + $this->changedFiles = array(); + if (!$time) { + $time = time(); + } + foreach ($parents as $parent) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + + list($storage, $internalPath) = $this->view->resolvePath($parent); + $cache = $storage->getCache(); + $id = $cache->getId($internalPath); + $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); + } + } + + /** + * @return string[] + */ + public function getAllParents() { + $parents = array(); + foreach ($this->getChanges() as $path) { + $parents = array_values(array_unique(array_merge($parents, $this->getParents($path)))); + } + return $parents; + } + + /** + * get all parent folders of $path + * + * @param string $path + * @return string[] + */ + protected function getParents($path) { + $parts = explode('/', $path); + + // remove the singe file + array_pop($parts); + $result = array('/'); + $resultPath = ''; + foreach ($parts as $part) { + if ($part) { + $resultPath .= '/' . $part; + $result[] = $resultPath; + } + } + return $result; + } +} diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php index f61769f0b9b..06ae62015a5 100644 --- a/lib/private/files/cache/homecache.php +++ b/lib/private/files/cache/homecache.php @@ -17,7 +17,7 @@ class HomeCache extends Cache { * @return int */ public function calculateFolderSize($path, $entry = null) { - if ($path !== '/' and $path !== '' and $path !== 'files' and $path !== 'files_trashbin') { + if ($path !== '/' and $path !== '' and $path !== 'files' and $path !== 'files_trashbin' and $path !== 'files_versions') { return parent::calculateFolderSize($path, $entry); } elseif ($path === '' or $path === '/') { // since the size of / isn't used (the size of /files is used instead) there is no use in calculating it diff --git a/lib/private/files/cache/permissions.php b/lib/private/files/cache/permissions.php deleted file mode 100644 index eba18af3863..00000000000 --- a/lib/private/files/cache/permissions.php +++ /dev/null @@ -1,156 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files\Cache; - -class Permissions { - /** - * @var string $storageId - */ - private $storageId; - - /** - * @param \OC\Files\Storage\Storage|string $storage - */ - public function __construct($storage) { - if ($storage instanceof \OC\Files\Storage\Storage) { - $this->storageId = $storage->getId(); - } else { - $this->storageId = $storage; - } - } - - /** - * get the permissions for a single file - * - * @param int $fileId - * @param string $user - * @return int (-1 if file no permissions set) - */ - public function get($fileId, $user) { - $sql = 'SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($user, $fileId)); - if ($row = $result->fetchRow()) { - return $this->updatePermissions($row['permissions']); - } else { - return -1; - } - } - - /** - * set the permissions of a file - * - * @param int $fileId - * @param string $user - * @param int $permissions - */ - public function set($fileId, $user, $permissions) { - if (self::get($fileId, $user) !== -1) { - $sql = 'UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'; - } else { - $sql = 'INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`) VALUES(?, ?,? )'; - } - \OC_DB::executeAudited($sql, array($permissions, $user, $fileId)); - } - - /** - * get the permissions of multiply files - * - * @param int[] $fileIds - * @param string $user - * @return int[] - */ - public function getMultiple($fileIds, $user) { - if (count($fileIds) === 0) { - return array(); - } - $params = $fileIds; - $params[] = $user; - $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - - $sql = 'SELECT `fileid`, `permissions` FROM `*PREFIX*permissions`' - . ' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'; - $result = \OC_DB::executeAudited($sql, $params); - $filePermissions = array(); - while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $this->updatePermissions($row['permissions']); - } - return $filePermissions; - } - - /** - * get the permissions for all files in a folder - * - * @param int $parentId - * @param string $user - * @return int[] - */ - public function getDirectoryPermissions($parentId, $user) { - $sql = 'SELECT `*PREFIX*permissions`.`fileid`, `permissions` - FROM `*PREFIX*permissions` - INNER JOIN `*PREFIX*filecache` ON `*PREFIX*permissions`.`fileid` = `*PREFIX*filecache`.`fileid` - WHERE `*PREFIX*filecache`.`parent` = ? AND `*PREFIX*permissions`.`user` = ?'; - - $result = \OC_DB::executeAudited($sql, array($parentId, $user)); - $filePermissions = array(); - while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $this->updatePermissions($row['permissions']); - } - return $filePermissions; - } - - /** - * remove the permissions for a file - * - * @param int $fileId - * @param string $user - */ - public function remove($fileId, $user = null) { - if (is_null($user)) { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ?', array($fileId)); - } else { - $sql = 'DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'; - \OC_DB::executeAudited($sql, array($fileId, $user)); - } - } - - public function removeMultiple($fileIds, $user) { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); - foreach ($fileIds as $fileId) { - \OC_DB::executeAudited($query, array($fileId, $user)); - } - } - - /** - * get the list of users which have permissions stored for a file - * - * @param int $fileId - */ - public function getUsers($fileId) { - $sql = 'SELECT `user` FROM `*PREFIX*permissions` WHERE `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($fileId)); - $users = array(); - while ($row = $result->fetchRow()) { - $users[] = $row['user']; - } - return $users; - } - - /** - * check if admin removed the share permission for the user and update the permissions - * - * @param int $permissions - * @return int - */ - protected function updatePermissions($permissions) { - if (\OCP\Util::isSharingDisabledForUser()) { - $permissions &= ~\OCP\PERMISSION_SHARE; - } - return $permissions; - } -} diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index b97070fcdf0..965013c5c98 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -40,11 +40,6 @@ class Scanner extends BasicEmitter { protected $cache; /** - * @var \OC\Files\Cache\Permissions $permissionsCache - */ - protected $permissionsCache; - - /** * @var boolean $cacheActive If true, perform cache operations, if false, do not affect cache */ protected $cacheActive; @@ -59,7 +54,6 @@ class Scanner extends BasicEmitter { $this->storage = $storage; $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); - $this->permissionsCache = $storage->getPermissionsCache(); $this->cacheActive = !Config::getSystemValue('filesystem_cache_readonly', false); } @@ -86,6 +80,7 @@ class Scanner extends BasicEmitter { } $data['etag'] = $this->storage->getETag($path); $data['storage_mtime'] = $data['mtime']; + $data['permissions'] = $this->storage->getPermissions($path); return $data; } @@ -117,41 +112,21 @@ class Scanner extends BasicEmitter { $newData = $data; $cacheData = $this->cache->get($file); if ($cacheData) { - if (isset($cacheData['fileid'])) { - $this->permissionsCache->remove($cacheData['fileid']); - } if ($reuseExisting) { // prevent empty etag if (empty($cacheData['etag'])) { $etag = $data['etag']; - $propagateETagChange = true; } else { $etag = $cacheData['etag']; - $propagateETagChange = false; } // only reuse data if the file hasn't explicitly changed if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) { + $data['mtime'] = $cacheData['mtime']; if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { $data['size'] = $cacheData['size']; } if ($reuseExisting & self::REUSE_ETAG) { $data['etag'] = $etag; - if ($propagateETagChange) { - $parent = $file; - while ($parent !== '') { - $parent = dirname($parent); - if ($parent === '.') { - $parent = ''; - } - $parentCacheData = $this->cache->get($parent); - \OC_Hook::emit('Scanner', 'updateCache', array('file' => $file, 'data' => $data)); - if($this->cacheActive) { - $this->cache->update($parentCacheData['fileid'], array( - 'etag' => $this->storage->getETag($parent), - )); - } - } - } } } // Only update metadata that has changed @@ -166,24 +141,53 @@ class Scanner extends BasicEmitter { } } if (!empty($newData)) { - \OC_Hook::emit('Scanner', 'addToCache', array('file' => $file, 'data' => $newData)); - if($this->cacheActive) { - $data['fileid'] = $this->cache->put($file, $newData); - } + $data['fileid'] = $this->addToCache($file, $newData); $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId)); \OC_Hook::emit('\OC\Files\Cache\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } } else { - \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $file)); - if($this->cacheActive) { - $this->cache->remove($file); - } + $this->removeFromCache($file); } return $data; } return null; } + protected function removeFromCache($path) { + \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $path)); + $this->emit('\OC\Files\Cache\Scanner', 'removeFromCache', array($path)); + if ($this->cacheActive) { + $this->cache->remove($path); + } + } + + /** + * @param string $path + * @param array $data + * @return int the id of the added file + */ + protected function addToCache($path, $data) { + \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data)); + $this->emit('\OC\Files\Cache\Scanner', 'addToCache', array($path, $this->storageId, $data)); + if ($this->cacheActive) { + return $this->cache->put($path, $data); + } else { + return -1; + } + } + + /** + * @param string $path + * @param array $data + */ + protected function updateCache($path, $data) { + \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data)); + $this->emit('\OC\Files\Cache\Scanner', 'updateCache', array($path, $this->storageId, $data)); + if ($this->cacheActive) { + $this->cache->put($path, $data); + } + } + /** * scan a folder and all it's children * @@ -236,18 +240,15 @@ class Scanner extends BasicEmitter { try { $data = $this->scanFile($child, $reuse, true); if ($data) { - if ($data['size'] === -1) { - if ($recursive === self::SCAN_RECURSIVE) { - $childQueue[] = $child; - } else { - $size = -1; - } + if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) { + $childQueue[] = $child; + } else if ($data['size'] === -1) { + $size = -1; } else if ($size !== -1) { $size += $data['size']; } } - } - catch (\Doctrine\DBAL\DBALException $ex){ + } catch (\Doctrine\DBAL\DBALException $ex) { // might happen if inserting duplicate while a scanning // process is running in parallel // log and ignore @@ -260,13 +261,10 @@ class Scanner extends BasicEmitter { $removedChildren = \array_diff($existingChildren, $newChildren); foreach ($removedChildren as $childName) { $child = ($path) ? $path . '/' . $childName : $childName; - \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $child)); - if($this->cacheActive) { - $this->cache->remove($child); - } + $this->removeFromCache($child); } \OC_DB::commit(); - if ($exceptionOccurred){ + if ($exceptionOccurred) { // It might happen that the parallel scan process has already // inserted mimetypes but those weren't available yet inside the transaction // To make sure to have the updated mime types in such cases, @@ -278,15 +276,11 @@ class Scanner extends BasicEmitter { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { $size = -1; - } else { + } else if ($size !== -1) { $size += $childSize; } } - $newData = array('size' => $size); - \OC_Hook::emit('Scanner', 'addToCache', array('file' => $child, 'data' => $newData)); - if($this->cacheActive) { - $this->cache->put($path, $newData); - } + $this->updateCache($path, array('size' => $size)); } $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; @@ -296,6 +290,7 @@ class Scanner extends BasicEmitter { * check if the file should be ignored when scanning * NOTE: files with a '.part' extension are ignored as well! * prevents unfinished put requests to be scanned + * * @param string $file * @return boolean */ @@ -314,7 +309,7 @@ class Scanner extends BasicEmitter { while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); - if($this->cacheActive) { + if ($this->cacheActive) { $this->cache->correctFolderSize($path); } $lastPath = $path; @@ -323,6 +318,7 @@ class Scanner extends BasicEmitter { /** * Set whether the cache is affected by scan operations + * * @param boolean $active The active state of the cache */ public function setCacheActive($active) { diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index ad7213d2368..2cc4a2130eb 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -168,8 +168,8 @@ class Filesystem { /** * @param callable $wrapper */ - public static function addStorageWrapper($wrapper) { - self::getLoader()->addStorageWrapper($wrapper); + public static function addStorageWrapper($wrapperName, $wrapper) { + self::getLoader()->addStorageWrapper($wrapperName, $wrapper); $mounts = self::getMountManager()->getAll(); foreach ($mounts as $mount) { diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php index 1af34fc2be6..3e23f5c2c94 100644 --- a/lib/private/files/node/folder.php +++ b/lib/private/files/node/folder.php @@ -71,13 +71,11 @@ class Folder extends Node implements \OCP\Files\Folder { list($storage, $internalPath) = $this->view->resolvePath($this->path); if ($storage) { $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); //trigger cache update check $this->view->getFileInfo($this->path); $files = $cache->getFolderContents($internalPath); - $permissions = $permissionsCache->getDirectoryPermissions($this->getId(), $this->root->getUser()->getUID()); } else { $files = array(); } @@ -129,9 +127,6 @@ class Folder extends Node implements \OCP\Files\Folder { foreach ($files as $file) { if ($file) { - if (isset($permissions[$file['fileid']])) { - $file['permissions'] = $permissions[$file['fileid']]; - } $node = $this->createNode($this->path . '/' . $file['name'], $file); $result[] = $node; } diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 6b11603323a..4d5a2078ef7 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -301,13 +301,6 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->scanner; } - public function getPermissionsCache($path = '') { - if (!isset($this->permissioncache)) { - $this->permissioncache = new \OC\Files\Cache\Permissions($this); - } - return $this->permissioncache; - } - public function getWatcher($path = '') { if (!isset($this->watcher)) { $this->watcher = new \OC\Files\Cache\Watcher($this); diff --git a/lib/private/files/storage/loader.php b/lib/private/files/storage/loader.php index 966234cb04d..c75a0a976a7 100644 --- a/lib/private/files/storage/loader.php +++ b/lib/private/files/storage/loader.php @@ -21,8 +21,8 @@ class Loader { * * @param callable $callback */ - public function addStorageWrapper($callback) { - $this->storageWrappers[] = $callback; + public function addStorageWrapper($wrapperName, $callback) { + $this->storageWrappers[$wrapperName] = $callback; } /** diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php index 5be90f24756..f085a0590b4 100644 --- a/lib/private/files/storage/storage.php +++ b/lib/private/files/storage/storage.php @@ -41,14 +41,6 @@ interface Storage extends \OCP\Files\Storage { public function getOwner($path); /** - * get a permissions cache instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Permissions - */ - public function getPermissionsCache($path = ''); - - /** * get a watcher instance for the cache * * @param string $path diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php index 364475a68e0..057c31c3cd8 100644 --- a/lib/private/files/storage/wrapper/wrapper.php +++ b/lib/private/files/storage/wrapper/wrapper.php @@ -389,16 +389,6 @@ class Wrapper implements \OC\Files\Storage\Storage { } /** - * get a permissions cache instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Permissions - */ - public function getPermissionsCache($path = '') { - return $this->storage->getPermissionsCache($path); - } - - /** * get a watcher instance for the cache * * @param string $path diff --git a/lib/private/files/stream/quota.php b/lib/private/files/stream/quota.php index 60e60da8e67..bb4623b1a7b 100644 --- a/lib/private/files/stream/quota.php +++ b/lib/private/files/stream/quota.php @@ -123,7 +123,7 @@ class Quota { } public function stream_lock($mode) { - flock($this->source, $mode); + return flock($this->source, $mode); } public function stream_flush() { diff --git a/lib/private/files/utils/scanner.php b/lib/private/files/utils/scanner.php index a802a8fcb8b..1bb3e694c96 100644 --- a/lib/private/files/utils/scanner.php +++ b/lib/private/files/utils/scanner.php @@ -8,6 +8,8 @@ namespace OC\Files\Utils; +use OC\Files\View; +use OC\Files\Cache\ChangePropagator; use OC\Files\Filesystem; use OC\Hooks\PublicEmitter; @@ -27,10 +29,16 @@ class Scanner extends PublicEmitter { private $user; /** + * @var \OC\Files\Cache\ChangePropagator + */ + protected $propagator; + + /** * @param string $user */ public function __construct($user) { $this->user = $user; + $this->propagator = new ChangePropagator(new View('')); } /** @@ -67,6 +75,15 @@ class Scanner extends PublicEmitter { $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function ($path) use ($mount, $emitter) { $emitter->emit('\OC\Files\Utils\Scanner', 'scanFolder', array($mount->getMountPoint() . $path)); }); + + // propagate etag and mtimes when files are changed or removed + $propagator = $this->propagator; + $propagatorListener = function ($path) use ($mount, $propagator) { + $fullPath = Filesystem::normalizePath($mount->getMountPoint() . $path); + $propagator->addChange($fullPath); + }; + $scanner->listen('\OC\Files\Cache\Scanner', 'addToCache', $propagatorListener); + $scanner->listen('\OC\Files\Cache\Scanner', 'removeFromCache', $propagatorListener); } /** @@ -82,6 +99,7 @@ class Scanner extends PublicEmitter { $this->attachListener($mount); $scanner->backgroundScan(); } + $this->propagator->propagateChanges(time()); } /** @@ -95,8 +113,9 @@ class Scanner extends PublicEmitter { } $scanner = $mount->getStorage()->getScanner(); $this->attachListener($mount); - $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG); + $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); } + $this->propagator->propagateChanges(time()); } } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 0b8d336f260..09b100d7cfd 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -807,7 +807,8 @@ class View { * get the filesystem info * * @param string $path - * @param boolean $includeMountPoints whether to add mountpoint sizes, + * @param boolean|string $includeMountPoints true to add mountpoint sizes, + * 'ext' to add only ext storage mount point sizes. Defaults to true. * defaults to true * @return \OC\Files\FileInfo|false */ @@ -826,8 +827,6 @@ class View { $data = null; if ($storage) { $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); - $user = \OC_User::getUser(); if (!$cache->inCache($internalPath)) { if (!$storage->file_exists($internalPath)) { @@ -847,23 +846,21 @@ class View { if ($data and isset($data['fileid'])) { if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder + $extOnly = ($includeMountPoints === 'ext'); $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { + // exclude shared storage ? + if ($extOnly && $subStorage instanceof \OC\Files\Storage\Shared) { + continue; + } $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += isset($rootEntry['size']) ? $rootEntry['size'] : 0; } } } - - $permissions = $permissionsCache->get($data['fileid'], $user); - if ($permissions === -1) { - $permissions = $storage->getPermissions($internalPath); - $permissionsCache->set($data['fileid'], $user, $permissions); - } - $data['permissions'] = $permissions; } } if (!$data) { @@ -896,7 +893,6 @@ class View { list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); $user = \OC_User::getUser(); if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { @@ -913,7 +909,6 @@ class View { foreach ($contents as $content) { $files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content); } - $permissions = $permissionsCache->getDirectoryPermissions($folderId, $user); $ids = array(); foreach ($files as $i => $file) { @@ -922,7 +917,6 @@ class View { if (!isset($permissions[$file['fileid']])) { $permissions[$file['fileid']] = $storage->getPermissions($file['path']); - $permissionsCache->set($file['fileid'], $user, $permissions[$file['fileid']]); } $files[$i]['permissions'] = $permissions[$file['fileid']]; } @@ -954,12 +948,7 @@ class View { } else { //mountpoint in this folder, add an entry for it $rootEntry['name'] = $relativePath; $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $subPermissionsCache = $subStorage->getPermissionsCache(''); - $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); - if ($permissions === -1) { - $permissions = $subStorage->getPermissions($rootEntry['path']); - $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); - } + $permissions = $rootEntry['permissions']; // do not allow renaming/deleting the mount point if they are not shared files/folders // for shared files/folders we use the permissions given by the owner if ($subStorage instanceof \OC\Files\Storage\Shared) { |