diff -purN -X /home/mbligh/.diff.exclude 160-lotsa_sds/mm/filemap.c 170-readahead_fixes/mm/filemap.c
--- 160-lotsa_sds/mm/filemap.c	2003-11-24 16:12:33.000000000 -0800
+++ 170-readahead_fixes/mm/filemap.c	2003-12-11 17:10:08.000000000 -0800
@@ -587,13 +587,22 @@ void do_generic_mapping_read(struct addr
 			     read_actor_t actor)
 {
 	struct inode *inode = mapping->host;
-	unsigned long index, offset;
+	unsigned long index, offset, last;
 	struct page *cached_page;
 	int error;
 
 	cached_page = NULL;
 	index = *ppos >> PAGE_CACHE_SHIFT;
 	offset = *ppos & ~PAGE_CACHE_MASK;
+	last = (*ppos + desc->count) >> PAGE_CACHE_SHIFT;
+
+	/*
+	 * Let the readahead logic know upfront about all
+	 * the pages we'll need to satisfy this request
+	 */
+	for (; index < last; index++)
+		page_cache_readahead(mapping, ra, filp, index);
+	index = *ppos >> PAGE_CACHE_SHIFT;
 
 	for (;;) {
 		struct page *page;
@@ -612,7 +621,6 @@ void do_generic_mapping_read(struct addr
 		}
 
 		cond_resched();
-		page_cache_readahead(mapping, ra, filp, index);
 
 		nr = nr - offset;
 find_page:
diff -purN -X /home/mbligh/.diff.exclude 160-lotsa_sds/mm/readahead.c 170-readahead_fixes/mm/readahead.c
--- 160-lotsa_sds/mm/readahead.c	2003-10-14 15:50:36.000000000 -0700
+++ 170-readahead_fixes/mm/readahead.c	2003-12-11 17:10:08.000000000 -0800
@@ -347,6 +347,8 @@ page_cache_readahead(struct address_spac
 	unsigned min;
 	unsigned orig_next_size;
 	unsigned actual;
+	int first_access=0;
+	unsigned long preoffset=0;
 
 	/*
 	 * Here we detect the case where the application is performing
@@ -370,16 +372,18 @@ page_cache_readahead(struct address_spac
 	min = get_min_readahead(ra);
 	orig_next_size = ra->next_size;
 
-	if (ra->next_size == 0 && offset == 0) {
+	if (ra->next_size == 0) {
 		/*
-		 * Special case - first read from first page.
+		 * Special case - first read.
 		 * We'll assume it's a whole-file read, and
 		 * grow the window fast.
 		 */
+		first_access=1;
 		ra->next_size = max / 2;
 		goto do_io;
 	}
 
+	preoffset = ra->prev_page;
 	ra->prev_page = offset;
 
 	if (offset >= ra->start && offset <= (ra->start + ra->size)) {
@@ -439,20 +443,45 @@ do_io:
 		 * ahead window and get some I/O underway for the new
 		 * current window.
 		 */
+		if (!first_access && preoffset >= ra->start &&
+				preoffset < (ra->start + ra->size)) {
+			 /* Heuristic:  If 'n' pages were
+			  * accessed in the current window, there
+			  * is a high probability that around 'n' pages
+			  * shall be used in the next current window.
+			  *
+			  * To minimize lazy-readahead triggered
+			  * in the next current window, read in
+			  * an extra page.
+			  */
+			ra->size = preoffset - ra->start + 2;
+		} else {
+			ra->size = ra->next_size;
+		}
 		ra->start = offset;
-		ra->size = ra->next_size;
 		ra->ahead_start = 0;		/* Invalidate these */
 		ra->ahead_size = 0;
 		actual = do_page_cache_readahead(mapping, filp, offset,
 						 ra->size);
-		check_ra_success(ra, ra->size, actual, orig_next_size);
+		if(!first_access) {
+			/*
+			 * do not adjust the readahead window size the first
+			 * time, the ahead window might get closed if all
+			 * the pages are already in the cache.
+			 */
+			check_ra_success(ra, ra->size, actual, orig_next_size);
+		}
 	} else {
 		/*
 		 * This read request is within the current window.  It is time
 		 * to submit I/O for the ahead window while the application is
-		 * crunching through the current window.
+		 * about to step into the ahead window.
+		 * Heuristic: Defer reading the ahead window till we hit
+		 * the last page in the current window. (lazy readahead)
+		 * If we read in earlier we run the risk of wasting
+		 * the ahead window.
 		 */
-		if (ra->ahead_start == 0) {
+		if (ra->ahead_start == 0 && offset == (ra->start + ra->size -1)) {
 			ra->ahead_start = ra->start + ra->size;
 			ra->ahead_size = ra->next_size;
 			actual = do_page_cache_readahead(mapping, filp,
@@ -488,7 +517,7 @@ void handle_ra_miss(struct address_space
 		const unsigned long max = get_max_readahead(ra);
 
 		if (offset != ra->prev_page + 1) {
-			ra->size = 0;			/* Not sequential */
+			ra->size = ra->size?ra->size-1:0; /* Not sequential */
 		} else {
 			ra->size++;			/* A sequential read */
 			if (ra->size >= max) {		/* Resume readahead */