Commit ebf43500ef148a380bd132743c3fc530111ac620
Committed by
Jens Axboe
1 parent
eb645a24de
Exists in
master
and in
4 other branches
[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 |
mm/filemap.c
... | ... | @@ -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. |