Commit ebf43500ef148a380bd132743c3fc530111ac620

Authored by Jens Axboe
Committed by Jens Axboe
1 parent eb645a24de

[PATCH] Add find_get_pages_contig(): contiguous variant of find_get_pages()

find_get_pages_contig() will break out if we hit a hole in the page cache.
From Andrew Morton, small modifications and documentation by me.

Signed-off-by: Jens Axboe <axboe@suse.de>

Showing 2 changed files with 34 additions and 0 deletions Side-by-side Diff

include/linux/pagemap.h
... ... @@ -78,6 +78,8 @@
78 78 unsigned long index, gfp_t gfp_mask);
79 79 unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
80 80 unsigned int nr_pages, struct page **pages);
  81 +unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
  82 + unsigned int nr_pages, struct page **pages);
81 83 unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
82 84 int tag, unsigned int nr_pages, struct page **pages);
83 85  
... ... @@ -697,6 +697,38 @@
697 697 return ret;
698 698 }
699 699  
  700 +/**
  701 + * find_get_pages_contig - gang contiguous pagecache lookup
  702 + * @mapping: The address_space to search
  703 + * @index: The starting page index
  704 + * @nr_pages: The maximum number of pages
  705 + * @pages: Where the resulting pages are placed
  706 + *
  707 + * find_get_pages_contig() works exactly like find_get_pages(), except
  708 + * that the returned number of pages are guaranteed to be contiguous.
  709 + *
  710 + * find_get_pages_contig() returns the number of pages which were found.
  711 + */
  712 +unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
  713 + unsigned int nr_pages, struct page **pages)
  714 +{
  715 + unsigned int i;
  716 + unsigned int ret;
  717 +
  718 + read_lock_irq(&mapping->tree_lock);
  719 + ret = radix_tree_gang_lookup(&mapping->page_tree,
  720 + (void **)pages, index, nr_pages);
  721 + for (i = 0; i < ret; i++) {
  722 + if (pages[i]->mapping == NULL || pages[i]->index != index)
  723 + break;
  724 +
  725 + page_cache_get(pages[i]);
  726 + index++;
  727 + }
  728 + read_unlock_irq(&mapping->tree_lock);
  729 + return i;
  730 +}
  731 +
700 732 /*
701 733 * Like find_get_pages, except we only return pages which are tagged with
702 734 * `tag'. We update *index to index the next page for the traversal.