summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/connector/sabre/file.php9
-rw-r--r--lib/private/files/cache/scanner.php11
-rw-r--r--lib/private/files/view.php20
3 files changed, 27 insertions, 13 deletions
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 5aef30cc577..740660f466b 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -216,15 +216,15 @@ class File extends Node implements IFile {
}
}
- // since we skipped the view we need to scan and emit the hooks ourselves
- $partStorage->getScanner()->scanFile($internalPath);
-
try {
$this->fileView->changeLock($this->path, ILockingProvider::LOCK_SHARED);
} catch (LockedException $e) {
throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
+ // since we skipped the view we need to scan and emit the hooks ourselves
+ $partStorage->getScanner()->scanFile($internalPath);
+
if ($view) {
$this->fileView->getUpdater()->propagate($hookPath);
if (!$exists) {
@@ -249,12 +249,11 @@ class File extends Node implements IFile {
}
}
$this->refreshInfo();
+ $this->fileView->unlockFile($this->path, ILockingProvider::LOCK_SHARED);
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage());
}
- $this->fileView->unlockFile($this->path, ILockingProvider::LOCK_SHARED);
-
return '"' . $this->info->getEtag() . '"';
}
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index d253afbfa1d..e8f7bd99902 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();
}
/**
@@ -123,6 +130,7 @@ class Scanner extends BasicEmitter {
if (!self::isPartialFile($file)
and !Filesystem::isFileBlacklisted($file)
) {
+ $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 +187,7 @@ class Scanner extends BasicEmitter {
} else {
$this->removeFromCache($file);
}
+ $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
return $data;
}
return null;
@@ -242,11 +251,13 @@ class Scanner extends BasicEmitter {
if ($reuse === -1) {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
+ $this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
$data = $this->scanFile($path, $reuse);
if ($data and $data['mimetype'] === 'httpd/unix-directory') {
$size = $this->scanChildren($path, $recursive, $reuse, $data);
$data['size'] = $size;
}
+ $this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
return $data;
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 39e2fe6bfce..0a597aee216 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -786,9 +786,12 @@ class View {
} else {
$result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
}
+
+ $this->changeLock($path2, ILockingProvider::LOCK_SHARED);
+
$this->updater->update($path2);
- $this->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
+ $this->unlockFile($path2, ILockingProvider::LOCK_SHARED);
$this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
if ($this->shouldEmitHooks() && $result !== false) {
@@ -1011,6 +1014,10 @@ class View {
throw $e;
}
+ if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) {
+ $this->changeLock($path, ILockingProvider::LOCK_SHARED);
+ }
+
if (in_array('delete', $hooks) and $result) {
$this->updater->remove($path);
}
@@ -1021,7 +1028,7 @@ class View {
$this->updater->update($path, $extraParam);
}
- if ($operation === 'fopen' and $result) {
+ if ($operation === 'fopen' and is_resource($result)) {
$result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) {
if (in_array('write', $hooks)) {
$this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
@@ -1029,12 +1036,8 @@ class View {
$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
}
});
- } else {
- if (in_array('write', $hooks) || in_array('delete', $hooks)) {
- $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
- } else if (in_array('read', $hooks)) {
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- }
+ } else if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
}
@@ -1717,6 +1720,7 @@ class View {
* @throws \OCP\Lock\LockedException if the path is already locked
*/
public function changeLock($path, $type) {
+ $path = Filesystem::normalizePath($path);
$absolutePath = $this->getAbsolutePath($path);
$absolutePath = Filesystem::normalizePath($absolutePath);
if (!$this->shouldLockFile($absolutePath)) {