aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/readahead.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/mm/readahead.c b/mm/readahead.c
index 4a58befbde4a..fd588ffc5086 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -380,6 +380,29 @@ ondemand_readahead(struct address_space *mapping,
380 } 380 }
381 381
382 /* 382 /*
383 * Hit a marked page without valid readahead state.
384 * E.g. interleaved reads.
385 * Query the pagecache for async_size, which normally equals to
386 * readahead size. Ramp it up and use it as the new readahead size.
387 */
388 if (hit_readahead_marker) {
389 pgoff_t start;
390
391 read_lock_irq(&mapping->tree_lock);
392 start = radix_tree_next_hole(&mapping->page_tree, offset, max+1);
393 read_unlock_irq(&mapping->tree_lock);
394
395 if (!start || start - offset > max)
396 return 0;
397
398 ra->start = start;
399 ra->size = start - offset; /* old async_size */
400 ra->size = get_next_ra_size(ra, max);
401 ra->async_size = ra->size;
402 goto readit;
403 }
404
405 /*
383 * It may be one of 406 * It may be one of
384 * - first read on start of file 407 * - first read on start of file
385 * - sequential cache miss 408 * - sequential cache miss
@@ -390,16 +413,6 @@ ondemand_readahead(struct address_space *mapping,
390 ra->size = get_init_ra_size(req_size, max); 413 ra->size = get_init_ra_size(req_size, max);
391 ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size; 414 ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;
392 415
393 /*
394 * Hit on a marked page without valid readahead state.
395 * E.g. interleaved reads.
396 * Not knowing its readahead pos/size, bet on the minimal possible one.
397 */
398 if (hit_readahead_marker) {
399 ra->start++;
400 ra->size = get_next_ra_size(ra, max);
401 }
402
403readit: 416readit:
404 return ra_submit(ra, mapping, filp); 417 return ra_submit(ra, mapping, filp);
405} 418}