]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/readahead.c
Merge branch 'for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
[karo-tx-linux.git] / mm / readahead.c
index c8a955b1297e0b60fb2efffdf3fc2bb71cfc4630..c4ca702392333288448cc7ae4ba6b410ddb93fef 100644 (file)
@@ -207,12 +207,21 @@ out:
  * memory at once.
  */
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
-               pgoff_t offset, unsigned long nr_to_read)
+                              pgoff_t offset, unsigned long nr_to_read)
 {
+       struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
+       struct file_ra_state *ra = &filp->f_ra;
+       unsigned long max_pages;
+
        if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages))
                return -EINVAL;
 
-       nr_to_read = min(nr_to_read, inode_to_bdi(mapping->host)->ra_pages);
+       /*
+        * If the request exceeds the readahead window, allow the read to
+        * be up to the optimal hardware IO size
+        */
+       max_pages = max_t(unsigned long, bdi->io_pages, ra->ra_pages);
+       nr_to_read = min(nr_to_read, max_pages);
        while (nr_to_read) {
                int err;
 
@@ -369,9 +378,17 @@ ondemand_readahead(struct address_space *mapping,
                   bool hit_readahead_marker, pgoff_t offset,
                   unsigned long req_size)
 {
-       unsigned long max = ra->ra_pages;
+       struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
+       unsigned long max_pages = ra->ra_pages;
        pgoff_t prev_offset;
 
+       /*
+        * If the request exceeds the readahead window, allow the read to
+        * be up to the optimal hardware IO size
+        */
+       if (req_size > max_pages && bdi->io_pages > max_pages)
+               max_pages = min(req_size, bdi->io_pages);
+
        /*
         * start of file
         */
@@ -385,7 +402,7 @@ ondemand_readahead(struct address_space *mapping,
        if ((offset == (ra->start + ra->size - ra->async_size) ||
             offset == (ra->start + ra->size))) {
                ra->start += ra->size;
-               ra->size = get_next_ra_size(ra, max);
+               ra->size = get_next_ra_size(ra, max_pages);
                ra->async_size = ra->size;
                goto readit;
        }
@@ -400,16 +417,16 @@ ondemand_readahead(struct address_space *mapping,
                pgoff_t start;
 
                rcu_read_lock();
-               start = page_cache_next_hole(mapping, offset + 1, max);
+               start = page_cache_next_hole(mapping, offset + 1, max_pages);
                rcu_read_unlock();
 
-               if (!start || start - offset > max)
+               if (!start || start - offset > max_pages)
                        return 0;
 
                ra->start = start;
                ra->size = start - offset;      /* old async_size */
                ra->size += req_size;
-               ra->size = get_next_ra_size(ra, max);
+               ra->size = get_next_ra_size(ra, max_pages);
                ra->async_size = ra->size;
                goto readit;
        }
@@ -417,7 +434,7 @@ ondemand_readahead(struct address_space *mapping,
        /*
         * oversize read
         */
-       if (req_size > max)
+       if (req_size > max_pages)
                goto initial_readahead;
 
        /*
@@ -433,7 +450,7 @@ ondemand_readahead(struct address_space *mapping,
         * Query the page cache and look for the traces(cached history pages)
         * that a sequential stream would leave behind.
         */
-       if (try_context_readahead(mapping, ra, offset, req_size, max))
+       if (try_context_readahead(mapping, ra, offset, req_size, max_pages))
                goto readit;
 
        /*
@@ -444,7 +461,7 @@ ondemand_readahead(struct address_space *mapping,
 
 initial_readahead:
        ra->start = offset;
-       ra->size = get_init_ra_size(req_size, max);
+       ra->size = get_init_ra_size(req_size, max_pages);
        ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;
 
 readit:
@@ -454,7 +471,7 @@ readit:
         * 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->async_size = get_next_ra_size(ra, max_pages);
                ra->size += ra->async_size;
        }