diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index 3378f00c4dd35f91a6874237dda98236f697aa1d..23483b3ab21e6def7e428ebb797d826837b3c0cb 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -39,6 +39,7 @@ use OCP\Files\Cache\ICacheEntry;
 use OCP\Files\FileInfo;
 use OCP\Files\NotFoundException;
 use OCP\Files\ObjectStore\IObjectStore;
+use OCP\Files\Storage\IStorage;
 
 class ObjectStoreStorage extends \OC\Files\Storage\Common {
 	use CopyDirectory;
@@ -530,6 +531,19 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
 		return $this->objectStore;
 	}
 
+	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
+		if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
+			/** @var ObjectStoreStorage $sourceStorage */
+			if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
+				$sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
+				$this->copyInner($sourceEntry, $targetInternalPath);
+				return true;
+			}
+		}
+
+		return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
+	}
+
 	public function copy($path1, $path2) {
 		$path1 = $this->normalizePath($path1);
 		$path2 = $this->normalizePath($path2);
diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php
index 1ce0eef65ad0d8c3209d4527d59facf3099ea7b5..5ddf7adfcbee470c10b8d7a699a1303335971565 100644
--- a/lib/private/Files/Storage/Wrapper/Jail.php
+++ b/lib/private/Files/Storage/Wrapper/Jail.php
@@ -48,7 +48,7 @@ class Jail extends Wrapper {
 	protected $rootPath;
 
 	/**
-	 * @param array $arguments ['storage' => $storage, 'mask' => $root]
+	 * @param array $arguments ['storage' => $storage, 'root' => $root]
 	 *
 	 * $storage: The storage that will be wrapper
 	 * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php
index fa8ec535061cb352cc253425c94ddf4e492bf548..85a68be3daf27e4f6f8bcd1ddaeedfc332c9b384 100644
--- a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php
+++ b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php
@@ -22,6 +22,7 @@ namespace Test\Files\ObjectStore;
 
 use OC\Files\ObjectStore\StorageObjectStore;
 use OC\Files\Storage\Temporary;
+use OC\Files\Storage\Wrapper\Jail;
 use OCP\Files\ObjectStore\IObjectStore;
 use Test\Files\Storage\Storage;
 
@@ -204,4 +205,27 @@ class ObjectStoreStorageTest extends Storage {
 		$this->assertTrue($cache->inCache('foo'));
 		$this->assertTrue($cache->inCache('foo/test.txt'));
 	}
+
+	public function testCopyBetweenJails() {
+		$this->instance->mkdir('a');
+		$this->instance->mkdir('b');
+		$jailA = new Jail([
+			'storage' => $this->instance,
+			'root' => 'a'
+		]);
+		$jailB = new Jail([
+			'storage' => $this->instance,
+			'root' => 'b'
+		]);
+		$jailA->mkdir('sub');
+		$jailA->file_put_contents('1.txt', '1');
+		$jailA->file_put_contents('sub/2.txt', '2');
+		$jailA->file_put_contents('sub/3.txt', '3');
+
+		$jailB->copyFromStorage($jailA, '', 'target');
+
+		$this->assertEquals('1', $this->instance->file_get_contents('b/target/1.txt'));
+		$this->assertEquals('2', $this->instance->file_get_contents('b/target/sub/2.txt'));
+		$this->assertEquals('3', $this->instance->file_get_contents('b/target/sub/3.txt'));
+	}
 }