diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php
index abff820c1682807abb4e58da9da44cc89b4fbe74..896191dfe516f78c0785cf428e11639726eff220 100644
--- a/apps/files_sharing/tests/share.php
+++ b/apps/files_sharing/tests/share.php
@@ -322,6 +322,22 @@ class Test_Files_Sharing extends OCA\Files_sharing\Tests\TestCase {
 		);
 	}
 
+	public function testFileOwner() {
+
+		$fileinfo = $this->view->getFileInfo($this->filename);
+
+		$result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+				\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL);
+
+		$this->assertTrue($result);
+
+		$this->loginHelper(\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2);
+
+		$info = \OC\Files\Filesystem::getFileInfo($this->filename);
+
+		$this->assertSame(\Test_Files_Sharing::TEST_FILES_SHARING_API_USER1, $info->getOwner()->getUID());
+	}
+
 	/**
 	 * @dataProvider dataProviderGetUsersSharingFile
 	 *
diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php
index cf9524241dde47110a1de64ed1adec40b143b1ac..bb810dd45edde4d4aef67d3fe714a8ed5b4225a4 100644
--- a/lib/private/files/fileinfo.php
+++ b/lib/private/files/fileinfo.php
@@ -28,6 +28,8 @@
 
 namespace OC\Files;
 
+use OCP\IUser;
+
 class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	/**
 	 * @var array $data
@@ -54,19 +56,26 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	 */
 	private $mount;
 
+	/**
+	 * @var IUser
+	 */
+	private $owner;
+
 	/**
 	 * @param string|boolean $path
 	 * @param Storage\Storage $storage
 	 * @param string $internalPath
 	 * @param array $data
 	 * @param \OCP\Files\Mount\IMountPoint $mount
+	 * @param \OCP\IUser|null $owner
 	 */
-	public function __construct($path, $storage, $internalPath, $data, $mount) {
+	public function __construct($path, $storage, $internalPath, $data, $mount, $owner= null) {
 		$this->path = $path;
 		$this->storage = $storage;
 		$this->internalPath = $internalPath;
 		$this->data = $data;
 		$this->mount = $mount;
+		$this->owner = $owner;
 	}
 
 	public function offsetSet($offset, $value) {
@@ -267,4 +276,13 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	public function getMountPoint() {
 		return $this->mount;
 	}
+
+	/**
+	 * Get the owner of the file
+	 *
+	 * @return \OCP\IUser
+	 */
+	public function getOwner() {
+		return $this->owner;
+	}
 }
diff --git a/lib/private/files/node/node.php b/lib/private/files/node/node.php
index 943d12122e69ee6a86e19c0b4f39b3704055dbc8..1b52243fcb4cdcd74d402a6713ac8e39e8a8f2b8 100644
--- a/lib/private/files/node/node.php
+++ b/lib/private/files/node/node.php
@@ -347,4 +347,8 @@ class Node implements \OCP\Files\Node {
 	public function getMountPoint() {
 		return $this->getFileInfo()->getMountPoint();
 	}
+
+	public function getOwner() {
+		return $this->getFileInfo()->getOwner();
+	}
 }
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 887b18530d7304d12256b5d6d2844ec38c1cde29..7dd83588ec68a4471bdb1eba1bda752b973a1e32 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -1250,7 +1250,8 @@ class View {
 			$data['permissions'] |= \OCP\Constants::PERMISSION_DELETE;
 		}
 
-		return new FileInfo($path, $storage, $internalPath, $data, $mount);
+		$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
+		return new FileInfo($path, $storage, $internalPath, $data, $mount, $owner);
 	}
 
 	/**
@@ -1316,7 +1317,8 @@ class View {
 				if (\OCP\Util::isSharingDisabledForUser()) {
 					$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
 				}
-				$files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount);
+				$owner = \OC::$server->getUserManager()->get($storage->getOwner($content['path']));
+				$files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner);
 			}
 
 			//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
@@ -1385,7 +1387,8 @@ class View {
 								$rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
 							}
 
-							$files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount);
+							$owner = \OC::$server->getUserManager()->get($subStorage->getOwner(''));
+							$files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner);
 						}
 					}
 				}
@@ -1507,7 +1510,8 @@ class View {
 					$internalPath = $result['path'];
 					$path = $mountPoint . $result['path'];
 					$result['path'] = substr($mountPoint . $result['path'], $rootLength);
-					$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount);
+					$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
+					$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
 				}
 			}
 
@@ -1525,7 +1529,8 @@ class View {
 							$internalPath = $result['path'];
 							$result['path'] = rtrim($relativeMountPoint . $result['path'], '/');
 							$path = rtrim($mountPoint . $internalPath, '/');
-							$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount);
+							$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
+							$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
 						}
 					}
 				}
@@ -1666,6 +1671,7 @@ class View {
 		$mount = $this->getMount($path);
 		$storage = $mount->getStorage();
 		$internalPath = $mount->getInternalPath($this->getAbsolutePath($path));
+		$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
 		return new FileInfo(
 			$this->getAbsolutePath($path),
 			$storage,
@@ -1680,7 +1686,8 @@ class View {
 				'encrypted' => false,
 				'permissions' => \OCP\Constants::PERMISSION_ALL
 			],
-			$mount
+			$mount,
+			$owner
 		);
 	}
 
diff --git a/lib/public/files/fileinfo.php b/lib/public/files/fileinfo.php
index accbe04e044d96adfd69bcc97e72f94be401d94a..1af13302af062d0dd9503277096d266db66cd598 100644
--- a/lib/public/files/fileinfo.php
+++ b/lib/public/files/fileinfo.php
@@ -229,4 +229,12 @@ interface FileInfo {
 	 * @since 8.0.0
 	 */
 	public function getMountPoint();
