diff options
author | Robin Appelman <icewind@owncloud.com> | 2015-06-03 16:44:57 +0200 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2015-06-15 14:32:29 +0200 |
commit | 7d72f7d8ce3c15e25382c6121c374de92fe84775 (patch) | |
tree | 9f3fc7f5a73b63183eb62643ec8b7f2cb424b8e3 | |
parent | 5eb0dace8c680425165e36c0b6d64d0245841c3a (diff) | |
download | nextcloud-server-7d72f7d8ce3c15e25382c6121c374de92fe84775.tar.gz nextcloud-server-7d72f7d8ce3c15e25382c6121c374de92fe84775.zip |
keep a read lock while scanning a file or folder
-rw-r--r-- | lib/private/connector/sabre/file.php | 9 | ||||
-rw-r--r-- | lib/private/files/cache/scanner.php | 11 | ||||
-rw-r--r-- | lib/private/files/view.php | 17 |
3 files changed, 25 insertions, 12 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 99db05f65c2..f410fdc8c00 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -771,9 +771,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) { @@ -996,6 +999,10 @@ class View { throw $e; } + if ((in_array('write', $hooks) || in_array('delete', $hooks)) && $operation !== 'fopen') { + $this->changeLock($path, ILockingProvider::LOCK_SHARED); + } + if (in_array('delete', $hooks) and $result) { $this->updater->remove($path); } @@ -1014,12 +1021,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); } |