From 6b0874203d3dc77bf4ff274add5a7d7844e791b8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Jun 2015 16:23:43 +0200 Subject: [PATCH 1/2] add proper locking to file_put_contents when using streams --- lib/private/files/view.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/private/files/view.php b/lib/private/files/view.php index b98842f5eb7..1b492213053 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -535,25 +535,37 @@ class View { ) { $path = $this->getRelativePath($absolutePath); + $this->lockFile($path, ILockingProvider::LOCK_SHARED); + $exists = $this->file_exists($path); $run = true; if ($this->shouldEmitHooks($path)) { $this->emit_file_hooks_pre($exists, $path, $run); } if (!$run) { + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); return false; } - $target = $this->fopen($path, 'w'); + + $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); + + /** @var \OC\Files\Storage\Storage $storage */ + list($storage, $internalPath) = $this->resolvePath($path); + $target = $storage->fopen($internalPath, 'w'); if ($target) { - list ($count, $result) = \OC_Helper::streamCopy($data, $target); + list (, $result) = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); $this->updater->update($path); + + $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); + if ($this->shouldEmitHooks($path) && $result !== false) { $this->emit_file_hooks_post($exists, $path); } return $result; } else { + $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); return false; } } else { From bcf13aff6f9082f87930068ecd9560612e36fc6a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Jun 2015 16:51:21 +0200 Subject: [PATCH 2/2] change lock back to shared before updating the cache --- lib/private/files/view.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 1b492213053..48fec01f171 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -556,9 +556,12 @@ class View { list (, $result) = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); + + $this->changeLock($path, ILockingProvider::LOCK_SHARED); + $this->updater->update($path); - $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); if ($this->shouldEmitHooks($path) && $result !== false) { $this->emit_file_hooks_post($exists, $path);