[Patch 2/2] Ext2 optimize to sequential read

Sven 'sleipnir' Rebhan odinshorse at googlemail.com
Thu Dec 18 08:39:29 CET 2008


Modified patch originates from Andy Green <andy at openmoko.com>
http://www.mail-archive.com/openmoko-kernel@lists.openmoko.org/msg05708.html

--- fs/ext2/ext2fs.c    2008-12-17 23:21:29.000000000 +0100
+++ fs/ext2/ext2fs.c.new        2008-12-17 23:27:47.000000000 +0100
@@ -390,6 +390,13 @@
        int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data);
        int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
        unsigned int filesize = __le32_to_cpu(node->inode.size);
+       int previous_block_number = -1;
+       int delayed_start = 0;
+       int delayed_extent = 0;
+       int delayed_skipfirst = 0;
+       int delayed_next = 0;
+       char * delayed_buf = NULL;
+       int status;

        /* Adjust len so it we can't read past the end of the file.  */
        if (len > filesize) {
@@ -431,15 +438,56 @@
                if (blknr) {
                        int status;

-                       status = ext2fs_devread (blknr, skipfirst,
blockend, buf);
-                       if (status == 0) {
-                               return (-1);
+                       if (previous_block_number != -1) {
+                               if (delayed_next == blknr) {
+                                       delayed_extent += blockend;
+                                       delayed_next += blockend >> SECTOR_BITS;
+                               } else { /* spill */
+                                       status = ext2fs_devread(delayed_start,
+
delayed_skipfirst,
+
delayed_extent, delayed_buf);
+                                       if (status == 0)
+                                               return -1;
+                                       previous_block_number = blknr;
+                                       delayed_start = blknr;
+                                       delayed_extent = blockend;
+                                       delayed_skipfirst = skipfirst;
+                                       delayed_buf = buf;
+                                       delayed_next = blknr +
(blockend >> SECTOR_BITS);
+                               }
+                       } else {
+                               previous_block_number = blknr;
+                               delayed_start = blknr;
+                               delayed_extent = blockend;
+                               delayed_skipfirst = skipfirst;
+                               delayed_buf = buf;
+                               delayed_next = blknr + (blockend >>
SECTOR_BITS);
                        }
                } else {
-                       memset (buf, 0, blocksize - skipfirst);
+                       if (previous_block_number != -1) {
+                               /* spill */
+                               status = ext2fs_devread(delayed_start,
+                                                       delayed_skipfirst,
+
delayed_extent, delayed_buf);
+                               if (status == 0)
+                                       return -1;
+                               previous_block_number = -1;
+                       }
+                       memset(buf, 0, blocksize - skipfirst);
                }
                buf += blocksize - skipfirst;
        }
+
+       if (previous_block_number != -1) {
+               /* spill */
+               status = ext2fs_devread(delayed_start,
+                                       delayed_skipfirst,
+                                       delayed_extent, delayed_buf);
+               if (status == 0)
+                       return -1;
+               previous_block_number = -1;
+       }
+
        return (len);
 }



More information about the openmoko-kernel mailing list