Skip to content

Commit 199b0bd

Browse files
committed
fix(files): Correctly copy the cache information on copy operations
Needed to copy the `encrypted` flag of encrypted files when those files are two level down in a moved folder. Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent 5ee4c9e commit 199b0bd

File tree

5 files changed

+49
-11
lines changed

5 files changed

+49
-11
lines changed

lib/private/Files/Cache/Updater.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
use Doctrine\DBAL\Exception\DeadlockException;
1111
use OC\Files\FileInfo;
12+
use OC\Files\ObjectStore\ObjectStoreStorage;
13+
use OCP\Files\Cache\ICache;
1214
use OCP\Files\Cache\ICacheEntry;
1315
use OCP\Files\Cache\IUpdater;
1416
use OCP\Files\Storage\IStorage;
@@ -157,13 +159,40 @@ public function remove($path) {
157159
}
158160

159161
/**
160-
* Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
162+
* Rename a file or folder in the cache.
161163
*
162164
* @param IStorage $sourceStorage
163165
* @param string $source
164166
* @param string $target
165167
*/
166168
public function renameFromStorage(IStorage $sourceStorage, $source, $target) {
169+
$this->copyOrRenameFromStorage($sourceStorage, $source, $target, function (ICache $sourceCache) use ($sourceStorage, $source, $target) {
170+
// Remove existing cache entry to no reuse the fileId.
171+
if ($this->cache->inCache($target)) {
172+
$this->cache->remove($target);
173+
}
174+
175+
if ($sourceStorage === $this->storage) {
176+
$this->cache->move($source, $target);
177+
} else {
178+
$this->cache->moveFromCache($sourceCache, $source, $target);
179+
}
180+
});
181+
}
182+
183+
/**
184+
* Copy a file or folder in the cache.
185+
*/
186+
public function copyFromStorage(IStorage $sourceStorage, string $source, string $target): void {
187+
$this->copyOrRenameFromStorage($sourceStorage, $source, $target, function (ICache $sourceCache, ICacheEntry $sourceInfo) use ($target) {
188+
$this->cache->copyFromCache($sourceCache, $sourceInfo, $target);
189+
});
190+
}
191+
192+
/**
193+
* Utility to copy or rename a file or folder in the cache and update the size, etag and mtime of the parent folders
194+
*/
195+
private function copyOrRenameFromStorage(IStorage $sourceStorage, string $source, string $target, callable $operation): void {
167196
if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) {
168197
return;
169198
}
@@ -177,14 +206,8 @@ public function renameFromStorage(IStorage $sourceStorage, $source, $target) {
177206
$sourceInfo = $sourceCache->get($source);
178207

179208
if ($sourceInfo !== false) {
180-
if ($this->cache->inCache($target)) {
181-
$this->cache->remove($target);
182-
}
183-
184-
if ($sourceStorage === $this->storage) {
185-
$this->cache->move($source, $target);
186-
} else {
187-
$this->cache->moveFromCache($sourceCache, $source, $target);
209+
if (!$this->storage->instanceOfStorage(ObjectStoreStorage::class)) {
210+
$operation($sourceCache, $sourceInfo);
188211
}
189212

190213
$sourceExtension = pathinfo($source, PATHINFO_EXTENSION);

lib/private/Files/Storage/Wrapper/Encryption.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,6 @@ private function copyBetweenStorage(
628628
$info->getUnencryptedSize()
629629
);
630630
}
631-
$this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename, true);
632631
}
633632
return $result;
634633
}

lib/private/Files/View.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage,
273273
}
274274
}
275275

276+
protected function copyUpdate(Storage $sourceStorage, Storage $targetStorage, string $sourceInternalPath, string $targetInternalPath): void {
277+
if ($this->updaterEnabled) {
278+
$targetStorage->getUpdater()->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
279+
}
280+
}
281+
276282
/**
277283
* @param string $path
278284
* @return bool|mixed
@@ -898,7 +904,9 @@ public function copy($source, $target, $preserveMtime = false) {
898904
$result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
899905
}
900906

901-
$this->writeUpdate($storage2, $internalPath2);
907+
if ($result) {
908+
$this->copyUpdate($storage1, $storage2, $internalPath1, $internalPath2);
909+
}
902910

903911
$this->changeLock($target, ILockingProvider::LOCK_SHARED);
904912
$lockTypePath2 = ILockingProvider::LOCK_SHARED;

lib/public/Files/Cache/IUpdater.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,11 @@ public function remove($path);
5858
* @since 9.0.0
5959
*/
6060
public function renameFromStorage(IStorage $sourceStorage, $source, $target);
61+
62+
/**
63+
* Copy a file or folder in the cache and update the size, etag and mtime of the parent folders
64+
*
65+
* @since 31.0.0
66+
*/
67+
public function copyFromStorage(IStorage $sourceStorage, string $source, string $target): void;
6168
}

tests/lib/Files/ViewTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,6 +2386,7 @@ public function testLockFileRenameCrossStorage($viewOperation, $storageOperation
23862386
Filesystem::mount($storage2, [], $this->user . '/files/substorage');
23872387
$storage->mkdir('files');
23882388
$view->file_put_contents($sourcePath, 'meh');
2389+
$storage2->getUpdater()->update('');
23892390

23902391
$storage->expects($this->never())
23912392
->method($storageOperation);

0 commit comments

Comments
 (0)