Skip to content

Commit

Permalink
fix: Transfer ownership with S3 as primary
Browse files Browse the repository at this point in the history
When using S3 as primary storage, transferring ownership with the `--move` option fail with the following error:

`SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '8-45b963397aa40d4a0063e0d85e4fe7a1' for key 'fs_storage_path_hash'`

The `--move` option moves the entire home folder from one account to another.
The error means that the move failed because the destination folder already exist in `oc_filecache`.

- With S3 as primary storage, folders only exists as entries in `oc_filecache`.
- With S3 as primary storage, `moveFromStorage(...)` only moves the cache entry, as nothing needs to be moved on disk. This cache move does not delete potentially pre-existing destination folder.
- With Local storage, `moveFromStorage(...)` calls `rename(...)` which delete pre-existing folder.

- `transfer(...)`: https://github.com/nextcloud/server/blob/687a4d9ac7fcdbd935f81a0def567a1092306f7a/apps/files/lib/Service/OwnershipTransferService.php#L112
- `oneTimeUserSetup(...)`: https://github.com/nextcloud/server/blob/687a4d9ac7fcdbd935f81a0def567a1092306f7a/lib/private/Files/SetupManager.php#L261-L262
- `mkdir(...)`: https://github.com/nextcloud/server/blob/687a4d9ac7fcdbd935f81a0def567a1092306f7a/lib/private/Files/ObjectStore/ObjectStoreStorage.php#L91-L135
- `moveFromStorage(...)`: https://github.com/nextcloud/server/blob/687a4d9ac7fcdbd935f81a0def567a1092306f7a/lib/private/Files/ObjectStore/ObjectStoreStorage.php#L635-L636

Delete pre-existing folder in `moveFromStorage(...)`

Signed-off-by: Louis Chemineau <[email protected]>
  • Loading branch information
artonge committed Feb 25, 2025
1 parent 687a4d9 commit 50696c5
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/private/Files/ObjectStore/ObjectStoreStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,13 @@ public function copyFromStorage(

public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, ?ICacheEntry $sourceCacheEntry = null): bool {
$sourceCache = $sourceStorage->getCache();
if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class) && $sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
if (
$sourceStorage->instanceOfStorage(ObjectStoreStorage::class) &&
$sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()
) {
if ($this->getCache()->get($targetInternalPath)) {
$this->getCache()->remove($targetInternalPath);
}
$this->getCache()->moveFromCache($sourceCache, $sourceInternalPath, $targetInternalPath);
// Do not import any data when source and target bucket are identical.
return true;
Expand Down

0 comments on commit 50696c5

Please sign in to comment.