+
+	/**
+	 * Get the owner of the file
+	 *
+	 * @return \OCP\IUser
+	 * @since 9.0.0
+	 */
+	public function getOwner();
 }
diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php
index a7979146b8557ffcfab02da3305ba1ee2a3de376..f0bad5abd18de96183e2395872d279e0f99ced40 100644
--- a/tests/lib/files/view.php
+++ b/tests/lib/files/view.php
@@ -11,6 +11,7 @@ use OC\Files\Cache\Watcher;
 use OC\Files\Storage\Common;
 use OC\Files\Mount\MountPoint;
 use OC\Files\Storage\Temporary;
+use OCP\Files\FileInfo;
 use OCP\Lock\ILockingProvider;
 
 class TemporaryNoTouch extends \OC\Files\Storage\Temporary {
@@ -1560,6 +1561,7 @@ class View extends \Test\TestCase {
 		$this->assertTrue($view->rename('mount1', 'renamed_mount'), 'Can rename mount point');
 		$this->assertTrue($view->rename('mount2', 'sub/moved_mount'), 'Can move a mount point into a subdirectory');
 	}
+
 	/**
 	 * Test that moving a mount point into another is forbidden
 	 */
@@ -1582,6 +1584,7 @@ class View extends \Test\TestCase {
 		$this->assertFalse($view->rename('mount1', 'mount2'), 'Cannot overwrite another mount point');
 		$this->assertFalse($view->rename('mount1', 'mount2/sub'), 'Cannot move a mount point into another');
 	}
+
 	/**
 	 * Test that moving a mount point into a shared folder is forbidden
 	 */
@@ -1765,7 +1768,7 @@ class View extends \Test\TestCase {
 		$storage->expects($this->once())
 			->method($operation)
 			->will($this->returnCallback(
-				function() use ($view, $lockedPath, &$lockTypeDuring){
+				function () use ($view, $lockedPath, &$lockTypeDuring) {
 					$lockTypeDuring = $this->getFileLockType($view, $lockedPath);
 
 					return true;
@@ -1808,7 +1811,7 @@ class View extends \Test\TestCase {
 		$storage->expects($this->once())
 			->method('fopen')
 			->will($this->returnCallback(
-				function() use ($view, $path, &$lockTypeDuring){
+				function () use ($view, $path, &$lockTypeDuring) {
 					$lockTypeDuring = $this->getFileLockType($view, $path);
 
 					return fopen('php://temp', 'r+');
@@ -1846,7 +1849,7 @@ class View extends \Test\TestCase {
 		$storage->expects($this->once())
 			->method('fopen')
 			->will($this->returnCallback(
-				function() use ($view, $path, &$lockTypeDuring){
+				function () use ($view, $path, &$lockTypeDuring) {
 					$lockTypeDuring = $this->getFileLockType($view, $path);
 
 					return fopen('php://temp', 'r+');
@@ -1903,7 +1906,7 @@ class View extends \Test\TestCase {
 		$storage->expects($this->once())
 			->method($operation)
 			->will($this->returnCallback(
-				function() {
+				function () {
 					throw new \Exception('Simulated exception');
 				}
 			));
@@ -1993,7 +1996,7 @@ class View extends \Test\TestCase {
 		$storage->expects($this->once())
 			->method($operation)
 			->will($this->returnCallback(
-				function() use ($view, $sourcePath, $targetPath, &$lockTypeSourceDuring, &$lockTypeTargetDuring){
+				function () use ($view, $sourcePath, $targetPath, &$lockTypeSourceDuring, &$lockTypeTargetDuring) {
 					$lockTypeSourceDuring = $this->getFileLockType($view, $sourcePath);
 					$lockTypeTargetDuring = $this->getFileLockType($view, $targetPath);
 
@@ -2044,7 +2047,7 @@ class View extends \Test\TestCase {
 		$storage->expects($this->once())
 			->method('copy')
 			->will($this->returnCallback(
-				function() {
+				function () {
 					throw new \Exception();
 				}
 			));
@@ -2097,6 +2100,37 @@ class View extends \Test\TestCase {
 		$view->unlockFile($targetPath, ILockingProvider::LOCK_EXCLUSIVE);
 	}
 
+	/**
+	 * Test rename operation: unlock first path when second path was locked
+	 */
+	public function testGetOwner() {
+		$this->loginAsUser('test');
+
+		$view = new \OC\Files\View('/test/files/');
+
+		$path = 'foo.txt';
+		$view->file_put_contents($path, 'meh');
+
+		$this->assertEquals('test', $view->getFileInfo($path)->getOwner()->getUID());
+
+		$folderInfo = $view->getDirectoryContent('');
+		$folderInfo = array_values(array_filter($folderInfo, function (FileInfo $info) {
+			return $info->getName() === 'foo.txt';
+		}));
+
+		$this->assertEquals('test', $folderInfo[0]->getOwner()->getUID());
+
+		$subStorage = new Temporary();
+		\OC\Files\Filesystem::mount($subStorage, [], '/test/files/asd');
+
+		$folderInfo = $view->getDirectoryContent('');
+		$folderInfo = array_values(array_filter($folderInfo, function (FileInfo $info) {
+			return $info->getName() === 'asd';
+		}));
+
+		$this->assertEquals('test', $folderInfo[0]->getOwner()->getUID());
+	}
+
 	public function lockFileRenameOrCopyCrossStorageDataProvider() {
 		return [
 			['rename', 'moveFromStorage', ILockingProvider::LOCK_EXCLUSIVE],
@@ -2141,7 +2175,7 @@ class View extends \Test\TestCase {
 		$storage2->expects($this->once())
 			->method($storageOperation)
 			->will($this->returnCallback(
-				function() use ($view, $sourcePath, $targetPath, &$lockTypeSourceDuring, &$lockTypeTargetDuring){
+				function () use ($view, $sourcePath, $targetPath, &$lockTypeSourceDuring, &$lockTypeTargetDuring) {
 					$lockTypeSourceDuring = $this->getFileLockType($view, $sourcePath);
 					$lockTypeTargetDuring = $this->getFileLockType($view, $targetPath);
 
@@ -2188,7 +2222,7 @@ class View extends \Test\TestCase {
 		$mount->expects($this->once())
 			->method('moveMount')
 			->will($this->returnCallback(
-				function($target) use ($mount, $view, $sourcePath, $targetPath, &$lockTypeSourceDuring, &$lockTypeTargetDuring, &$lockTypeSharedRootDuring){
+				function ($target) use ($mount, $view, $sourcePath, $targetPath, &$lockTypeSourceDuring, &$lockTypeTargetDuring, &$lockTypeSharedRootDuring) {
 					$lockTypeSourceDuring = $this->getFileLockType($view, $sourcePath, true);
 					$lockTypeTargetDuring = $this->getFileLockType($view, $targetPath, true);
 
@@ -2253,14 +2287,14 @@ class View extends \Test\TestCase {
 		$eventHandler->expects($this->any())
 			->method('preCallback')
 			->will($this->returnCallback(
-				function() use ($view, $path, $onMountPoint, &$lockTypePre){
+				function () use ($view, $path, $onMountPoint, &$lockTypePre) {
 					$lockTypePre = $this->getFileLockType($view, $path, $onMountPoint);
 				}
 			));
 		$eventHandler->expects($this->any())
 			->method('postCallback')
 			->will($this->returnCallback(
-				function() use ($view, $path, $onMountPoint, &$lockTypePost){
+				function () use ($view, $path, $onMountPoint, &$lockTypePost) {
 					$lockTypePost = $this->getFileLockType($view, $path, $onMountPoint);
 				}
 			));