Browse Source

Merge pull request #33566 from nextcloud/fopen-not-found-rescan

trigger a rescan when trying to fopen a file that exists in cache but not on disk
tags/v26.0.0beta1
blizzz 1 year ago
parent
commit
ca958de7e9
No account linked to committer's email address

+ 2
- 2
apps/dav/tests/unit/Connector/Sabre/FileTest.php View File



$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);

+ 8
- 1
lib/private/Files/Storage/Local.php View File

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;
} }

+ 11
- 1
lib/private/Files/View.php View File

$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;
} }


/** /**

+ 19
- 0
tests/lib/Files/ViewTest.php View File

$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'));
}
} }

Loading…
Cancel
Save