Merge pull request #50761 from nextcloud/backport/50324/stable30

[stable30] fix: don't use cached root info from shared cache if the watcher has detected an update
This commit is contained in:
Andy Scherzinger 2025-02-13 16:43:50 +01:00 committed by GitHub
commit 094ea5c885
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 62 additions and 0 deletions

View file

@ -198,4 +198,8 @@ class Cache extends CacheJail {
return null;
}
}
public function markRootChanged(): void {
$this->rootUnchanged = false;
}
}

View file

@ -460,7 +460,12 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements LegacyISha
// for shares from the home storage we can rely on the home storage to keep itself up to date
// for other storages we need use the proper watcher
if (!(str_starts_with($storageId, 'home::') || str_starts_with($storageId, 'object::user'))) {
$cache = $this->getCache();
$this->watcher = parent::getWatcher($path, $storage);
if ($cache instanceof Cache && $this->watcher instanceof Watcher) {
$this->watcher->onUpdate([$cache, 'markRootChanged']);
}
return $this->watcher;
}
}

View file

@ -6,9 +6,12 @@
*/
namespace OCA\Files_Sharing\Tests;
use OC\Files\Filesystem;
use OC\Files\Storage\Temporary;
use OC\Files\Storage\Wrapper\Jail;
use OCA\Files_Sharing\SharedStorage;
use OCP\Constants;
use OCP\Files\Cache\IWatcher;
use OCP\Share\IShare;
/**
@ -564,4 +567,38 @@ class CacheTest extends TestCase {
$results = $sharedStorage->getCache()->search("foo.txt");
$this->assertCount(1, $results);
}
public function testWatcherRootChange() {
$sourceStorage = new Temporary();
$sourceStorage->mkdir('shared');
$sourceStorage->file_put_contents('shared/foo.txt', 'foo');
$sourceStorage->getScanner()->scan('');
$sourceStorage->getWatcher()->setPolicy(IWatcher::CHECK_ALWAYS);
$this->registerMount(self::TEST_FILES_SHARING_API_USER1, $sourceStorage, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
$rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
$node = $rootFolder->get('foo/shared');
$this->assertEquals(3, $node->getSize());
$share = $this->shareManager->newShare();
$share->setNode($node)
->setShareType(IShare::TYPE_USER)
->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
->setPermissions(Constants::PERMISSION_ALL);
$share = $this->shareManager->createShare($share);
$share->setStatus(IShare::STATUS_ACCEPTED);
$this->shareManager->updateShare($share);
\OC_Util::tearDownFS();
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
$view = Filesystem::getView();
$sourceStorage->rmdir('shared');
$this->assertFalse($view->getFileInfo('shared'));
}
}

View file

@ -33,6 +33,9 @@ class Watcher implements IWatcher {
*/
protected $scanner;
/** @var callable[] */
protected $onUpdate = [];
/**
* @param \OC\Files\Storage\Storage $storage
*/
@ -100,6 +103,9 @@ class Watcher implements IWatcher {
if ($this->cache instanceof Cache) {
$this->cache->correctFolderSize($path);
}
foreach ($this->onUpdate as $callback) {
$callback($path);
}
}
/**
@ -130,4 +136,11 @@ class Watcher implements IWatcher {
}
}
}
/**
* register a callback to be called whenever the watcher triggers and update
*/
public function onUpdate(callable $callback): void {
$this->onUpdate[] = $callback;
}
}

View file

@ -55,4 +55,7 @@ class JailWatcher extends Watcher {
$this->watcher->cleanFolder($this->getSourcePath($path));
}
public function onUpdate(callable $callback): void {
$this->watcher->onUpdate($callback);
}
}