diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b14bd121901e21192d2b810fcff304b69ce6a63
--- /dev/null
+++ b/lib/private/files/cache/homecache.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Cache;
+
+class HomeCache extends Cache {
+	/**
+	 * get the size of a folder and set it in the cache
+	 *
+	 * @param string $path
+	 * @return int
+	 */
+	public function calculateFolderSize($path) {
+		if ($path !== '/' and $path !== '') {
+			return parent::calculateFolderSize($path);
+		}
+
+		$totalSize = 0;
+		$entry = $this->get($path);
+		if ($entry && $entry['mimetype'] === 'httpd/unix-directory') {
+			$id = $entry['fileid'];
+			$sql = 'SELECT SUM(`size`) FROM `*PREFIX*filecache` ' .
+				'WHERE `parent` = ? AND `storage` = ? AND `size` >= 0';
+			$result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId()));
+			if ($row = $result->fetchRow()) {
+				list($sum) = array_values($row);
+				$totalSize = (int)$sum;
+				if ($entry['size'] !== $totalSize) {
+					$this->update($id, array('size' => $totalSize));
+				}
+			}
+		}
+		return $totalSize;
+	}
+}
diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php
index e40502bbe64c4d94bc1cb717fa94ab6640abba14..899666f3e1a864098528cbf1e5b129b6988bbaaf 100644
--- a/lib/private/files/filesystem.php
+++ b/lib/private/files/filesystem.php
@@ -307,10 +307,18 @@ class Filesystem {
 		$root = \OC_User::getHome($user);
 
 		$userObject = \OC_User::getManager()->get($user);
-		if (\OC\Files\Cache\Storage::exists('local::' . $root . '/') or is_null($userObject)) {
+
+		if (!is_null($userObject)) {
+			// check for legacy home id (<= 5.0.12)
+			if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) {
+				self::mount('\OC\Files\Storage\Home', array('user' => $userObject, 'legacy' => true), $user);
+			}
+			else {
+				self::mount('\OC\Files\Storage\Home', array('user' => $userObject), $user);
+			}
+		}
+		else {
 			self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user);
-		} else {
-			self::mount('\OC\Files\Storage\Home', array('user' => $userObject), $user);
 		}
 		$datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
 
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index a5b79f0e96763df55e01cf3f70aa45ec56f39f4f..3943d667c35715f368ef9646ae72286ede87c4ac 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -21,11 +21,11 @@ namespace OC\Files\Storage;
  */
 
 abstract class Common implements \OC\Files\Storage\Storage {
-	private $cache;
-	private $scanner;
-	private $permissioncache;
-	private $watcher;
-	private $storageCache;
+	protected $cache;
+	protected $scanner;
+	protected $permissioncache;
+	protected $watcher;
+	protected $storageCache;
 
 	public function __construct($parameters) {
 	}
diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php
index bf1d6017cbf9ed1ab2b2f5c9f5b54ad74335543a..b4ceb8f4f9bab60793fc47ac223a7da065cfe52d 100644
--- a/lib/private/files/storage/home.php
+++ b/lib/private/files/storage/home.php
@@ -12,6 +12,11 @@ namespace OC\Files\Storage;
  * Specialized version of Local storage for home directory usage
  */
 class Home extends Local {
+	/**
+	 * @var string
+	 */
+	protected $id;
+
 	/**
 	 * @var \OC\User\User $user
 	 */
@@ -20,11 +25,25 @@ class Home extends Local {
 	public function __construct($arguments) {
 		$this->user = $arguments['user'];
 		$datadir = $this->user->getHome();
+		if (isset($arguments['legacy']) && $arguments['legacy']) {
+			// legacy home id (<= 5.0.12)
+			$this->id = 'local::' . $datadir . '/';
+		}
+		else {
+		    $this->id = 'home::' . $this->user->getUID();
+		}
 
 		parent::__construct(array('datadir' => $datadir));
 	}
 
 	public function getId() {
-		return 'home::' . $this->user->getUID();
+		return $this->id;
+	}
+
+	public function getCache($path = '') {
+		if (!isset($this->cache)) {
+			$this->cache = new \OC\Files\Cache\HomeCache($this);
+		}
+		return $this->cache;
 	}
 }
diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php
index 247373a5cb9fd641b8e8e07a1f2f793650313bd7..052d70dd0b4404824e47185dc0e8fa09cf5595f6 100644
--- a/tests/lib/files/cache/cache.php
+++ b/tests/lib/files/cache/cache.php
@@ -18,11 +18,11 @@ class LongId extends \OC\Files\Storage\Temporary {
 
 class Cache extends \PHPUnit_Framework_TestCase {
 	/**
-	 * @var \OC\Files\Storage\Temporary $storage;
+	 * @var \OC\Files\Storage\Temporary $storage ;
 	 */
 	private $storage;
 	/**
-	 * @var \OC\Files\Storage\Temporary $storage2;
+	 * @var \OC\Files\Storage\Temporary $storage2 ;
 	 */
 	private $storage2;
 
@@ -137,6 +137,33 @@ class Cache extends \PHPUnit_Framework_TestCase {
 		$this->assertFalse($this->cache->inCache('folder/bar'));
 	}
 
+	public function testRootFolderSizeForNonHomeStorage() {
+		$dir1 = 'knownsize';
+		$dir2 = 'unknownsize';
+		$fileData = array();
+		$fileData[''] = array('size' => -1, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
+		$fileData[$dir1] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
+		$fileData[$dir2] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'httpd/unix-directory');
+
+		$this->cache->put('', $fileData['']);
+		$this->cache->put($dir1, $fileData[$dir1]);
+		$this->cache->put($dir2, $fileData[$dir2]);
+
+		$this->assertTrue($this->cache->inCache($dir1));
+		$this->assertTrue($this->cache->inCache($dir2));
+
+		// check that root size ignored the unknown sizes
+		$this->assertEquals(-1, $this->cache->calculateFolderSize(''));
+
+		// clean up
+		$this->cache->remove('');
+		$this->cache->remove($dir1);
+		$this->cache->remove($dir2);
+
+		$this->assertFalse($this->cache->inCache($dir1));
+		$this->assertFalse($this->cache->inCache($dir2));
+	}
+
 	function testStatus() {
 		$this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo'));
 		$this->cache->put('foo', array('size' => -1));
@@ -247,14 +274,14 @@ class Cache extends \PHPUnit_Framework_TestCase {
 		$data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
 		$this->cache->put('foo', $data);
 		$cachedData = $this->cache->get('foo');
-		$this->assertEquals($data['mtime'], $cachedData['storage_mtime']);//if no storage_mtime is saved, mtime should be used
+		$this->assertEquals($data['mtime'], $cachedData['storage_mtime']); //if no storage_mtime is saved, mtime should be used
 
-		$this->cache->put('foo', array('storage_mtime' => 30));//when setting storage_mtime, mtime is also set
+		$this->cache->put('foo', array('storage_mtime' => 30)); //when setting storage_mtime, mtime is also set
 		$cachedData = $this->cache->get('foo');
 		$this->assertEquals(30, $cachedData['storage_mtime']);
 		$this->assertEquals(30, $cachedData['mtime']);
 
-		$this->cache->put('foo', array('mtime' => 25));//setting mtime does not change storage_mtime
+		$this->cache->put('foo', array('mtime' => 25)); //setting mtime does not change storage_mtime
 		$cachedData = $this->cache->get('foo');
 		$this->assertEquals(30, $cachedData['storage_mtime']);
 		$this->assertEquals(25, $cachedData['mtime']);
@@ -295,18 +322,18 @@ class Cache extends \PHPUnit_Framework_TestCase {
 		$this->assertGreaterThan(0, $cacheMock->put('folder', $data));
 
 		// put un-normalized folder
-		$this->assertFalse($cacheMock->get('folder/' .$folderWith0308));
-		$this->assertGreaterThan(0, $cacheMock->put('folder/' .$folderWith0308, $data));
+		$this->assertFalse($cacheMock->get('folder/' . $folderWith0308));
+		$this->assertGreaterThan(0, $cacheMock->put('folder/' . $folderWith0308, $data));
 
 		// get un-normalized folder by name
-		$unNormalizedFolderName = $cacheMock->get('folder/' .$folderWith0308);
+		$unNormalizedFolderName = $cacheMock->get('folder/' . $folderWith0308);
 
 		// check if database layer normalized the folder name (this should not happen)
 		$this->assertEquals($folderWith0308, $unNormalizedFolderName['name']);
 
 		// put normalized folder
 		$this->assertFalse($cacheMock->get('folder/' . $folderWith00F6));
-		$this->assertGreaterThan(0, $cacheMock->put('folder/' .$folderWith00F6, $data));
+		$this->assertGreaterThan(0, $cacheMock->put('folder/' . $folderWith00F6, $data));
 
 		// this is our bug, we have two different hashes with the same name (Schön)
 		$this->assertEquals(2, count($cacheMock->getFolderContents('folder')));
@@ -317,7 +344,7 @@ class Cache extends \PHPUnit_Framework_TestCase {
 	 */
 	public function testWithNormalizer() {
 
-		if(!class_exists('Patchwork\PHP\Shim\Normalizer')) {
+		if (!class_exists('Patchwork\PHP\Shim\Normalizer')) {
 			$this->markTestSkipped('The 3rdparty Normalizer extension is not available.');
 			return;
 		}
@@ -335,18 +362,18 @@ class Cache extends \PHPUnit_Framework_TestCase {
 		$this->assertGreaterThan(0, $this->cache->put('folder', $data));
 
 		// put un-normalized folder
-		$this->assertFalse($this->cache->get('folder/' .$folderWith0308));
-		$this->assertGreaterThan(0, $this->cache->put('folder/' .$folderWith0308, $data));
+		$this->assertFalse($this->cache->get('folder/' . $folderWith0308));
+		$this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith0308, $data));
 
 		// get un-normalized folder by name
-		$unNormalizedFolderName = $this->cache->get('folder/' .$folderWith0308);
+		$unNormalizedFolderName = $this->cache->get('folder/' . $folderWith0308);
 
 		// check if folder name was normalized
 		$this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']);
 
 		// put normalized folder
 		$this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6)));
-		$this->assertGreaterThan(0, $this->cache->put('folder/' .$folderWith00F6, $data));
+		$this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith00F6, $data));
 
 		// at this point we should have only one folder named "Schön"
 		$this->assertEquals(1, count($this->cache->getFolderContents('folder')));
diff --git a/tests/lib/files/cache/homecache.php b/tests/lib/files/cache/homecache.php
new file mode 100644
index 0000000000000000000000000000000000000000..ebf2b7270dad6579843ec8988531cd286f6a0642
--- /dev/null
+++ b/tests/lib/files/cache/homecache.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Files\Cache;
+
+class DummyUser extends \OC\User\User {
+	/**
+	 * @var string $home
+	 */
+	private $home;
+
+	/**
+	 * @var string $uid
+	 */
+	private $uid;
+
+	public function __construct($uid, $home) {
+		$this->home = $home;
+		$this->uid = $uid;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getHome() {
+		return $this->home;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getUID() {
+		return $this->uid;
+	}
+}
+
+class HomeCache extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \OC\Files\Storage\Home $storage
+	 */
+	private $storage;
+
+	/**
+	 * @var \OC\Files\Cache\HomeCache $cache
+	 */
+	private $cache;
+
+	/**
+	 * @var \OC\User\User $user
+	 */
+	private $user;
+
+	public function setUp() {
+		$this->user = new DummyUser('foo', \OC_Helper::tmpFolder());
+		$this->storage = new \OC\Files\Storage\Home(array('user' => $this->user));
+		$this->cache = $this->storage->getCache();
+	}
+
+	/**
+	 * Tests that the root folder size calculation ignores the subdirs that have an unknown
+	 * size. This makes sure that quota calculation still works as it's based on the root
+	 * folder size.
+	 */
+	public function testRootFolderSizeIgnoresUnknownUpdate() {
+		$dir1 = 'knownsize';
+		$dir2 = 'unknownsize';
+		$fileData = array();
+		$fileData[''] = array('size' => -1, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
+		$fileData[$dir1] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
+		$fileData[$dir2] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'httpd/unix-directory');
+
+		$this->cache->put('', $fileData['']);
+		$this->cache->put($dir1, $fileData[$dir1]);
+		$this->cache->put($dir2, $fileData[$dir2]);
+
+		$this->assertTrue($this->cache->inCache($dir1));
+		$this->assertTrue($this->cache->inCache($dir2));
+
+		// check that root size ignored the unknown sizes
+		$this->assertEquals(1000, $this->cache->calculateFolderSize(''));
+
+		// clean up
+		$this->cache->remove('');
+		$this->cache->remove($dir1);
+		$this->cache->remove($dir2);
+
+		$this->assertFalse($this->cache->inCache($dir1));
+		$this->assertFalse($this->cache->inCache($dir2));
+	}
+}
diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php
index bef70cc725b167c4ced0495c31638d8571f1a88c..990e95ca5957aa8e9f4a39bffd8765c1931d7217 100644
--- a/tests/lib/files/filesystem.php
+++ b/tests/lib/files/filesystem.php
@@ -41,9 +41,12 @@ class Filesystem extends \PHPUnit_Framework_TestCase {
 		foreach ($this->tmpDirs as $dir) {
 			\OC_Helper::rmdirr($dir);
 		}
+		\OC\Files\Filesystem::clearMounts();
+		\OC_User::setUserId('');
 	}
 
 	public function setUp() {
+		\OC_User::setUserId('');
 		\OC\Files\Filesystem::clearMounts();
 	}
 
@@ -103,6 +106,67 @@ class Filesystem extends \PHPUnit_Framework_TestCase {
 //		\OC\Files\Filesystem::file_put_contents('/bar//foo', $fh);
 	}
 
+	/**
+	 * Tests that a local storage mount is used when passed user
+	 * does not exist.
+	 */
+	public function testLocalMountWhenUserDoesNotExist() {
+		$datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
+		$userId = uniqid('user_');
+
+		\OC\Files\Filesystem::initMountPoints($userId);
+
+		$homeMount = \OC\Files\Filesystem::getStorage('/' . $userId . '/');
+
+		$this->assertInstanceOf('\OC\Files\Storage\Local', $homeMount);
+		$this->assertEquals('local::' . $datadir . '/' . $userId . '/', $homeMount->getId());
+	}
+
+	/**
+	 * Tests that the home storage is used for the user's mount point
+	 */
+	public function testHomeMount() {
+		$userId = uniqid('user_');
+
+		\OC_User::createUser($userId, $userId);
+
+		\OC\Files\Filesystem::initMountPoints($userId);
+
+		$homeMount = \OC\Files\Filesystem::getStorage('/' . $userId . '/');
+
+		$this->assertInstanceOf('\OC\Files\Storage\Home', $homeMount);
+		$this->assertEquals('home::' . $userId, $homeMount->getId());
+
+		\OC_User::deleteUser($userId);
+	}
+
+	/**
+	 * Tests that the home storage is used in legacy mode
+	 * for the user's mount point
+	 */
+	public function testLegacyHomeMount() {
+		$datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data");
+		$userId = uniqid('user_');
+
+		// insert storage into DB by constructing it
+		// to make initMountsPoint find its existence
+		$localStorage = new \OC\Files\Storage\Local(array('datadir' => $datadir . '/' . $userId . '/'));
+		// this will trigger the insert
+		$cache = $localStorage->getCache();
+
+		\OC_User::createUser($userId, $userId);
+		\OC\Files\Filesystem::initMountPoints($userId);
+
+		$homeMount = \OC\Files\Filesystem::getStorage('/' . $userId . '/');
+
+		$this->assertInstanceOf('\OC\Files\Storage\Home', $homeMount);
+		$this->assertEquals('local::' . $datadir. '/' . $userId . '/', $homeMount->getId());
+
+		\OC_User::deleteUser($userId);
+		// delete storage entry
+		$cache->clear();
+	}
+
 	public function dummyHook($arguments) {
 		$path = $arguments['path'];
 		$this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized
diff --git a/tests/lib/files/storage/home.php b/tests/lib/files/storage/home.php
index b01e07f7457639bc71a522d0b12598da283b55f6..885291e440403d1f422ff3fcadb4b0b6a3cddd83 100644
--- a/tests/lib/files/storage/home.php
+++ b/tests/lib/files/storage/home.php
@@ -56,8 +56,8 @@ class Home extends Storage {
 
 	public function setUp() {
 		$this->tmpDir = \OC_Helper::tmpFolder();
-		$userId = uniqid('user_');
-		$this->user = new DummyUser($userId, $this->tmpDir);
+		$this->userId = uniqid('user_');
+		$this->user = new DummyUser($this->userId, $this->tmpDir);
 		$this->instance = new \OC\Files\Storage\Home(array('user' => $this->user));
 	}
 
@@ -65,7 +65,32 @@ class Home extends Storage {
 		\OC_Helper::rmdirr($this->tmpDir);
 	}
 
+	/**
+	 * Tests that the root path matches the data dir
+	 */
 	public function testRoot() {
 		$this->assertEquals($this->tmpDir, $this->instance->getLocalFolder(''));
 	}
+
+	/**
+	 * Tests that the home id is in the format home::user1
+	 */
+	public function testId() {
+		$this->assertEquals('home::' . $this->userId, $this->instance->getId());
+	}
+
+	/**
+	 * Tests that the legacy home id is in the format local::/path/to/datadir/user1/
+	 */
+	public function testLegacyId() {
+		$this->instance = new \OC\Files\Storage\Home(array('user' => $this->user, 'legacy' => true));
+		$this->assertEquals('local::' . $this->tmpDir . '/', $this->instance->getId());
+	}
+
+	/**
+	 * Tests that getCache() returns an instance of HomeCache
+	 */
+	public function testGetCacheReturnsHomeCache() {
+		$this->assertInstanceOf('\OC\Files\Cache\HomeCache', $this->instance->getCache());
+	}
 }