aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorblizzz <blizzz@arthur-schiwon.de>2022-10-01 21:47:26 +0200
committerGitHub <noreply@github.com>2022-10-01 21:47:26 +0200
commitca958de7e9738ba40f5170f9c3d4980374566fa2 (patch)
tree67d2f0ecf7c65268c0256d89c28c5c4189e93463
parent2b854c104433a8c38e2f8bd50d4af70526d06090 (diff)
parentcb51564356e111c79224401b9067d755ac5f5c42 (diff)
downloadnextcloud-server-ca958de7e9738ba40f5170f9c3d4980374566fa2.tar.gz
nextcloud-server-ca958de7e9738ba40f5170f9c3d4980374566fa2.zip
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
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FileTest.php4
-rw-r--r--lib/private/Files/Storage/Local.php9
-rw-r--r--lib/private/Files/View.php12
-rw-r--r--tests/lib/Files/ViewTest.php19
4 files changed, 40 insertions, 4 deletions
diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php
index 6a954378d02..91e49d331e9 100644
--- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php
@@ -1151,7 +1151,7 @@ class FileTest extends TestCase {
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
'permissions' => \OCP\Constants::PERMISSION_ALL,
- 'type' => FileInfo::TYPE_FOLDER,
+ 'type' => FileInfo::TYPE_FILE,
], null);
$file = new \OCA\DAV\Connector\Sabre\File($view, $info);
@@ -1172,7 +1172,7 @@ class FileTest extends TestCase {
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
'permissions' => \OCP\Constants::PERMISSION_ALL,
- 'type' => FileInfo::TYPE_FOLDER,
+ 'type' => FileInfo::TYPE_FILE,
], null);
$file = new \OCA\DAV\Connector\Sabre\File($view, $info);
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index 2a7e30cada6..62a04292e23 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -166,6 +166,9 @@ class Local extends \OC\Files\Storage\Common {
public function stat($path) {
$fullPath = $this->getSourcePath($path);
clearstatcache(true, $fullPath);
+ if (!file_exists($fullPath)) {
+ return false;
+ }
$statResult = @stat($fullPath);
if (PHP_INT_SIZE === 4 && $statResult && !$this->is_dir($path)) {
$filesize = $this->filesize($path);
@@ -388,11 +391,15 @@ class Local extends \OC\Files\Storage\Common {
}
public function fopen($path, $mode) {
+ $sourcePath = $this->getSourcePath($path);
+ if (!file_exists($sourcePath) && $mode === 'r') {
+ return false;
+ }
$oldMask = umask($this->defUMask);
if (($mode === 'w' || $mode === 'w+') && $this->unlinkOnTruncate) {
$this->unlink($path);
}
- $result = fopen($this->getSourcePath($path), $mode);
+ $result = @fopen($sourcePath, $mode);
umask($oldMask);
return $result;
}
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 294912e698b..986aecf556f 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -1003,7 +1003,17 @@ class View {
$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;
}
/**
diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php
index 86101d79a1e..2189e7c09f4 100644
--- a/tests/lib/Files/ViewTest.php
+++ b/tests/lib/Files/ViewTest.php
@@ -2709,4 +2709,23 @@ class ViewTest extends \Test\TestCase {
$this->assertEquals(25, $info->getUploadTime());
$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'));
+ }
}