summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/pagemap.h142
-rw-r--r--include/linux/radix-tree.h25
2 files changed, 142 insertions, 25 deletions
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 97354102794d..db8e15287ea0 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -324,18 +324,136 @@ static inline struct page *grab_cache_page_nowait(struct address_space *mapping,
struct page *find_get_entry(struct address_space *mapping, pgoff_t offset);
struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset);
-unsigned find_get_entries(struct address_space *mapping, pgoff_t start,
- unsigned int nr_entries, struct page **entries,
- pgoff_t *indices);
-unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
- unsigned int nr_pages, struct page **pages);
-unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
- unsigned int nr_pages, struct page **pages);
-unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
- int tag, unsigned int nr_pages, struct page **pages);
-unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
- int tag, unsigned int nr_entries,
- struct page **entries, pgoff_t *indices);
+
+unsigned __find_get_pages(struct address_space *mapping,
+ pgoff_t start, pgoff_t end,
+ unsigned nr_entries, struct page **entries,
+ pgoff_t *indices, unsigned flags);
+
+/**
+ * find_get_entries - gang pagecache lookup
+ * @mapping: The address_space to search
+ * @start: The starting page cache index
+ * @nr_entries: The maximum number of entries
+ * @entries: Where the resulting entries are placed
+ * @indices: The cache indices corresponding to the entries in @entries
+ *
+ * find_get_entries() will search for and return a group of up to
+ * @nr_entries entries in the mapping. The entries are placed at
+ * @entries. find_get_entries() takes a reference against any actual
+ * pages it returns.
+ *
+ * The search returns a group of mapping-contiguous page cache entries
+ * with ascending indexes. There may be holes in the indices due to
+ * not-present pages.
+ *
+ * Any shadow entries of evicted pages, or swap entries from
+ * shmem/tmpfs, are included in the returned array.
+ *
+ * find_get_entries() returns the number of pages and shadow entries
+ * which were found.
+ */
+static inline unsigned find_get_entries(struct address_space *mapping,
+ pgoff_t start, unsigned nr_entries,
+ struct page **entries, pgoff_t *indices)
+{
+ return __find_get_pages(mapping, start, ULONG_MAX,
+ nr_entries, entries, indices,
+ RADIX_TREE_ITER_EXCEPTIONAL);
+}
+
+/**
+ * find_get_pages - gang pagecache lookup
+ * @mapping: The address_space to search
+ * @start: The starting page index
+ * @nr_pages: The maximum number of pages
+ * @pages: Where the resulting pages are placed
+ *
+ * find_get_pages() will search for and return a group of up to
+ * @nr_pages pages in the mapping. The pages are placed at @pages.
+ * find_get_pages() takes a reference against the returned pages.
+ *
+ * The search returns a group of mapping-contiguous pages with ascending
+ * indexes. There may be holes in the indices due to not-present pages.
+ *
+ * find_get_pages() returns the number of pages which were found.
+ */
+static inline unsigned find_get_pages(struct address_space *mapping,
+ pgoff_t start, unsigned nr_pages,
+ struct page **pages)
+{
+ return __find_get_pages(mapping, start, ULONG_MAX,
+ nr_pages, pages, NULL, 0);
+}
+
+/**
+ * find_get_pages_contig - gang contiguous pagecache lookup
+ * @mapping: The address_space to search
+ * @start: The starting page index
+ * @nr_pages: The maximum number of pages
+ * @pages: Where the resulting pages are placed
+ *
+ * find_get_pages_contig() works exactly like find_get_pages(), except
+ * that the returned number of pages are guaranteed to be contiguous.
+ *
+ * find_get_pages_contig() returns the number of pages which were found.
+ */
+static inline unsigned find_get_pages_contig(struct address_space *mapping,
+ pgoff_t start, unsigned nr_pages,
+ struct page **pages)
+{
+ return __find_get_pages(mapping, start, ULONG_MAX,
+ nr_pages, pages, NULL,
+ RADIX_TREE_ITER_CONTIG);
+}
+
+/**
+ * find_get_pages_tag - find and return pages that match @tag
+ * @mapping: the address_space to search
+ * @index: the starting page index
+ * @tag: the tag index
+ * @nr_pages: the maximum number of pages
+ * @pages: where the resulting pages are placed
+ *
+ * Like find_get_pages, except we only return pages which are tagged with
+ * @tag. We update @index to index the next page for the traversal.
+ */
+static inline unsigned find_get_pages_tag(struct address_space *mapping,
+ pgoff_t *index, int tag,
+ unsigned nr_pages, struct page **pages)
+{
+ unsigned ret;
+
+ ret = __find_get_pages(mapping, *index, ULONG_MAX,
+ nr_pages, pages, NULL,
+ RADIX_TREE_ITER_TAGGED|tag);
+ if (ret)
+ *index = pages[ret - 1]->index + 1;
+
+ return ret;
+}
+
+/**
+ * find_get_entries_tag - find and return entries that match @tag
+ * @mapping: the address_space to search
+ * @start: the starting page cache index
+ * @tag: the tag index
+ * @nr_entries: the maximum number of entries
+ * @entries: where the resulting entries are placed
+ * @indices: the cache indices corresponding to the entries in @entries
+ *
+ * Like find_get_entries, except we only return entries which are tagged with
+ * @tag.
+ */
+static inline unsigned find_get_entries_tag(struct address_space *mapping,
+ pgoff_t start, int tag, unsigned nr_entries,
+ struct page **entries, pgoff_t *indices)
+{
+ return __find_get_pages(mapping, start, ULONG_MAX,
+ nr_entries, entries, indices,
+ RADIX_TREE_ITER_EXCEPTIONAL|
+ RADIX_TREE_ITER_TAGGED|tag);
+}
struct page *grab_cache_page_write_begin(struct address_space *mapping,
pgoff_t index, unsigned flags);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index eca6f626c16e..a83a42770f41 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -354,6 +354,8 @@ static inline unsigned int iter_shift(struct radix_tree_iter *iter)
#define RADIX_TREE_ITER_TAG_MASK 0x00FF /* tag index in lower byte */
#define RADIX_TREE_ITER_TAGGED 0x0100 /* lookup tagged slots */
#define RADIX_TREE_ITER_CONTIG 0x0200 /* stop at first hole */
+#define RADIX_TREE_ITER_EXCEPTIONAL 0x0400 /* include exceptional entries */
+ /* used by __find_get_pages() */
/**
* radix_tree_iter_init - initialize radix tree iterator
@@ -520,6 +522,11 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags)
return NULL;
}
+#define __radix_tree_for_each_slot(slot, root, iter, start, flags) \
+ for (slot = radix_tree_iter_init(iter, start) ; \
+ slot || (slot = radix_tree_next_chunk(root, iter, flags)); \
+ slot = radix_tree_next_slot(slot, iter, flags))
+
/**
* radix_tree_for_each_slot - iterate over non-empty slots
*
@@ -531,9 +538,7 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags)
* @slot points to radix tree slot, @iter->index contains its index.
*/
#define radix_tree_for_each_slot(slot, root, iter, start) \
- for (slot = radix_tree_iter_init(iter, start) ; \
- slot || (slot = radix_tree_next_chunk(root, iter, 0)) ; \
- slot = radix_tree_next_slot(slot, iter, 0))
+ __radix_tree_for_each_slot(slot, root, iter, start, 0)
/**
* radix_tree_for_each_contig - iterate over contiguous slots
@@ -546,11 +551,8 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags)
* @slot points to radix tree slot, @iter->index contains its index.
*/
#define radix_tree_for_each_contig(slot, root, iter, start) \
- for (slot = radix_tree_iter_init(iter, start) ; \
- slot || (slot = radix_tree_next_chunk(root, iter, \
- RADIX_TREE_ITER_CONTIG)) ; \
- slot = radix_tree_next_slot(slot, iter, \
- RADIX_TREE_ITER_CONTIG))
+ __radix_tree_for_each_slot(slot, root, iter, start, \
+ RADIX_TREE_ITER_CONTIG)
/**
* radix_tree_for_each_tagged - iterate over tagged slots
@@ -564,10 +566,7 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags)
* @slot points to radix tree slot, @iter->index contains its index.
*/
#define radix_tree_for_each_tagged(slot, root, iter, start, tag) \
- for (slot = radix_tree_iter_init(iter, start) ; \
- slot || (slot = radix_tree_next_chunk(root, iter, \
- RADIX_TREE_ITER_TAGGED | tag)) ; \
- slot = radix_tree_next_slot(slot, iter, \
- RADIX_TREE_ITER_TAGGED))
+ __radix_tree_for_each_slot(slot, root, iter, start, \
+ RADIX_TREE_ITER_TAGGED|tag)
#endif /* _LINUX_RADIX_TREE_H */