readahead: remove sync/async readahead call dependency
[sfrench/cifs-2.6.git] / mm / readahead.c
index 133b6d525513a886247ce3adc5eff41ef4e91752..d7c6e143a1297fc4866b18b28f04be2f9aaf2ecb 100644 (file)
@@ -210,6 +210,7 @@ int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
        if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages))
                return -EINVAL;
 
+       nr_to_read = max_sane_readahead(nr_to_read);
        while (nr_to_read) {
                int err;
 
@@ -356,7 +357,7 @@ ondemand_readahead(struct address_space *mapping,
                   bool hit_readahead_marker, pgoff_t offset,
                   unsigned long req_size)
 {
-       int     max = ra->ra_pages;     /* max readahead pages */
+       unsigned long max = max_sane_readahead(ra->ra_pages);
        pgoff_t prev_offset;
        int     sequential;
 
@@ -394,7 +395,7 @@ ondemand_readahead(struct address_space *mapping,
                pgoff_t start;
 
                rcu_read_lock();
-               start = radix_tree_next_hole(&mapping->page_tree, offset,max+1);
+               start = radix_tree_next_hole(&mapping->page_tree, offset+1,max);
                rcu_read_unlock();
 
                if (!start || start - offset > max)
@@ -402,6 +403,7 @@ ondemand_readahead(struct address_space *mapping,
 
                ra->start = start;
                ra->size = start - offset;      /* old async_size */
+               ra->size += req_size;
                ra->size = get_next_ra_size(ra, max);
                ra->async_size = ra->size;
                goto readit;
@@ -419,6 +421,16 @@ ondemand_readahead(struct address_space *mapping,
        ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;
 
 readit:
+       /*
+        * Will this read hit the readahead marker made by itself?
+        * If so, trigger the readahead marker hit now, and merge
+        * the resulted next readahead window into the current one.
+        */
+       if (offset == ra->start && ra->size == ra->async_size) {
+               ra->async_size = get_next_ra_size(ra, max);
+               ra->size += ra->async_size;
+       }
+
        return ra_submit(ra, mapping, filp);
 }