From: Wu Fengguang In do_generic_mapping_read(), release accessed pages some time later, so that it can be passed to and used by the adaptive read-ahead code. Signed-off-by: Wu Fengguang Signed-off-by: Andrew Morton --- mm/filemap.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff -puN mm/filemap.c~readahead-delay-page-release-in-do_generic_mapping_read mm/filemap.c --- a/mm/filemap.c~readahead-delay-page-release-in-do_generic_mapping_read +++ a/mm/filemap.c @@ -953,10 +953,12 @@ void do_generic_mapping_read(struct addr unsigned long prev_index; loff_t isize; struct page *cached_page; + struct page *prev_page; int error; struct file_ra_state ra = *_ra; cached_page = NULL; + prev_page = NULL; index = *ppos >> PAGE_CACHE_SHIFT; next_index = index; prev_index = ra.prev_page; @@ -995,6 +997,11 @@ find_page: handle_ra_miss(mapping, &ra, index); goto no_cached_page; } + + if (prev_page) + page_cache_release(prev_page); + prev_page = page; + if (!PageUptodate(page)) goto page_not_up_to_date; page_ok: @@ -1029,7 +1036,6 @@ page_ok: index += offset >> PAGE_CACHE_SHIFT; offset &= ~PAGE_CACHE_MASK; - page_cache_release(page); if (ret == nr && desc->count) continue; goto out; @@ -1041,7 +1047,6 @@ page_not_up_to_date: /* Did it get truncated before we got the lock? */ if (!page->mapping) { unlock_page(page); - page_cache_release(page); continue; } @@ -1071,7 +1076,6 @@ readpage: * invalidate_inode_pages got it */ unlock_page(page); - page_cache_release(page); goto find_page; } unlock_page(page); @@ -1093,7 +1097,6 @@ readpage: isize = i_size_read(inode); end_index = (isize - 1) >> PAGE_CACHE_SHIFT; if (unlikely(!isize || index > end_index)) { - page_cache_release(page); goto out; } @@ -1102,7 +1105,6 @@ readpage: if (index == end_index) { nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1; if (nr <= offset) { - page_cache_release(page); goto out; } } @@ -1112,7 +1114,6 @@ readpage: readpage_error: /* UHHUH! A synchronous read error occurred. Report it */ desc->error = error; - page_cache_release(page); goto out; no_cached_page: @@ -1137,6 +1138,9 @@ no_cached_page: } page = cached_page; cached_page = NULL; + if (prev_page) + page_cache_release(prev_page); + prev_page = page; goto readpage; } @@ -1146,6 +1150,8 @@ out: *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; if (cached_page) page_cache_release(cached_page); + if (prev_page) + page_cache_release(prev_page); if (filp) file_accessed(filp); } _