summaryrefslogtreecommitdiffstats
path: root/lib/private/files/cache/scanner.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/files/cache/scanner.php')
-rw-r--r--lib/private/files/cache/scanner.php38
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index d253afbfa1d..12aa05277a1 100644
--- a/lib/private/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -34,6 +34,7 @@ namespace OC\Files\Cache;
use OC\Files\Filesystem;
use OC\Hooks\BasicEmitter;
use OCP\Config;
+use OCP\Lock\ILockingProvider;
/**
* Class Scanner
@@ -72,6 +73,11 @@ class Scanner extends BasicEmitter {
*/
protected $useTransactions = true;
+ /**
+ * @var \OCP\Lock\ILockingProvider
+ */
+ protected $lockingProvider;
+
const SCAN_RECURSIVE = true;
const SCAN_SHALLOW = false;
@@ -83,6 +89,7 @@ class Scanner extends BasicEmitter {
$this->storageId = $this->storage->getId();
$this->cache = $storage->getCache();
$this->cacheActive = !Config::getSystemValue('filesystem_cache_readonly', false);
+ $this->lockingProvider = \OC::$server->getLockingProvider();
}
/**
@@ -117,12 +124,18 @@ class Scanner extends BasicEmitter {
* @param int $reuseExisting
* @param int $parentId
* @param array | null $cacheData existing data in the cache for the file to be scanned
+ * @param bool $lock set to false to disable getting an additional read lock during scanning
* @return array an array of metadata of the scanned file
+ * @throws \OC\ServerNotAvailableException
+ * @throws \OCP\Lock\LockedException
*/
- public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null) {
+ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) {
if (!self::isPartialFile($file)
and !Filesystem::isFileBlacklisted($file)
) {
+ if ($lock) {
+ $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
$this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId));
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
$data = $this->getData($file);
@@ -179,6 +192,9 @@ class Scanner extends BasicEmitter {
} else {
$this->removeFromCache($file);
}
+ if ($lock) {
+ $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
return $data;
}
return null;
@@ -236,17 +252,24 @@ class Scanner extends BasicEmitter {
* @param string $path
* @param bool $recursive
* @param int $reuse
+ * @param bool $lock set to false to disable getting an additional read lock during scanning
* @return array an array of the meta data of the scanned file or folder
*/
- public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) {
+ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true) {
if ($reuse === -1) {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
- $data = $this->scanFile($path, $reuse);
+ if ($lock) {
+ $this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
+ $data = $this->scanFile($path, $reuse, -1, null, $lock);
if ($data and $data['mimetype'] === 'httpd/unix-directory') {
- $size = $this->scanChildren($path, $recursive, $reuse, $data);
+ $size = $this->scanChildren($path, $recursive, $reuse, $data, $lock);
$data['size'] = $size;
}
+ if ($lock) {
+ $this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
return $data;
}
@@ -292,9 +315,10 @@ class Scanner extends BasicEmitter {
* @param bool $recursive
* @param int $reuse
* @param array $folderData existing cache data for the folder to be scanned
+ * @param bool $lock set to false to disable getting an additional read lock during scanning
* @return int the size of the scanned folder or -1 if the size is unknown at this stage
*/
- protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null) {
+ protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null, $lock = true) {
if ($reuse === -1) {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
@@ -317,7 +341,7 @@ class Scanner extends BasicEmitter {
$child = ($path) ? $path . '/' . $file : $file;
try {
$existingData = isset($existingChildren[$file]) ? $existingChildren[$file] : null;
- $data = $this->scanFile($child, $reuse, $folderId, $existingData);
+ $data = $this->scanFile($child, $reuse, $folderId, $existingData, $lock);
if ($data) {
if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) {
$childQueue[$child] = $data;
@@ -352,7 +376,7 @@ class Scanner extends BasicEmitter {
}
foreach ($childQueue as $child => $childData) {
- $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childData);
+ $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childData, $lock);
if ($childSize === -1) {
$size = -1;
} else if ($size !== -1) {