From 4b1759c9d1134468bc3a7fbbe056f95639be7986 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 25 Sep 2024 17:52:42 +0200 Subject: [PATCH] fix: preserve fileid when moving from objectstore to non-objectstore Signed-off-by: Robin Appelman --- apps/files_trashbin/tests/StorageTest.php | 6 +----- .../Files/ObjectStore/ObjectStoreStorage.php | 13 ++++++++++-- lib/private/Files/Storage/Common.php | 20 +++++++++++++++---- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/apps/files_trashbin/tests/StorageTest.php b/apps/files_trashbin/tests/StorageTest.php index d6e911e3dea6f..bcd4124b8be16 100644 --- a/apps/files_trashbin/tests/StorageTest.php +++ b/apps/files_trashbin/tests/StorageTest.php @@ -33,7 +33,6 @@ use OC\Files\Filesystem; use OC\Files\Storage\Common; -use OC\Files\Storage\Local; use OC\Files\Storage\Temporary; use OCA\Files_Trashbin\AppInfo\Application; use OCA\Files_Trashbin\Events\MoveToTrashEvent; @@ -697,10 +696,7 @@ public function testTrashbinCollision() { $this->assertEquals('bar', $this->rootView->file_get_contents($this->user . '/files_trashbin/files/test.txt.d1001')); } - public function testMoveFromStoragePreserveFileId() { - if (!$this->userView->getMount('')->getStorage()->instanceOfStorage(Local::class)) { - $this->markTestSkipped("Skipping on non-local users storage"); - } + public function testMoveFromStoragePreserveFileId(): void { $this->userView->file_put_contents('test.txt', 'foo'); $fileId = $this->userView->getFileInfo('test.txt')->getId(); diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 7277c5b1e2060..58dd8f6d2a4b1 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -69,6 +69,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil private $logger; private bool $handleCopiesAsOwned; + private bool $preserveCacheItemsOnDelete = false; /** @var bool */ protected $validateWrites = true; @@ -204,7 +205,9 @@ private function rmObjects(ICacheEntry $entry): bool { } } - $this->getCache()->remove($entry->getPath()); + if (!$this->preserveCacheItemsOnDelete) { + $this->getCache()->remove($entry->getPath()); + } return true; } @@ -236,7 +239,9 @@ public function rmObject(ICacheEntry $entry): bool { } //removing from cache is ok as it does not exist in the objectstore anyway } - $this->getCache()->remove($entry->getPath()); + if (!$this->preserveCacheItemsOnDelete) { + $this->getCache()->remove($entry->getPath()); + } return true; } @@ -770,4 +775,8 @@ public function cancelChunkedWrite(string $targetPath, string $writeToken): void $urn = $this->getURN($cacheEntry->getId()); $this->objectStore->abortMultipartUpload($urn, $writeToken); } + + public function setPreserveCacheOnDelete(bool $preserve) { + $this->preserveCacheItemsOnDelete = $preserve; + } } diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index 87a4a810c0e51..2e6fcd9509991 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -48,6 +48,7 @@ use OC\Files\Cache\Updater; use OC\Files\Cache\Watcher; use OC\Files\Filesystem; +use OC\Files\ObjectStore\ObjectStoreStorage; use OC\Files\Storage\Wrapper\Jail; use OC\Files\Storage\Wrapper\Wrapper; use OCP\Files\EmptyFileNameException; @@ -698,10 +699,21 @@ public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $t $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true); if ($result) { - if ($sourceStorage->is_dir($sourceInternalPath)) { - $result = $sourceStorage->rmdir($sourceInternalPath); - } else { - $result = $sourceStorage->unlink($sourceInternalPath); + if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) { + /** @var ObjectStoreStorage $sourceStorage */ + $sourceStorage->setPreserveCacheOnDelete(true); + } + try { + if ($sourceStorage->is_dir($sourceInternalPath)) { + $result = $sourceStorage->rmdir($sourceInternalPath); + } else { + $result = $sourceStorage->unlink($sourceInternalPath); + } + } finally { + if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) { + /** @var ObjectStoreStorage $sourceStorage */ + $sourceStorage->setPreserveCacheOnDelete(false); + } } } return $result;