From c8f9efeb94b136ed0906cefe946629a091796ff2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu>
Date: Mon, 16 Sep 2013 23:32:17 +0200
Subject: [PATCH] etag changes are now propagated up the file tree

---
 lib/files/cache/scanner.php       | 14 ++++++++++++++
 tests/lib/files/cache/scanner.php | 21 +++++++++++++++------
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php
index 78cab6ed2d..fdbce0d51f 100644
--- a/lib/files/cache/scanner.php
+++ b/lib/files/cache/scanner.php
@@ -99,8 +99,10 @@ class Scanner extends BasicEmitter {
 				if ($reuseExisting and $cacheData = $this->cache->get($file)) {
 					// prevent empty etag
 					$etag = $cacheData['etag'];
+					$propagateETagChange = false;
 					if (empty($etag)) {
 						$etag = $data['etag'];
+						$propagateETagChange = true;
 					}
 
 					// only reuse data if the file hasn't explicitly changed
@@ -110,6 +112,18 @@ class Scanner extends BasicEmitter {
 						}
 						if ($reuseExisting & self::REUSE_ETAG) {
 							$data['etag'] = $etag;
+							if ($propagateETagChange) {
+								$parent = $file;
+								while ($parent !== '') {
+									$parent = dirname($parent);
+									if ($parent === '.') {
+										$parent = '';
+									}
+									$parentCacheData = $this->cache->get($parent);
+									$parentCacheData['etag'] = $this->storage->getETag($parent);
+									$this->cache->put($parent, $parentCacheData);
+								}
+							}
 						}
 					}
 					// Only update metadata that has changed
diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php
index fa1b340604..b137799bbc 100644
--- a/tests/lib/files/cache/scanner.php
+++ b/tests/lib/files/cache/scanner.php
@@ -187,17 +187,26 @@ class Scanner extends \PHPUnit_Framework_TestCase {
 	public function testETagRecreation() {
 		$this->fillTestFolders();
 
-		$this->scanner->scan('');
+		$this->scanner->scan('folder/bar.txt');
 
 		// manipulate etag to simulate an empty etag
 		$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
-		$data['etag'] = '';
-		$this->cache->put('', $data);
+		$data0 = $this->cache->get('folder/bar.txt');
+		$data1 = $this->cache->get('folder');
+		$data2 = $this->cache->get('');
+		$data0['etag'] = '';
+		$this->cache->put('folder/bar.txt', $data0);
 
 		// rescan
-		$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
-		$newData = $this->cache->get('');
-		$this->assertNotEmpty($newData['etag']);
+		$this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
+
+		// verify cache content
+		$newData0 = $this->cache->get('folder/bar.txt');
+		$newData1 = $this->cache->get('folder');
+		$newData2 = $this->cache->get('');
+		$this->assertNotEmpty($newData0['etag']);
+		$this->assertNotEquals($data1['etag'], $newData1['etag']);
+		$this->assertNotEquals($data2['etag'], $newData2['etag']);
 
 	}
 
-- 
GitLab