aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/fs.h1
-rw-r--r--mm/filemap.c9
-rw-r--r--mm/readahead.c3
3 files changed, 10 insertions, 3 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7c0077f06e24..0949e243b8b9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -702,6 +702,7 @@ struct file_ra_state {
702 unsigned long ra_pages; /* Maximum readahead window */ 702 unsigned long ra_pages; /* Maximum readahead window */
703 unsigned long mmap_hit; /* Cache hit stat for mmap accesses */ 703 unsigned long mmap_hit; /* Cache hit stat for mmap accesses */
704 unsigned long mmap_miss; /* Cache miss stat for mmap accesses */ 704 unsigned long mmap_miss; /* Cache miss stat for mmap accesses */
705 unsigned int offset; /* Offset where last read() ended in a page */
705}; 706};
706#define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */ 707#define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
707#define RA_FLAG_INCACHE 0x02 /* file is already in cache */ 708#define RA_FLAG_INCACHE 0x02 /* file is already in cache */
diff --git a/mm/filemap.c b/mm/filemap.c
index cbea95a25283..07f5b77114a3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -868,6 +868,7 @@ void do_generic_mapping_read(struct address_space *mapping,
868 unsigned long last_index; 868 unsigned long last_index;
869 unsigned long next_index; 869 unsigned long next_index;
870 unsigned long prev_index; 870 unsigned long prev_index;
871 unsigned int prev_offset;
871 loff_t isize; 872 loff_t isize;
872 struct page *cached_page; 873 struct page *cached_page;
873 int error; 874 int error;
@@ -877,6 +878,7 @@ void do_generic_mapping_read(struct address_space *mapping,
877 index = *ppos >> PAGE_CACHE_SHIFT; 878 index = *ppos >> PAGE_CACHE_SHIFT;
878 next_index = index; 879 next_index = index;
879 prev_index = ra.prev_page; 880 prev_index = ra.prev_page;
881 prev_offset = ra.offset;
880 last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; 882 last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
881 offset = *ppos & ~PAGE_CACHE_MASK; 883 offset = *ppos & ~PAGE_CACHE_MASK;
882 884
@@ -924,10 +926,10 @@ page_ok:
924 flush_dcache_page(page); 926 flush_dcache_page(page);
925 927
926 /* 928 /*
927 * When (part of) the same page is read multiple times 929 * When a sequential read accesses a page several times,
928 * in succession, only mark it as accessed the first time. 930 * only mark it as accessed the first time.
929 */ 931 */
930 if (prev_index != index) 932 if (prev_index != index || offset != prev_offset)
931 mark_page_accessed(page); 933 mark_page_accessed(page);
932 prev_index = index; 934 prev_index = index;
933 935
@@ -945,6 +947,7 @@ page_ok:
945 offset += ret; 947 offset += ret;
946 index += offset >> PAGE_CACHE_SHIFT; 948 index += offset >> PAGE_CACHE_SHIFT;
947 offset &= ~PAGE_CACHE_MASK; 949 offset &= ~PAGE_CACHE_MASK;
950 prev_offset = ra.offset = offset;
948 951
949 page_cache_release(page); 952 page_cache_release(page);
950 if (ret == nr && desc->count) 953 if (ret == nr && desc->count)
diff --git a/mm/readahead.c b/mm/readahead.c
index 93d9ee692fd8..0a6fed9d365c 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -207,6 +207,8 @@ out:
207 * If page_cache_readahead sees that it is again being called for 207 * If page_cache_readahead sees that it is again being called for
208 * a page which it just looked at, it can return immediately without 208 * a page which it just looked at, it can return immediately without
209 * making any state changes. 209 * making any state changes.
210 * offset: Offset in the prev_page where the last read ended - used for
211 * detection of sequential file reading.
210 * ahead_start, 212 * ahead_start,
211 * ahead_size: Together, these form the "ahead window". 213 * ahead_size: Together, these form the "ahead window".
212 * ra_pages: The externally controlled max readahead for this fd. 214 * ra_pages: The externally controlled max readahead for this fd.
@@ -473,6 +475,7 @@ page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
473 /* Note that prev_page == -1 if it is a first read */ 475 /* Note that prev_page == -1 if it is a first read */
474 sequential = (offset == ra->prev_page + 1); 476 sequential = (offset == ra->prev_page + 1);
475 ra->prev_page = offset; 477 ra->prev_page = offset;
478 ra->offset = 0;
476 479
477 max = get_max_readahead(ra); 480 max = get_max_readahead(ra);
478 newsize = min(req_size, max); 481 newsize = min(req_size, max);