diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
index f621741e40..f1fce48a39 100644
--- a/fs/ext2/ext2fs.c
+++ b/fs/ext2/ext2fs.c
@@ -420,7 +420,6 @@ int ext2fs_read_file
 		if (blknr < 0) {
 			return (-1);
 		}
-		blknr = blknr << log2blocksize;
 
 		/* Last block.  */
 		if (i == blockcnt - 1) {
@@ -438,6 +437,29 @@ int ext2fs_read_file
 			blockend -= skipfirst;
 		}
 
+		/* grab middle blocks in one go */
+		if (i != pos / blocksize && i != blockcnt - 1 && blockcnt > 3) {
+			int oldblk = blknr;
+			int blocknxt;
+			while (i < blockcnt - 1) {
+				blocknxt = ext2fs_read_block(node, i + 1);
+				if (blocknxt == (oldblk + 1)) {
+					oldblk = blocknxt;
+					i++;
+				} else {
+					blocknxt = ext2fs_read_block(node, i);
+					break;
+				}
+			}
+
+			if (oldblk == blknr)
+				blockend = blocksize;
+			else
+				blockend = (1 + blocknxt - blknr) * blocksize;
+		}
+
+		blknr = blknr << log2blocksize;
+
 		/* If the block number is 0 this block is not stored on disk but
 		   is zero filled instead.  */
 		if (blknr) {
@@ -450,7 +472,7 @@ int ext2fs_read_file
 		} else {
 			memset (buf, 0, blocksize - skipfirst);
 		}
-		buf += blocksize - skipfirst;
+		buf += blockend - skipfirst;
 	}
 	return (len);
 }