diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 03e448be0affc81d48905fbae4340588433a2c19..5f56340d25445efc37a0bbb219a47ceb1c2e04ab 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -42,7 +42,6 @@ $l = \OC::$server->getL10N('files_sharing');
 
 $application = new Application();
 $application->registerMountProviders();
-$application->setupPropagation();
 
 \OCP\App::registerAdmin('files_sharing', 'settings-admin');
 \OCP\App::registerPersonal('files_sharing', 'settings-personal');
diff --git a/apps/files_sharing/appinfo/application.php b/apps/files_sharing/appinfo/application.php
index 545a9425083dac940c69b30354166f29fe928a5b..ffe3a6a513f45453a4962fec29e8d721905ec66c 100644
--- a/apps/files_sharing/appinfo/application.php
+++ b/apps/files_sharing/appinfo/application.php
@@ -27,8 +27,6 @@ namespace OCA\Files_Sharing\AppInfo;
 
 use OCA\Files_Sharing\Helper;
 use OCA\Files_Sharing\MountProvider;
-use OCA\Files_Sharing\Propagation\PropagationManager;
-use OCA\Files_Sharing\Propagation\GroupPropagationManager;
 use OCP\AppFramework\App;
 use OC\AppFramework\Utility\SimpleContainer;
 use OCA\Files_Sharing\Controllers\ExternalSharesController;
@@ -116,8 +114,7 @@ class Application extends App {
 			/** @var \OCP\IServerContainer $server */
 			$server = $c->query('ServerContainer');
 			return new MountProvider(
-				$server->getConfig(),
-				$c->query('PropagationManager')
+				$server->getConfig()
 			);
 		});
 
@@ -132,25 +129,6 @@ class Application extends App {
 			);
 		});
 
-		$container->registerService('PropagationManager', function (IContainer $c) {
-			/** @var \OCP\IServerContainer $server */
-			$server = $c->query('ServerContainer');
-			return new PropagationManager(
-				$server->getUserSession(),
-				$server->getConfig()
-			);
-		});
-
-		$container->registerService('GroupPropagationManager', function (IContainer $c) {
-			/** @var \OCP\IServerContainer $server */
-			$server = $c->query('ServerContainer');
-			return new GroupPropagationManager(
-				$server->getUserSession(),
-				$server->getGroupManager(),
-				$c->query('PropagationManager')
-			);
-		});
-
 		/*
 		 * Register capabilities
 		 */
@@ -164,11 +142,4 @@ class Application extends App {
 		$mountProviderCollection->registerProvider($this->getContainer()->query('MountProvider'));
 		$mountProviderCollection->registerProvider($this->getContainer()->query('ExternalMountProvider'));
 	}
-
-	public function setupPropagation() {
-		$propagationManager = $this->getContainer()->query('PropagationManager');
-		\OCP\Util::connectHook('OC_Filesystem', 'setup', $propagationManager, 'globalSetup');
-
-		$this->getContainer()->query('GroupPropagationManager')->globalSetup();
-	}
 }
diff --git a/apps/files_sharing/lib/mountprovider.php b/apps/files_sharing/lib/mountprovider.php
index 458e7f2619bdfb5ed65b5c068f407886ad850ccd..74a2a3ff4d604166f521acc5d4c80a90052d4765 100644
--- a/apps/files_sharing/lib/mountprovider.php
+++ b/apps/files_sharing/lib/mountprovider.php
@@ -24,7 +24,6 @@ namespace OCA\Files_Sharing;
 
 use OC\Files\Filesystem;
 use OC\User\NoUserException;
-use OCA\Files_Sharing\Propagation\PropagationManager;
 use OCP\Files\Config\IMountProvider;
 use OCP\Files\Storage\IStorageFactory;
 use OCP\IConfig;
