keep a read lock while scanning a file or folder
This commit is contained in:
parent
5eb0dace8c
commit
7d72f7d8ce
|
@ -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() . '"';
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue