diff options
Diffstat (limited to 'mm/readahead.c')
| -rw-r--r-- | mm/readahead.c | 54 | 
1 files changed, 19 insertions, 35 deletions
diff --git a/mm/readahead.c b/mm/readahead.c index e4ed0414978..0ca36a7770b 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -8,9 +8,7 @@   */  #include <linux/kernel.h> -#include <linux/fs.h>  #include <linux/gfp.h> -#include <linux/mm.h>  #include <linux/export.h>  #include <linux/blkdev.h>  #include <linux/backing-dev.h> @@ -20,6 +18,8 @@  #include <linux/syscalls.h>  #include <linux/file.h> +#include "internal.h" +  /*   * Initialise a struct file's readahead state.  Assumes that the caller has   * memset *ra to zero. @@ -149,8 +149,7 @@ out:   *   * Returns the number of pages requested, or the maximum amount of I/O allowed.   */ -static int -__do_page_cache_readahead(struct address_space *mapping, struct file *filp, +int __do_page_cache_readahead(struct address_space *mapping, struct file *filp,  			pgoff_t offset, unsigned long nr_to_read,  			unsigned long lookahead_size)  { @@ -179,7 +178,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,  		rcu_read_lock();  		page = radix_tree_lookup(&mapping->page_tree, page_offset);  		rcu_read_unlock(); -		if (page) +		if (page && !radix_tree_exceptional_entry(page))  			continue;  		page = page_cache_alloc_readahead(mapping); @@ -211,8 +210,6 @@ out:  int force_page_cache_readahead(struct address_space *mapping, struct file *filp,  		pgoff_t offset, unsigned long nr_to_read)  { -	int ret = 0; -  	if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages))  		return -EINVAL; @@ -226,39 +223,23 @@ int force_page_cache_readahead(struct address_space *mapping, struct file *filp,  			this_chunk = nr_to_read;  		err = __do_page_cache_readahead(mapping, filp,  						offset, this_chunk, 0); -		if (err < 0) { -			ret = err; -			break; -		} -		ret += err; +		if (err < 0) +			return err; +  		offset += this_chunk;  		nr_to_read -= this_chunk;  	} -	return ret; +	return 0;  } +#define MAX_READAHEAD   ((512*4096)/PAGE_CACHE_SIZE)  /*   * Given a desired number of PAGE_CACHE_SIZE readahead pages, return a   * sensible upper limit.   */  unsigned long max_sane_readahead(unsigned long nr)  { -	return min(nr, (node_page_state(numa_node_id(), NR_INACTIVE_FILE) -		+ node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2); -} - -/* - * Submit IO for the read-ahead request in file_ra_state. - */ -unsigned long ra_submit(struct file_ra_state *ra, -		       struct address_space *mapping, struct file *filp) -{ -	int actual; - -	actual = __do_page_cache_readahead(mapping, filp, -					ra->start, ra->size, ra->async_size); - -	return actual; +	return min(nr, MAX_READAHEAD);  }  /* @@ -351,7 +332,7 @@ static pgoff_t count_history_pages(struct address_space *mapping,  	pgoff_t head;  	rcu_read_lock(); -	head = radix_tree_prev_hole(&mapping->page_tree, offset - 1, max); +	head = page_cache_prev_hole(mapping, offset - 1, max);  	rcu_read_unlock();  	return offset - 1 - head; @@ -401,6 +382,7 @@ ondemand_readahead(struct address_space *mapping,  		   unsigned long req_size)  {  	unsigned long max = max_sane_readahead(ra->ra_pages); +	pgoff_t prev_offset;  	/*  	 * start of file @@ -430,7 +412,7 @@ ondemand_readahead(struct address_space *mapping,  		pgoff_t start;  		rcu_read_lock(); -		start = radix_tree_next_hole(&mapping->page_tree, offset+1,max); +		start = page_cache_next_hole(mapping, offset + 1, max);  		rcu_read_unlock();  		if (!start || start - offset > max) @@ -452,8 +434,11 @@ ondemand_readahead(struct address_space *mapping,  	/*  	 * sequential cache miss +	 * trivial case: (offset - prev_offset) == 1 +	 * unaligned reads: (offset - prev_offset) == 0  	 */ -	if (offset - (ra->prev_pos >> PAGE_CACHE_SHIFT) <= 1UL) +	prev_offset = (unsigned long long)ra->prev_pos >> PAGE_CACHE_SHIFT; +	if (offset - prev_offset <= 1UL)  		goto initial_readahead;  	/* @@ -569,11 +554,10 @@ static ssize_t  do_readahead(struct address_space *mapping, struct file *filp,  	     pgoff_t index, unsigned long nr)  { -	if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage) +	if (!mapping || !mapping->a_ops)  		return -EINVAL; -	force_page_cache_readahead(mapping, filp, index, nr); -	return 0; +	return force_page_cache_readahead(mapping, filp, index, nr);  }  SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count)  | 
