diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
index e2da8cf2e05a396ca1376fcbb56031fa0e72e617..43016e0892fbab9572a26fd2bdc14d8610746d31 100644
--- a/lib/private/files/storage/wrapper/quota.php
+++ b/lib/private/files/storage/wrapper/quota.php
@@ -95,7 +95,7 @@ class Quota extends Wrapper {
 	public function fopen($path, $mode) {
 		$source = $this->storage->fopen($path, $mode);
 		$free = $this->free_space('');
-		if ($free >= 0) {
+		if ($free >= 0 && $mode !== 'r') {
 			return \OC\Files\Stream\Quota::wrap($source, $free);
 		} else {
 			return $source;
diff --git a/lib/private/files/stream/quota.php b/lib/private/files/stream/quota.php
index 53d8a03d30f6e135d517ef869ef7593fd94ea76b..60e60da8e67a204b8ae6490f29d5842e72f702e0 100644
--- a/lib/private/files/stream/quota.php
+++ b/lib/private/files/stream/quota.php
@@ -66,12 +66,24 @@ class Quota {
 	}
 
 	public function stream_seek($offset, $whence = SEEK_SET) {
-		if ($whence === SEEK_SET) {
+		if ($whence === SEEK_END){
+			// go to the end to find out last position's offset
+			$oldOffset = $this->stream_tell();
+			if (fseek($this->source, 0, $whence) !== 0){
+				return false;
+			}
+			$whence = SEEK_SET;
+			$offset = $this->stream_tell() + $offset;
+			$this->limit += $oldOffset - $offset;
+		}
+		else if ($whence === SEEK_SET) {
 			$this->limit += $this->stream_tell() - $offset;
 		} else {
 			$this->limit -= $offset;
 		}
-		fseek($this->source, $offset, $whence);
+		// this wrapper needs to return "true" for success.
+		// the fseek call itself returns 0 on succeess
+		return !fseek($this->source, $offset, $whence);
 	}
 
 	public function stream_tell() {
diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php
index 3702f8154f55fafe171bb78457d20a4e4e1269e9..9b14335782faa2d378a9fc96d5b5fe6caa978b2a 100644
--- a/tests/lib/files/storage/wrapper/quota.php
+++ b/tests/lib/files/storage/wrapper/quota.php
@@ -58,4 +58,26 @@ class Quota extends \Test\Files\Storage\Storage {
 		fclose($stream);
 		$this->assertEquals('foobarqwe', $instance->file_get_contents('foo'));
 	}
+
+	public function testReturnRegularStreamOnRead(){
+		$instance = $this->getLimitedStorage(9);
+
+		// create test file first
+		$stream = $instance->fopen('foo', 'w+');
+		fwrite($stream, 'blablacontent');
+		fclose($stream);
+
+		$stream = $instance->fopen('foo', 'r');
+		$meta = stream_get_meta_data($stream);
+		$this->assertEquals('plainfile', $meta['wrapper_type']);
+		fclose($stream);
+	}
+
+	public function testReturnQuotaStreamOnWrite(){
+		$instance = $this->getLimitedStorage(9);
+		$stream = $instance->fopen('foo', 'w+');
+		$meta = stream_get_meta_data($stream);
+		$this->assertEquals('user-space', $meta['wrapper_type']);
+		fclose($stream);
+	}
 }
diff --git a/tests/lib/files/stream/quota.php b/tests/lib/files/stream/quota.php
index 22d3e93592c7de4285e608111327a45f969434dd..b11f0ac74c0b4f3f2295f66585cd87d95a8f639b 100644
--- a/tests/lib/files/stream/quota.php
+++ b/tests/lib/files/stream/quota.php
@@ -75,4 +75,76 @@ class Quota extends \PHPUnit_Framework_TestCase {
 		rewind($stream);
 		$this->assertEquals('qwerty', fread($stream, 100));
 	}
+
+	public function testFseekReturnsSuccess() {
+		$stream = $this->getStream('w+', 100);
+		fwrite($stream, '0123456789');
+		$this->assertEquals(0, fseek($stream, 3, SEEK_SET));
+		$this->assertEquals(0, fseek($stream, -1, SEEK_CUR));
+		$this->assertEquals(0, fseek($stream, -4, SEEK_END));
+	}
+
+	public function testWriteAfterSeekEndWithEnoughSpace() {
+		$stream = $this->getStream('w+', 100);
+		fwrite($stream, '0123456789');
+		fseek($stream, -3, SEEK_END);
+		$this->assertEquals(11, fwrite($stream, 'abcdefghijk'));
+		rewind($stream);
+		$this->assertEquals('0123456abcdefghijk', fread($stream, 100));
+	}
+
+	public function testWriteAfterSeekEndWithNotEnoughSpace() {
+		$stream = $this->getStream('w+', 13);
+		fwrite($stream, '0123456789');
+		// seek forward first to potentially week out
+		// potential limit calculation errors
+		fseek($stream, 4, SEEK_SET);
+		// seek to the end
+		fseek($stream, -3, SEEK_END);
+		$this->assertEquals(6, fwrite($stream, 'abcdefghijk'));
+		rewind($stream);
+		$this->assertEquals('0123456abcdef', fread($stream, 100));
+	}
+
+	public function testWriteAfterSeekSetWithEnoughSpace() {
+		$stream = $this->getStream('w+', 100);
+		fwrite($stream, '0123456789');
+		fseek($stream, 7, SEEK_SET);
+		$this->assertEquals(11, fwrite($stream, 'abcdefghijk'));
+		rewind($stream);
+		$this->assertEquals('0123456abcdefghijk', fread($stream, 100));
+	}
+
+	public function testWriteAfterSeekSetWithNotEnoughSpace() {
+		$stream = $this->getStream('w+', 13);
+		fwrite($stream, '0123456789');
+		fseek($stream, 7, SEEK_SET);
+		$this->assertEquals(6, fwrite($stream, 'abcdefghijk'));
+		rewind($stream);
+		$this->assertEquals('0123456abcdef', fread($stream, 100));
+	}
+
+	public function testWriteAfterSeekCurWithEnoughSpace() {
+		$stream = $this->getStream('w+', 100);
+		fwrite($stream, '0123456789');
+		rewind($stream);
+		fseek($stream, 3, SEEK_CUR);
+		fseek($stream, 5, SEEK_CUR);
+		fseek($stream, -1, SEEK_CUR);
+		$this->assertEquals(11, fwrite($stream, 'abcdefghijk'));
+		rewind($stream);
+		$this->assertEquals('0123456abcdefghijk', fread($stream, 100));
+	}
+
+	public function testWriteAfterSeekCurWithNotEnoughSpace() {
+		$stream = $this->getStream('w+', 13);
+		fwrite($stream, '0123456789');
+		rewind($stream);
+		fseek($stream, 3, SEEK_CUR);
+		fseek($stream, 5, SEEK_CUR);
+		fseek($stream, -1, SEEK_CUR);
+		$this->assertEquals(6, fwrite($stream, 'abcdefghijk'));
+		rewind($stream);
+		$this->assertEquals('0123456abcdef', fread($stream, 100));
+	}
 }