diff options
author | Robin Appelman <icewind@owncloud.com> | 2015-05-04 15:05:09 +0200 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2015-06-01 13:22:56 +0200 |
commit | bf7002bc655967dd8dd1970db45e5affce47c3c3 (patch) | |
tree | d2338bf7307dc774374fc76e7a56f23f7da0e324 | |
parent | 536e187e5125aefec75037648181afc42df2a9d0 (diff) | |
download | nextcloud-server-bf7002bc655967dd8dd1970db45e5affce47c3c3.tar.gz nextcloud-server-bf7002bc655967dd8dd1970db45e5affce47c3c3.zip |
add locking to the view apo
-rw-r--r-- | lib/private/files/view.php | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 63af2b616cf..c82f8e1fafe 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -47,6 +47,7 @@ use OCP\Files\FileNameTooLongException; use OCP\Files\InvalidCharacterInPathException; use OCP\Files\InvalidPathException; use OCP\Files\ReservedWordException; +use OCP\Lock\ILockingProvider; /** * Class to provide access to ownCloud filesystem via a "view", and methods for @@ -72,6 +73,11 @@ class View { protected $updater; /** + * @var \OCP\Lock\ILockingProvider + */ + private $lockingProvider; + + /** * @param string $root * @throws \Exception If $root contains an invalid path */ @@ -79,12 +85,13 @@ class View { if (is_null($root)) { throw new \InvalidArgumentException('Root can\'t be null'); } - if(!Filesystem::isValidPath($root)) { + if (!Filesystem::isValidPath($root)) { throw new \Exception(); } $this->fakeRoot = $root; $this->updater = new Updater($this); + $this->lockingProvider = \OC::$server->getLockingProvider(); } public function getAbsolutePath($path = '/') { @@ -137,7 +144,7 @@ class View { return $path; } - if (rtrim($path,'/') === rtrim($this->fakeRoot, '/')) { + if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) { return '/'; } @@ -1553,4 +1560,66 @@ class View { throw new InvalidPathException($l10n->t('File name is too long')); } } + + /** + * get all parent folders of $path + * + * @param string $path + * @return string[] + */ + private 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; + } + + private function lockPath($path, $type) { + $mount = $this->getMount($path); + $mount->getStorage()->acquireLock($mount->getInternalPath($path), $type, $this->lockingProvider); + } + + private function unlockPath($path, $type) { + $mount = $this->getMount($path); + $mount->getStorage()->releaseLock($mount->getInternalPath($path), $type, $this->lockingProvider); + } + + /** + * Lock a path and all it's parents + * + * @param string $path + * @param int $type + */ + public function lockFile($path, $type) { + $this->lockPath($path, $type); + + $parents = $this->getParents($path); + foreach ($parents as $parent) { + $this->lockPath($parent, ILockingProvider::LOCK_SHARED); + } + } + + /** + * Unlock a path and all it's parents + * + * @param string $path + * @param int $type + */ + public function unlockFile($path, $type) { + $this->unlockPath($path, $type); + + $parents = $this->getParents($path); + foreach ($parents as $parent) { + $this->unlockPath($parent, ILockingProvider::LOCK_SHARED); + } + } } |