trigger a rescan when trying to fopen a file that exists in cache but not on disktags/v26.0.0beta1
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [ | $info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [ | ||||
'permissions' => \OCP\Constants::PERMISSION_ALL, | 'permissions' => \OCP\Constants::PERMISSION_ALL, | ||||
'type' => FileInfo::TYPE_FOLDER, | |||||
'type' => FileInfo::TYPE_FILE, | |||||
], null); | ], null); | ||||
$file = new \OCA\DAV\Connector\Sabre\File($view, $info); | $file = new \OCA\DAV\Connector\Sabre\File($view, $info); | ||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [ | $info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [ | ||||
'permissions' => \OCP\Constants::PERMISSION_ALL, | 'permissions' => \OCP\Constants::PERMISSION_ALL, | ||||
'type' => FileInfo::TYPE_FOLDER, | |||||
'type' => FileInfo::TYPE_FILE, | |||||
], null); | ], null); | ||||
$file = new \OCA\DAV\Connector\Sabre\File($view, $info); | $file = new \OCA\DAV\Connector\Sabre\File($view, $info); |
public function stat($path) { | public function stat($path) { | ||||
$fullPath = $this->getSourcePath($path); | $fullPath = $this->getSourcePath($path); | ||||
clearstatcache(true, $fullPath); | clearstatcache(true, $fullPath); | ||||
if (!file_exists($fullPath)) { | |||||
return false; | |||||
} | |||||
$statResult = @stat($fullPath); | $statResult = @stat($fullPath); | ||||
if (PHP_INT_SIZE === 4 && $statResult && !$this->is_dir($path)) { | if (PHP_INT_SIZE === 4 && $statResult && !$this->is_dir($path)) { | ||||
$filesize = $this->filesize($path); | $filesize = $this->filesize($path); | ||||
} | } | ||||
public function fopen($path, $mode) { | public function fopen($path, $mode) { | ||||
$sourcePath = $this->getSourcePath($path); | |||||
if (!file_exists($sourcePath) && $mode === 'r') { | |||||
return false; | |||||
} | |||||
$oldMask = umask($this->defUMask); | $oldMask = umask($this->defUMask); | ||||
if (($mode === 'w' || $mode === 'w+') && $this->unlinkOnTruncate) { | if (($mode === 'w' || $mode === 'w+') && $this->unlinkOnTruncate) { | ||||
$this->unlink($path); | $this->unlink($path); | ||||
} | } | ||||
$result = fopen($this->getSourcePath($path), $mode); | |||||
$result = @fopen($sourcePath, $mode); | |||||
umask($oldMask); | umask($oldMask); | ||||
return $result; | return $result; | ||||
} | } |
$this->logger->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends', ['app' => 'core']); | $this->logger->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends', ['app' => 'core']); | ||||
} | } | ||||
return $this->basicOperation('fopen', $path, $hooks, $mode); | |||||
$handle = $this->basicOperation('fopen', $path, $hooks, $mode); | |||||
if (!is_resource($handle) && $mode === 'r') { | |||||
// trying to read a file that isn't on disk, check if the cache is out of sync and rescan if needed | |||||
$mount = $this->getMount($path); | |||||
$internalPath = $mount->getInternalPath($this->getAbsolutePath($path)); | |||||
$storage = $mount->getStorage(); | |||||
if ($storage->getCache()->inCache($internalPath) && !$storage->file_exists($path)) { | |||||
$this->writeUpdate($storage, $internalPath); | |||||
} | |||||
} | |||||
return $handle; | |||||
} | } | ||||
/** | /** |
$this->assertEquals(25, $info->getUploadTime()); | $this->assertEquals(25, $info->getUploadTime()); | ||||
$this->assertEquals(0, $info->getCreationTime()); | $this->assertEquals(0, $info->getCreationTime()); | ||||
} | } | ||||
public function testFopenGone() { | |||||
$storage = new Temporary([]); | |||||
$scanner = $storage->getScanner(); | |||||
$storage->file_put_contents('foo.txt', 'bar'); | |||||
$scanner->scan(''); | |||||
$cache = $storage->getCache(); | |||||
Filesystem::mount($storage, [], '/test/'); | |||||
$view = new View('/test'); | |||||
$storage->unlink('foo.txt'); | |||||
$this->assertTrue($cache->inCache('foo.txt')); | |||||
$this->assertFalse($view->fopen('foo.txt', 'r')); | |||||
$this->assertFalse($cache->inCache('foo.txt')); | |||||
} | |||||
} | } |