@@ -36,18 +35,11 @@ class MountProvider implements IMountProvider {
 	 */
 	protected $config;
 
-	/**
-	 * @var \OCA\Files_Sharing\Propagation\PropagationManager
-	 */
-	protected $propagationManager;
-
 	/**
 	 * @param \OCP\IConfig $config
-	 * @param \OCA\Files_Sharing\Propagation\PropagationManager $propagationManager
 	 */
-	public function __construct(IConfig $config, PropagationManager $propagationManager) {
+	public function __construct(IConfig $config) {
 		$this->config = $config;
-		$this->propagationManager = $propagationManager;
 	}
 
 
@@ -60,21 +52,15 @@ class MountProvider implements IMountProvider {
 	 */
 	public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) {
 		$shares = \OCP\Share::getItemsSharedWithUser('file', $user->getUID());
-		$propagator = $this->propagationManager->getSharePropagator($user->getUID());
-		$propagator->propagateDirtyMountPoints($shares);
 		$shares = array_filter($shares, function ($share) {
 			return $share['permissions'] > 0;
 		});
 		$shares = array_map(function ($share) use ($user, $storageFactory) {
-			// for updating etags for the share owner when we make changes to this share.
-			$ownerPropagator = $this->propagationManager->getChangePropagator($share['uid_owner']);
 
 			return new SharedMount(
 				'\OC\Files\Storage\Shared',
 				'/' . $user->getUID() . '/' . $share['file_target'],
 				array(
-					'propagationManager' => $this->propagationManager,
-					'propagator' => $ownerPropagator,
 					'share' => $share,
 					'user' => $user->getUID()
 				),
diff --git a/apps/files_sharing/lib/propagation/changewatcher.php b/apps/files_sharing/lib/propagation/changewatcher.php
deleted file mode 100644
index e61c161da19a2466f664082adc3b859bd25b69c9..0000000000000000000000000000000000000000
--- a/apps/files_sharing/lib/propagation/changewatcher.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Propagation;
-
-use OC\Files\Cache\ChangePropagator;
-use OC\Files\Filesystem;
-use OC\Files\View;
-use OCA\Files_Sharing\SharedMount;
-
-/**
- * Watch for changes made in a shared mount and propagate the changes to the share owner
- */
-class ChangeWatcher {
-	/**
-	 * The user view for the logged in user
-	 *
-	 * @var \OC\Files\View
-	 */
-	private $baseView;
-
-	/**
-	 * @var RecipientPropagator
-	 */
-	private $recipientPropagator;
-
-	/**
-	 * @param \OC\Files\View $baseView the view for the logged in user
-	 * @param RecipientPropagator $recipientPropagator
-	 */
-	public function __construct(View $baseView, RecipientPropagator $recipientPropagator) {
-		$this->baseView = $baseView;
-		$this->recipientPropagator = $recipientPropagator;
-	}
-
-
-	public function writeHook($params) {
-		$path = $params['path'];
-		$fullPath = $this->baseView->getAbsolutePath($path);
-		$mount = $this->baseView->getMount($path);
-		if ($mount instanceof SharedMount) {
-			$this->propagateForOwner($mount->getShare(), $mount->getInternalPath($fullPath), $mount->getOwnerPropagator());
-		}
-		$info = $this->baseView->getFileInfo($path);
-		if ($info) {
-			// trigger propagation if the subject of the write hook is shared.
-			// if a parent folder of $path is shared the propagation will be triggered from the change propagator hooks
-			$this->recipientPropagator->propagateById($info->getId());
-		}
-	}
-
-	public function renameHook($params) {
-		$path1 = $params['oldpath'];
-		$path2 = $params['newpath'];
-		$fullPath1 = $this->baseView->getAbsolutePath($path1);
-		$fullPath2 = $this->baseView->getAbsolutePath($path2);
-		$mount1 = $this->baseView->getMount($path1);
-		$mount2 = $this->baseView->getMount($path2);
-		if ($mount1 instanceof SharedMount and $mount1->getInternalPath($fullPath1) !== '') {
-			$this->propagateForOwner($mount1->getShare(), $mount1->getInternalPath($fullPath1), $mount1->getOwnerPropagator());
-		}
-		if ($mount1 !== $mount2 and $mount2 instanceof SharedMount and $mount2->getInternalPath($fullPath2) !== '') {
-			$this->propagateForOwner($mount2->getShare(), $mount2->getInternalPath($fullPath2), $mount2->getOwnerPropagator());
-		}
-	}
-
-	/**
-	 * @param array $share
-	 * @param string $internalPath
-	 * @param \OC\Files\Cache\ChangePropagator $propagator
-	 */
-	private function propagateForOwner($share, $internalPath, ChangePropagator $propagator) {
-		// note that we have already set up the filesystem for the owner when mounting the share
-		$view = new View('/' . $share['uid_owner'] . '/files');
-
-		$shareRootPath = $view->getPath($share['item_source']);
-		if (!is_null($shareRootPath)) {
-			$path = $shareRootPath . '/' . $internalPath;
-			$path = Filesystem::normalizePath($path);
-			$propagator->addChange($path);
-			$propagator->propagateChanges();
-		}
-	}
-
-	public function permissionsHook($params) {
-		$share = $params['share'];
-
-		if ($share['item_type'] === 'file' || $share['item_type'] === 'folder') {
-			$this->recipientPropagator->markDirty($share, microtime(true));
-		}
-	}
-}
diff --git a/apps/files_sharing/lib/propagation/grouppropagationmanager.php b/apps/files_sharing/lib/propagation/grouppropagationmanager.php
deleted file mode 100644
index ba550dccec39a6909605e5031873265affc4c83b..0000000000000000000000000000000000000000
--- a/apps/files_sharing/lib/propagation/grouppropagationmanager.php
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-/**
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Propagation;
-
-use OC\Files\Filesystem;
-use OC\Files\View;
-use OCP\IConfig;
-use OCP\IUserSession;
-use OCP\IGroup;
-use OCP\IUser;
-use OCP\IGroupManager;
-use OCA\Files_Sharing\Propagation\PropagationManager;
-
-/**
- * Propagate changes on group changes
- */
-class GroupPropagationManager {
-	/**
-	 * @var \OCP\IUserSession
-	 */
-	private $userSession;
-
-	/**
-	 * @var \OCP\IGroupManager
-	 */
-	private $groupManager;
-
-	/**
-	 * @var PropagationManager
-	 */
-	private $propagationManager;
-
-	/**
-	 * Items shared with a given user.
-	 * Key is user id and value is an array of shares.
-	 *
-	 * @var array
-	 */
-	private $userShares = [];
-
-	public function __construct(IUserSession $userSession, IGroupManager $groupManager, PropagationManager $propagationManager) {
-		$this->userSession = $userSession;
-		$this->groupManager = $groupManager;
-		$this->propagationManager = $propagationManager;
-	}
-
-	public function onPreProcessUser(IGroup $group, IUser $targetUser) {
-		$this->userShares[$targetUser->getUID()] = $this->getUserShares($targetUser->getUID());
-	}
-
-	public function onPostAddUser(IGroup $group, IUser $targetUser) {
-		$targetUserId = $targetUser->getUID();
-		$sharesAfter = $this->getUserShares($targetUserId);
-
-		$this->propagateSharesDiff($targetUserId, $sharesAfter, $this->userShares[$targetUserId]);
-		unset($this->userShares[$targetUserId]);
-	}
-
-	public function onPostRemoveUser(IGroup $group, IUser $targetUser) {
-		$targetUserId = $targetUser->getUID();
-		$sharesAfter = $this->getUserShares($targetUserId);
-
-		$this->propagateSharesDiff($targetUserId, $this->userShares[$targetUserId], $sharesAfter);
-		unset($this->userShares[$targetUserId]);
-	}
-
-	private function getUserShares($targetUserId) {
-		return \OCP\Share::getItemsSharedWithUser('file', $targetUserId);
-	}
-
-	/**
-	 * Propagate etag for the shares that are in $shares1 but not in $shares2.
-	 *
-	 * @param string $targetUserId user id for which to propagate shares
-	 * @param array $shares1
-	 * @param array $shares2
-	 */
-	private function propagateSharesDiff($targetUserId, $shares1, $shares2) {
-		$sharesToPropagate = array_udiff(
-			$shares1,
-			$shares2,
-			function($share1, $share2) {
-				return ($share2['id'] - $share1['id']);
-			}
-		);
-
-		\OC\Files\Filesystem::initMountPoints($targetUserId);
-		$this->propagationManager->propagateSharesToUser($sharesToPropagate, $targetUserId);
-	}
-
-	/**
-	 * To be called from setupFS trough a hook
-	 *
-	 * Sets up listening to changes made to shares owned by the current user
-	 */
-	public function globalSetup() {
-		$user = $this->userSession->getUser();
-		if (!$user) {
-			return;
-		}
-
-		$this->groupManager->listen('\OC\Group', 'preAddUser', [$this, 'onPreProcessUser']);
-		$this->groupManager->listen('\OC\Group', 'postAddUser', [$this, 'onPostAddUser']);
-		$this->groupManager->listen('\OC\Group', 'preRemoveUser', [$this, 'onPreProcessUser']);
-		$this->groupManager->listen('\OC\Group', 'postRemoveUser', [$this, 'onPostRemoveUser']);
-	}
-
-	public function tearDown() {
-		$this->groupManager->removeListener('\OC\Group', 'preAddUser', [$this, 'onPreProcessUser']);
-		$this->groupManager->removeListener('\OC\Group', 'postAddUser', [$this, 'onPostAddUser']);
-		$this->groupManager->removeListener('\OC\Group', 'preRemoveUser', [$this, 'onPreProcessUser']);
-		$this->groupManager->removeListener('\OC\Group', 'postRemoveUser', [$this, 'onPostRemoveUser']);
-	}
-}
diff --git a/apps/files_sharing/lib/propagation/propagationmanager.php b/apps/files_sharing/lib/propagation/propagationmanager.php
deleted file mode 100644
index aac9428240dba82818b5b1fbf72c18bdda70a083..0000000000000000000000000000000000000000
--- a/apps/files_sharing/lib/propagation/propagationmanager.php
+++ /dev/null
@@ -1,144 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Propagation;
-
-use OC\Files\Filesystem;
-use OC\Files\View;
-use OCP\IConfig;
-use OCP\IUserSession;
-use OCP\Util;
-
-
-/**
- * Keep track of all change and share propagators by owner
- */
-class PropagationManager {
-	/**
-	 * @var \OCP\IUserSession
-	 */
-	private $userSession;
-
-	/**
-	 * @var \OCP\IConfig
-	 */
-	private $config;
-
-	/**
-	 * Change propagators for share owner
-	 *
-	 * @var \OC\Files\Cache\ChangePropagator[]
-	 */
-	private $changePropagators = [];
-
-	/**
-	 * Recipient propagators
-	 *
-	 * @var \OCA\Files_Sharing\Propagation\RecipientPropagator[]
-	 */
-	private $sharePropagators = [];
-
-	public function __construct(IUserSession $userSession, IConfig $config) {
-		$this->userSession = $userSession;
-		$this->config = $config;
-	}
-
-	/**
-	 * @param string $user
-	 * @return \OC\Files\Cache\ChangePropagator
-	 */
-	public function getChangePropagator($user) {
-		$activeUser = $this->userSession->getUser();
-
-		// for the local user we want to propagator from the active view, not any cached one
-		if ($activeUser && $activeUser->getUID() === $user && Filesystem::getView() instanceof View) {
-			// it's important that we take the existing propagator here to make sure we can listen to external changes
-			$this->changePropagators[$user] = Filesystem::getView()->getUpdater()->getPropagator();
-		}
-		if (isset($this->changePropagators[$user])) {
-			return $this->changePropagators[$user];
-		}
-		$view = new View('/' . $user . '/files');
-		$this->changePropagators[$user] = $view->getUpdater()->getPropagator();
-		return $this->changePropagators[$user];
-	}
-
-	/**
-	 * Propagates etag changes for the given shares to the given user
-	 *
-	 * @param array array of shares for which to trigger etag change
-	 * @param string $user
-	 */
-	public function propagateSharesToUser($shares, $user) {
-		$changePropagator = $this->getChangePropagator($user);
-		foreach ($shares as $share) {
-			$changePropagator->addChange($share['file_target']);
-		}
-		$time = microtime(true);
-		$changePropagator->propagateChanges(floor($time));
-	}
-
-	/**
-	 * @param string $user
-	 * @return \OCA\Files_Sharing\Propagation\RecipientPropagator
-	 */
-	public function getSharePropagator($user) {
-		if (isset($this->sharePropagators[$user])) {
-			return $this->sharePropagators[$user];
-		}
-		$this->sharePropagators[$user] = new RecipientPropagator($user, $this->getChangePropagator($user), $this->config, $this);
-		return $this->sharePropagators[$user];
-	}
-
-	/**
-	 * Attach the recipient propagator for $user to the change propagator of a share owner to mark shares as dirty when the owner makes a change to a share
-	 *
-	 * @param string $shareOwner
-	 * @param string $user
-	 */
-	public function listenToOwnerChanges($shareOwner, $user) {
-		$sharePropagator = $this->getSharePropagator($user);
-		$ownerPropagator = $this->getChangePropagator($shareOwner);
-		$sharePropagator->attachToPropagator($ownerPropagator, $shareOwner);
-	}
-
-	/**
-	 * To be called from setupFS trough a hook
-	 *
-	 * Sets up listening to changes made to shares owned by the current user
-	 */
-	public function globalSetup() {
-		$user = $this->userSession->getUser();
-		if (!$user) {
-			return;
-		}
-		$recipientPropagator = $this->getSharePropagator($user->getUID());
-		$watcher = new ChangeWatcher(Filesystem::getView(), $recipientPropagator);
-
-		// for marking shares owned by the active user as dirty when a file inside them changes
-		$this->listenToOwnerChanges($user->getUID(), $user->getUID());
-		Util::connectHook('OC_Filesystem', 'post_write', $watcher, 'writeHook');
-		Util::connectHook('OC_Filesystem', 'post_delete', $watcher, 'writeHook');
-		Util::connectHook('OC_Filesystem', 'post_rename', $watcher, 'renameHook');
-		Util::connectHook('OCP\Share', 'post_update_permissions', $watcher, 'permissionsHook');
-	}
-}
diff --git a/apps/files_sharing/lib/propagation/recipientpropagator.php b/apps/files_sharing/lib/propagation/recipientpropagator.php
deleted file mode 100644
index 5eacf4c0f6e86292d274e7a5dc7cd7c23ec4cef4..0000000000000000000000000000000000000000
--- a/apps/files_sharing/lib/propagation/recipientpropagator.php
+++ /dev/null
@@ -1,164 +0,0 @@
-<?php
-/**
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Propagation;
-
-use OC\Files\Cache\ChangePropagator;
-use OC\Files\View;
-use OC\Share\Share;
-use OCP\Files\NotFoundException;
-
-/**
- * Propagate etags for share recipients
- */
-class RecipientPropagator {
-	/**
-	 * @var string
-	 */
-	protected $userId;
-
-	/**
-	 * @var \OC\Files\Cache\ChangePropagator
-	 */
-	protected $changePropagator;
-
-	/**
-	 * @var \OCP\IConfig
-	 */
-	protected $config;
-
-	/**
-	 * @var PropagationManager
-	 */
-	private $manager;
-
-	/**
-	 * @param string $userId current user, must match the propagator's
-	 * user
-	 * @param \OC\Files\Cache\ChangePropagator $changePropagator change propagator
-	 * initialized with a view for $user
-	 * @param \OCP\IConfig $config
-	 * @param PropagationManager $manager
-	 */
-	public function __construct($userId, $changePropagator, $config, PropagationManager $manager) {
-		$this->userId = $userId;
-		$this->changePropagator = $changePropagator;
-		$this->config = $config;
-		$this->manager = $manager;
-	}
-
-	/**
-	 * Propagate the etag changes for all shares marked as dirty and mark the shares as clean
-	 *
-	 * @param array $shares the shares for the users
-	 * @param int $time
-	 */
-	public function propagateDirtyMountPoints(array $shares, $time = null) {
-		if ($time === null) {
-			$time = microtime(true);
-		}
-		$dirtyShares = $this->getDirtyShares($shares);
-		foreach ($dirtyShares as $share) {
-			$this->changePropagator->addChange($share['file_target']);
-		}
-		if (count($dirtyShares)) {
-			$this->config->setUserValue($this->userId, 'files_sharing', 'last_propagate', $time);
-			$this->changePropagator->propagateChanges(floor($time));
-		}
-	}
-
-	/**
-	 * Get all shares we need to update the etag for
-	 *
-	 * @param array $shares the shares for the users
-	 * @return string[]
-	 */
-	protected function getDirtyShares($shares) {
-		$dirty = [];
-		$userTime = $this->config->getUserValue($this->userId, 'files_sharing', 'last_propagate', 0);
-		foreach ($shares as $share) {
-			$updateTime = $this->config->getAppValue('files_sharing', $share['id'], 0);
-			if ($updateTime >= $userTime) {
-				$dirty[] = $share;
-			}
-		}
-		return $dirty;
-	}
-
-	/**
-	 * @param array $share
-	 * @param float $time
-	 */
-	public function markDirty($share, $time = null) {
-		if ($time === null) {
-			$time = microtime(true);
-		}
-		$this->config->setAppValue('files_sharing', $share['id'], $time);
-	}
-
-	/**
-	 * Listen on the propagator for updates made to shares owned by a user
-	 *
-	 * @param \OC\Files\Cache\ChangePropagator $propagator
-	 * @param string $owner
-	 */
-	public function attachToPropagator(ChangePropagator $propagator, $owner) {
-		$propagator->listen('\OC\Files', 'propagate', function ($path, $entry) use ($owner) {
-			$this->propagateById($entry['fileid']);
-		});
-	}
-
-	protected $propagatingIds = [];
-
-	/**
-	 * @param int $id
-	 */
-	public function propagateById($id) {
-		if (isset($this->propagatingIds[$id])) {
-			return;
-		}
-		$this->propagatingIds[$id] = true;
-		$shares = Share::getAllSharesForFileId($id);
-		foreach ($shares as $share) {
-			// propagate down the share tree
-			$this->markDirty($share, microtime(true));
-
-			// propagate up the share tree
-			if ($share['share_with'] === $this->userId) {
-				$user = $share['uid_owner'];
-				$view = new View('/' . $user . '/files');
-
-				try {
-					$path = $view->getPath($share['file_source']);
-				} catch (NotFoundException $e) {
-					$path = null;
-				}
-
-				$watcher = new ChangeWatcher($view, $this->manager->getSharePropagator($user));
-				$watcher->writeHook(['path' => $path]);
-			}
-		}
-
-		unset($this->propagatingIds[$id]);
-	}
-}
diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php
index a1387957867a0ce6334c566943b25cfd5db9b3f1..275fea97c7f0340dbf63eecaf264ae0d19d62f5d 100644
--- a/apps/files_sharing/lib/sharedmount.php
+++ b/apps/files_sharing/lib/sharedmount.php
@@ -38,11 +38,6 @@ class SharedMount extends MountPoint implements MoveableMount {
 	 */
 	protected $storage = null;
 
-	/**
-	 * @var \OC\Files\Cache\ChangePropagator
-	 */
-	protected $ownerPropagator;
-
 	/**
 	 * @var \OC\Files\View
 	 */
@@ -54,8 +49,6 @@ class SharedMount extends MountPoint implements MoveableMount {
 	private $user;
 
 	public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
-		// first update the mount point before creating the parent
-		$this->ownerPropagator = $arguments['propagator'];
 		$this->user = $arguments['user'];
 		$this->recipientView = new View('/' . $this->user . '/files');
 		$newMountPoint = $this->verifyMountPoint($arguments['share']);
@@ -201,11 +194,4 @@ class SharedMount extends MountPoint implements MoveableMount {
 	public function getShare() {
 		return $this->getStorage()->getShare();
 	}
-
-	/**
-	 * @return \OC\Files\Cache\ChangePropagator
-	 */
-	public function getOwnerPropagator() {
-		return $this->ownerPropagator;
-	}
 }
diff --git a/apps/files_sharing/lib/sharedpropagator.php b/apps/files_sharing/lib/sharedpropagator.php
new file mode 100644
index 0000000000000000000000000000000000000000..fcb4b92dd331dcd64478ea7d508f66b73e475661
--- /dev/null
+++ b/apps/files_sharing/lib/sharedpropagator.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Sharing;
+
+use OC\Files\Cache\Propagator;
+
+class SharedPropagator extends Propagator {
+	/**
+	 * @var \OC\Files\Storage\Shared
+	 */
+	protected $storage;
+
+	/**
+	 * @param string $internalPath
+	 * @param int $time
+	 * @return array[] all propagated entries
+	 */
+	public function propagateChange($internalPath, $time) {
+		$source = $this->storage->getSourcePath($internalPath);
+		/** @var \OC\Files\Storage\Storage $storage */
+		list($storage, $sourceInternalPath) = \OC\Files\Filesystem::resolvePath($source);
+		return $storage->getPropagator()->propagateChange($sourceInternalPath, $time);
+	}
+}
diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php
index 18e02844179526adfa2f7f2ea6a4ef1957bf4722..4807b5ee73857b71659d1664487bd23c450aa719 100644
--- a/apps/files_sharing/lib/sharedstorage.php
+++ b/apps/files_sharing/lib/sharedstorage.php
@@ -50,11 +50,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 	 */
 	private $ownerView;
 
-	/**
-	 * @var \OCA\Files_Sharing\Propagation\PropagationManager
-	 */
-	private $propagationManager;
-
 	/**
 	 * @var string
 	 */
@@ -65,7 +60,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 	public function __construct($arguments) {
 		$this->share = $arguments['share'];
 		$this->ownerView = $arguments['ownerView'];
-		$this->propagationManager = $arguments['propagationManager'];
 		$this->user = $arguments['user'];
 	}
 
@@ -75,9 +69,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 		}
 		$this->initialized = true;
 		Filesystem::initMountPoints($this->share['uid_owner']);
-
-		// for updating our etags when changes are made to the share from the owners side (probably indirectly by us trough another share)
-		$this->propagationManager->listenToOwnerChanges($this->share['uid_owner'], $this->user);
 	}
 
 	/**
@@ -571,6 +562,13 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 		return new \OC\Files\Cache\Shared_Watcher($storage);
 	}
 
+	public function getPropagator($storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return new \OCA\Files_Sharing\SharedPropagator($storage);
+	}
+
 	public function getOwner($path) {
 		if ($path == '') {
 			$path = $this->getMountPoint();
diff --git a/apps/files_sharing/tests/grouppropagationmanager.php b/apps/files_sharing/tests/grouppropagationmanager.php
deleted file mode 100644
index ea32ca4f7ec76a2968159332b10a8b964ea5b21a..0000000000000000000000000000000000000000
--- a/apps/files_sharing/tests/grouppropagationmanager.php
+++ /dev/null
@@ -1,173 +0,0 @@
-<?php
-/**
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_sharing\Tests;
-
-use OC\Files\View;
-use OCP\IGroupManager;
-use OCP\IGroup;
-use OCP\IUser;
-use OCP\Share;
-use OCA\Files_Sharing\Propagation\GroupPropagationManager;
-use OCA\Files_Sharing\Propagation\PropagationManager;
-
-class GroupPropagationManagerTest extends TestCase {
-
-	/**
-	 * @var GroupPropagationManager
-	 */
-	private $groupPropagationManager;
-
-	/**
-	 * @var IGroupManager
-	 */
-	private $groupManager;
-
-	/**
-	 * @var PropagationManager
-	 */
-	private $propagationManager;
-
-	/**
-	 * @var IGroup
-	 */
-	private $recipientGroup;
-
-	/**
-	 * @var IUser
-	 */
-	private $recipientUser;
-
-	/**
-	 * @var array
-	 */
-	private $fileInfo;
-
-	protected function setUp() {
-		parent::setUp();
-
-		$user = $this->getMockBuilder('\OCP\IUser')
-		             ->disableOriginalConstructor()
-		             ->getMock();
-		$user->method('getUID')->willReturn(self::TEST_FILES_SHARING_API_USER1);
-		$userSession = $this->getMockBuilder('\OCP\IUserSession')
-		                    ->disableOriginalConstructor()
-		                    ->getMock();
-		$userSession->method('getUser')->willReturn(selF::TEST_FILES_SHARING_API_USER1);
-
-		$this->propagationManager = $this->getMockBuilder('OCA\Files_Sharing\Propagation\PropagationManager')
-			->disableOriginalConstructor()
-			->getMock();
-
-		$this->groupManager = \OC::$server->getGroupManager();
-		$this->groupPropagationManager = new GroupPropagationManager(
-			$userSession,
-			$this->groupManager,
-			$this->propagationManager
-		);
-		$this->groupPropagationManager->globalSetup();
-
-		// since the sharing code is not mockable, we have to create a real folder
-		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
-		$view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
-		$view1->mkdir('/folder');
-
-		$this->fileInfo = $view1->getFileInfo('/folder');
-
-		$this->recipientGroup = $this->groupManager->get(self::TEST_FILES_SHARING_API_GROUP1);
-		$this->recipientUser = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3);
-
-		Share::shareItem(
-			'folder',
-			$this->fileInfo['fileid'],
-			Share::SHARE_TYPE_GROUP,
-			$this->recipientGroup->getGID(),
-			\OCP\Constants::PERMISSION_READ
-		);
-
-		$this->loginAsUser($this->recipientUser->getUID());
-	}
-
-	protected function tearDown() {
-		$this->groupPropagationManager->tearDown();
-		$this->recipientGroup->removeUser($this->recipientUser);
-		parent::tearDown();
-	}
-
-	public function testPropagateWhenAddedToGroup() {
-		$this->propagationManager->expects($this->once())
-			->method('propagateSharesToUser')
-			->with($this->callback(function($shares) {
-				if (count($shares) !== 1) {
-					return false;
-				}
-				$share = array_values($shares)[0];
-				return $share['file_source'] === $this->fileInfo['fileid'] &&
-					$share['share_with'] === $this->recipientGroup->getGID() &&
-					$share['file_target'] === '/folder';
-			}), $this->recipientUser->getUID());
-
-		$this->recipientGroup->addUser($this->recipientUser);
-	}
-
-	public function testPropagateWhenRemovedFromGroup() {
-		$this->recipientGroup->addUser($this->recipientUser);
-
-		$this->propagationManager->expects($this->once())
-			->method('propagateSharesToUser')
-			->with($this->callback(function($shares) {
-				if (count($shares) !== 1) {
-					return false;
-				}
-				$share = array_values($shares)[0];
-				return $share['file_source'] === $this->fileInfo['fileid'] &&
-					$share['share_with'] === $this->recipientGroup->getGID() &&
-					$share['file_target'] === '/folder';
-			}), $this->recipientUser->getUID());
-
-		$this->recipientGroup->removeUser($this->recipientUser);
-	}
-
-	public function testPropagateWhenRemovedFromGroupWithSubdirTarget() {
-		$this->recipientGroup->addUser($this->recipientUser);
-
-		// relogin to refresh mount points
-		$this->loginAsUser($this->recipientUser->getUID());
-		$recipientView = new View('/' . $this->recipientUser->getUID() . '/files');
-
-		$this->assertTrue($recipientView->mkdir('sub'));
-		$this->assertTrue($recipientView->rename('folder', 'sub/folder'));
-
-		$this->propagationManager->expects($this->once())
-			->method('propagateSharesToUser')
-			->with($this->callback(function($shares) {
-				if (count($shares) !== 1) {
-					return false;
-				}
-				$share = array_values($shares)[0];
-				return $share['file_source'] === $this->fileInfo['fileid'] &&
-					$share['share_with'] === $this->recipientGroup->getGID() &&
-					$share['file_target'] === '/sub/folder';
-			}), $this->recipientUser->getUID());
-
-		$this->recipientGroup->removeUser($this->recipientUser);
-	}
-}
diff --git a/apps/files_sharing/tests/testcase.php b/apps/files_sharing/tests/testcase.php
index c91734a5b03ca5e54d8e313a04fe671843e21eb9..6a72a34149ad53eb2210ba47f30d62befece233c 100644
--- a/apps/files_sharing/tests/testcase.php
+++ b/apps/files_sharing/tests/testcase.php
@@ -61,7 +61,6 @@ abstract class TestCase extends \Test\TestCase {
 
 		$application = new Application();
 		$application->registerMountProviders();
-		$application->setupPropagation();
 		
 		// reset backend
 		\OC_User::clearBackends();
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
index 404772433243113a4882be7b0388246acf329b8d..e6110c1925ddce88916cd65ef5d346355433d03c 100644
--- a/lib/private/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -160,6 +160,7 @@ class Cache {
 		} else {
 			//fix types
 			$data['fileid'] = (int)$data['fileid'];
+			$data['parent'] = (int)$data['parent'];
 			$data['size'] = 0 + $data['size'];
 			$data['mtime'] = (int)$data['mtime'];
 			$data['storage_mtime'] = (int)$data['storage_mtime'];
@@ -391,12 +392,17 @@ class Cache {
 		if ($file === '') {
 			return -1;
 		} else {
-			$parent = dirname($file);
-			if ($parent === '.') {
-				$parent = '';
-			}
-			return $this->getId($parent);
+			$parent = $this->getParentPath($file);
+			return (int) $this->getId($parent);
+		}
+	}
+
+	private function getParentPath($path) {
+		$parent = dirname($path);
+		if ($parent === '.') {
+			$parent = '';
 		}
+		return $parent;
 	}
 
 	/**
diff --git a/lib/private/files/cache/changepropagator.php b/lib/private/files/cache/changepropagator.php
index 9696a82257e19c6cd209d62460e60437bb0ed725..2a48eb13c596899630b3a221e1e842d93a0aec65 100644
--- a/lib/private/files/cache/changepropagator.php
+++ b/lib/private/files/cache/changepropagator.php
@@ -22,6 +22,7 @@
 
 namespace OC\Files\Cache;
 
+use OC\Files\Filesystem;
 use OC\Hooks\BasicEmitter;
 
 /**
@@ -61,23 +62,30 @@ class ChangePropagator extends BasicEmitter {
 	 * @param int $time (optional) the mtime to set for the folders, if not set the current time is used
 	 */
 	public function propagateChanges($time = null) {
-		$parents = $this->getAllParents();
-		$this->changedFiles = array();
+		$changes = $this->getChanges();
+		$this->changedFiles = [];
 		if (!$time) {
 			$time = time();
 		}
-		foreach ($parents as $parent) {
+		foreach ($changes as $change) {
 			/**
 			 * @var \OC\Files\Storage\Storage $storage
 			 * @var string $internalPath
 			 */
 
-			list($storage, $internalPath) = $this->view->resolvePath($parent);
+			$absolutePath = $this->view->getAbsolutePath($change);
+			$mount = $this->view->getMount($change);
+			$storage = $mount->getStorage();
+			$internalPath = $mount->getInternalPath($absolutePath);
 			if ($storage) {
-				$cache = $storage->getCache();
-				$entry = $cache->get($internalPath);
-				$cache->update($entry['fileid'], array('mtime' => max($time, $entry['mtime']), 'etag' => $storage->getETag($internalPath)));
-				$this->emit('\OC\Files', 'propagate', [$parent, $entry]);
+				$propagator = $storage->getPropagator();
+				$propagatedEntries = $propagator->propagateChange($internalPath, $time);
+
+				foreach ($propagatedEntries as $entry) {
+					$absolutePath = Filesystem::normalizePath($mount->getMountPoint() . '/' . $entry['path']);
+					$relativePath = $this->view->getRelativePath($absolutePath);
+					$this->emit('\OC\Files', 'propagate', [$relativePath, $entry]);
+				}
 			}
 		}
 	}
diff --git a/lib/private/files/cache/propagator.php b/lib/private/files/cache/propagator.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd11cef5990d02e24551ee86af473d2d98566a39
--- /dev/null
+++ b/lib/private/files/cache/propagator.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Cache;
+
+/**
+ * Propagate etags and mtimes within the storage
+ */
+class Propagator {
+	/**
+	 * @var \OC\Files\Storage\Storage
+	 */
+	protected $storage;
+
+	/**
+	 * @param \OC\Files\Storage\Storage $storage
+	 */
+	public function __construct(\OC\Files\Storage\Storage $storage) {
+		$this->storage = $storage;
+	}
+
+
+	/**
+	 * @param string $internalPath
+	 * @param int $time
+	 * @return array[] all propagated entries
+	 */
+	public function propagateChange($internalPath, $time) {
+		$cache = $this->storage->getCache($internalPath);
+
+		$parentId = $cache->getParentId($internalPath);
+		$propagatedEntries = [];
+		while ($parentId !== -1) {
+			$entry = $cache->get($parentId);
+			$propagatedEntries[] = $entry;
+			if (!$entry) {
+				return $propagatedEntries;
+			}
+			$mtime = max($time, $entry['mtime']);
+
+			$cache->update($parentId, ['mtime' => $mtime, 'etag' => $this->storage->getETag($entry['path'])]);
+
+			$parentId = $entry['parent'];
+		}
+
+		return $propagatedEntries;
+	}
+}
diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php
index 2d2ef325d38aeef218689b83690e6b50a077d250..5b5e8697004c7eaf1228a7fdb91fab020ea94438 100644
--- a/lib/private/files/fileinfo.php
+++ b/lib/private/files/fileinfo.php
@@ -61,6 +61,11 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	 */
 	private $owner;
 
+	/**
+	 * @var string[]
+	 */
+	private $childEtags = [];
+
 	/**
 	 * @param string|boolean $path
 	 * @param Storage\Storage $storage
@@ -93,6 +98,8 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	public function offsetGet($offset) {
 		if ($offset === 'type') {
 			return $this->getType();
+		} else if ($offset === 'etag') {
+			return $this->getEtag();
 		} elseif (isset($this->data[$offset])) {
 			return $this->data[$offset];
 		} else {
@@ -153,7 +160,12 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	 * @return string
 	 */
 	public function getEtag() {
-		return $this->data['etag'];
+		if (count($this->childEtags) > 0) {
+			$combinedEtag = $this->data['etag'] . '::' . implode('::', $this->childEtags);
+			return md5($combinedEtag);
+		} else {
+			return $this->data['etag'];
+		}
 	}
 
 	/**
@@ -292,8 +304,19 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
 	 * Sets the size, etag and size to for cross-storage childs
 	 *
 	 * @param array $data cache entry for the child
+	 * @param string $entryPath full path of the child entry
 	 */
-	public function addSubEntry($data) {
+	public function addSubEntry($data, $entryPath) {
 		$this->data['size'] += isset($data['size']) ? $data['size'] : 0;
+		if (isset($data['mtime'])) {
+			$this->data['mtime'] = max($this->data['mtime'], $data['mtime']);
+		}
+		if (isset($data['etag'])) {
+			// prefix the etag with the relative path of the subentry to propagate etag on mount moves
+			$relativeEntryPath = substr($entryPath, strlen($this->getPath()));
+			// attach the permissions to propagate etag on permision changes of submounts
+			$permissions = isset($data['permissions']) ? $data['permissions'] : 0;
+			$this->childEtags[] = $relativeEntryPath . '/' . $data['etag'] . $permissions;
+		}
 	}
 }
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index 77a70226b37cb1e44409e7ae8337e78fcb9b3412..a52e7c35f8759ea8974fe6ee9c5788ba8a6b8e10 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -37,6 +37,7 @@
 namespace OC\Files\Storage;
 
 use OC\Files\Cache\Cache;
+use OC\Files\Cache\Propagator;
 use OC\Files\Cache\Scanner;
 use OC\Files\Filesystem;
 use OC\Files\Cache\Watcher;
@@ -64,6 +65,7 @@ abstract class Common implements Storage {
 	protected $cache;
 	protected $scanner;
 	protected $watcher;
+	protected $propagator;
 	protected $storageCache;
 
 	protected $mountOptions = [];
@@ -345,6 +347,22 @@ abstract class Common implements Storage {
 		return $this->watcher;
 	}
 
+	/**
+	 * get a propagator instance for the cache
+	 *
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
+	 * @return \OC\Files\Cache\Propagator
+	 */
+	public function getPropagator($storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		if (!isset($this->propagator)) {
+			$this->propagator = new Propagator($storage);
+		}
+		return $this->propagator;
+	}
+
 	public function getStorageCache($storage = null) {
 		if (!$storage) {
 			$storage = $this;
diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php
index f46ac544b56566437f69bd69f0fdc770233a8932..3399c71789029f2969c797cee4844291e529df89 100644
--- a/lib/private/files/storage/storage.php
+++ b/lib/private/files/storage/storage.php
@@ -67,6 +67,14 @@ interface Storage extends \OCP\Files\Storage {
 	 */
 	public function getWatcher($path = '', $storage = null);
 
+	/**
+	 * get a propagator instance for the cache
+	 *
+	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
+	 * @return \OC\Files\Cache\Propagator
+	 */
+	public function getPropagator($storage = null);
+
 	/**
 	 * @return \OC\Files\Cache\Storage
 	 */
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index 048738170dbd5e0c0665c5363f07898ea7f685d6..5327b94211b5e500c4403934855298c7fce73c13 100644
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
@@ -430,6 +430,13 @@ class Wrapper implements \OC\Files\Storage\Storage {
 		return $this->storage->getWatcher($path, $storage);
 	}
 
+	public function getPropagator($storage = null) {
+		if (!$storage) {
+			$storage = $this;
+		}
+		return $this->storage->getPropagator($storage);
+	}
+
 	/**
 	 * @return \OC\Files\Cache\Storage
 	 */
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 5f19558a4fcb6312f992a300d7869b1677ec12f3..3ad9d36a3844f27c08e739a87f0f5560c168655b 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -707,10 +707,6 @@ class View {
 				} else if ($result) {
 					if ($internalPath1 !== '') { // dont do a cache update for moved mounts
 						$this->updater->rename($path1, $path2);
-					} else { // only do etag propagation
-						$this->getUpdater()->getPropagator()->addChange($path1);
-						$this->getUpdater()->getPropagator()->addChange($path2);
-						$this->getUpdater()->getPropagator()->propagateChanges();
 					}
 				}
 
@@ -1179,6 +1175,11 @@ class View {
 	}
 
 	/**
+	 * Get file info from cache
+	 *
+	 * If the file is not in cached it will be scanned
+	 * If the file has changed on storage the cache will be updated
+	 *
 	 * @param \OC\Files\Storage\Storage $storage
 	 * @param string $internalPath
 	 * @param string $relativePath
@@ -1266,7 +1267,7 @@ class View {
 							}
 							$subCache = $subStorage->getCache('');
 							$rootEntry = $subCache->get('');
-							$info->addSubEntry($rootEntry);
+							$info->addSubEntry($rootEntry, $mount->getMountPoint());
 						}
 					}
 				}
@@ -1357,7 +1358,7 @@ class View {
 							$entryName = substr($relativePath, 0, $pos);
 							foreach ($files as &$entry) {
 								if ($entry->getName() === $entryName) {
-									$entry->addSubEntry($rootEntry);
+									$entry->addSubEntry($rootEntry, $mountPoint);
 								}
 							}
 						} else { //mountpoint in this folder, add an entry for it
diff --git a/tests/lib/files/cache/changepropagator.php b/tests/lib/files/cache/changepropagator.php
index 1b56da5e97c27a2f600058be0a0aa995bd5ac3c7..9108330eb9b9810771289414bf762e1c093035c1 100644
--- a/tests/lib/files/cache/changepropagator.php
+++ b/tests/lib/files/cache/changepropagator.php
@@ -94,4 +94,37 @@ class ChangePropagator extends \Test\TestCase {
 		$this->assertEquals(100, $time - $cache->get('foo')['mtime']);
 		$this->assertEquals(100, $time - $cache->get('foo/bar')['mtime']);
 	}
+
+	public function testPropagateCrossStorage() {
+		$storage = new Temporary();
+		$this->view->mkdir('/foo');
+		Filesystem::mount($storage, [], $this->view->getAbsolutePath('/foo/submount'));
+		$this->view->mkdir('/foo/submount/bar');
+		$this->view->file_put_contents('/foo/submount/bar/sad.txt', 'qwerty');
+
+		$oldInfo1 = $this->view->getFileInfo('/');
+		$oldInfo2 = $this->view->getFileInfo('/foo');
+		$oldInfo3 = $this->view->getFileInfo('/foo/submount');
+		$oldInfo4 = $this->view->getFileInfo('/foo/submount/bar');
+
+		$time = time() + 50;
+
+		$this->propagator->addChange('/foo/submount/bar/sad.txt');
+		$this->propagator->propagateChanges($time);
+
+		$newInfo1 = $this->view->getFileInfo('/');
+		$newInfo2 = $this->view->getFileInfo('/foo');
+		$newInfo3 = $this->view->getFileInfo('/foo/submount');
+		$newInfo4 = $this->view->getFileInfo('/foo/submount/bar');
+
+		$this->assertEquals($newInfo1->getMTime(), $time);
+		$this->assertEquals($newInfo2->getMTime(), $time);
+		$this->assertEquals($newInfo3->getMTime(), $time);
+		$this->assertEquals($newInfo4->getMTime(), $time);
+
+		$this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag());
+		$this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag());
+		$this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag());
+		$this->assertNotSame($oldInfo4->getEtag(), $newInfo3->getEtag());
+	}
 }