summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-06-12 18:50:49 +0200
committerVincent Petry <pvince81@owncloud.com>2015-06-12 18:52:18 +0200
commit4497aa4c68051ff75d1587dc1b01676926dfb466 (patch)
treee298734f2f3ed0abcc19e45db284f6c1e2ca427a /lib
parentbb0ea6336df84d391c0d972a56f27077f632948c (diff)
downloadnextcloud-server-4497aa4c68051ff75d1587dc1b01676926dfb466.tar.gz
nextcloud-server-4497aa4c68051ff75d1587dc1b01676926dfb466.zip
Webdav PUT small file lock must be shared during hooks
Fixed code path for Webdav PUT of small files to use shared locks during hook execution, and exclusive during the file operation This makes it possible for versions to be copied by accessing the file in a post_write hook.
Diffstat (limited to 'lib')
-rw-r--r--lib/private/connector/sabre/file.php16
-rw-r--r--lib/private/files/view.php4
2 files changed, 17 insertions, 3 deletions
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 3e1b29a4f28..5aef30cc577 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -114,7 +114,7 @@ class File extends Node implements IFile {
}
try {
- $this->fileView->lockFile($this->path, ILockingProvider::LOCK_EXCLUSIVE);
+ $this->fileView->lockFile($this->path, ILockingProvider::LOCK_SHARED);
} catch (LockedException $e) {
throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
@@ -192,6 +192,12 @@ class File extends Node implements IFile {
));
}
+ try {
+ $this->fileView->changeLock($this->path, ILockingProvider::LOCK_EXCLUSIVE);
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
+ }
+
if ($needsPartFile) {
// rename to correct path
try {
@@ -213,6 +219,12 @@ 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);
+ }
+
if ($view) {
$this->fileView->getUpdater()->propagate($hookPath);
if (!$exists) {
@@ -241,7 +253,7 @@ class File extends Node implements IFile {
throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage());
}
- $this->fileView->unlockFile($this->path, ILockingProvider::LOCK_EXCLUSIVE);
+ $this->fileView->unlockFile($this->path, ILockingProvider::LOCK_SHARED);
return '"' . $this->info->getEtag() . '"';
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index a206eab54e4..99db05f65c2 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -1683,12 +1683,14 @@ class View {
}
/**
+ * Change the lock type
+ *
* @param string $path the path of the file to lock, relative to the view
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
* @return bool False if the path is excluded from locking, true otherwise
* @throws \OCP\Lock\LockedException if the path is already locked
*/
- private function changeLock($path, $type) {
+ public function changeLock($path, $type) {
$absolutePath = $this->getAbsolutePath($path);
if (!$this->shouldLockFile($absolutePath)) {
return false;