summaryrefslogtreecommitdiffstats
path: root/lib/private/files
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/files')
-rw-r--r--lib/private/files/cache/backgroundwatcher.php107
-rw-r--r--lib/private/files/cache/cache.php17
-rw-r--r--lib/private/files/cache/changepropagator.php98
-rw-r--r--lib/private/files/cache/homecache.php2
-rw-r--r--lib/private/files/cache/permissions.php156
-rw-r--r--lib/private/files/cache/scanner.php106
-rw-r--r--lib/private/files/filesystem.php4
-rw-r--r--lib/private/files/node/folder.php5
-rw-r--r--lib/private/files/storage/common.php7
-rw-r--r--lib/private/files/storage/loader.php4
-rw-r--r--lib/private/files/storage/storage.php8
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php10
-rw-r--r--lib/private/files/stream/quota.php2
-rw-r--r--lib/private/files/utils/scanner.php21
-rw-r--r--lib/private/files/view.php27
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) {