Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1297606
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH v6 3/7] mm: add find_get_entries_tag() |
| Date | 2015-12-23 20:50 +0100 |
| Message-ID | <qIXA6-5kL-15@gated-at.bofh.it> (permalink) |
| References | <qIXqq-5hs-13@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
Add find_get_entries_tag() to the family of functions that include
find_get_entries(), find_get_pages() and find_get_pages_tag(). This is
needed for DAX dirty page handling because we need a list of both page
offsets and radix tree entries ('indices' and 'entries' in this function)
that are marked with the PAGECACHE_TAG_TOWRITE tag.
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---
include/linux/pagemap.h | 3 +++
mm/filemap.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 4d08b6c..92395a0 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -361,6 +361,9 @@ 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);
struct page *grab_cache_page_write_begin(struct address_space *mapping,
pgoff_t index, unsigned flags);
diff --git a/mm/filemap.c b/mm/filemap.c
index 7b8be78..1e215fc 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1499,6 +1499,74 @@ repeat:
}
EXPORT_SYMBOL(find_get_pages_tag);
+/**
+ * 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.
+ */
+unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
+ int tag, unsigned int nr_entries,
+ struct page **entries, pgoff_t *indices)
+{
+ void **slot;
+ unsigned int ret = 0;
+ struct radix_tree_iter iter;
+
+ if (!nr_entries)
+ return 0;
+
+ rcu_read_lock();
+restart:
+ radix_tree_for_each_tagged(slot, &mapping->page_tree,
+ &iter, start, tag) {
+ struct page *page;
+repeat:
+ page = radix_tree_deref_slot(slot);
+ if (unlikely(!page))
+ continue;
+ if (radix_tree_exception(page)) {
+ if (radix_tree_deref_retry(page)) {
+ /*
+ * Transient condition which can only trigger
+ * when entry at index 0 moves out of or back
+ * to root: none yet gotten, safe to restart.
+ */
+ goto restart;
+ }
+
+ /*
+ * A shadow entry of a recently evicted page, a swap
+ * entry from shmem/tmpfs or a DAX entry. Return it
+ * without attempting to raise page count.
+ */
+ goto export;
+ }
+ if (!page_cache_get_speculative(page))
+ goto repeat;
+
+ /* Has the page moved? */
+ if (unlikely(page != *slot)) {
+ page_cache_release(page);
+ goto repeat;
+ }
+export:
+ indices[ret] = iter.index;
+ entries[ret] = page;
+ if (++ret == nr_entries)
+ break;
+ }
+ rcu_read_unlock();
+ return ret;
+}
+EXPORT_SYMBOL(find_get_entries_tag);
+
/*
* CD/DVDs are error prone. When a medium error occurs, the driver may fail
* a _large_ part of the i/o request. Imagine the worst scenario:
--
2.6.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH v6 0/7] DAX fsync/msync support Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:40 +0100
[PATCH v6 6/7] ext4: call dax_pfn_mkwrite() for DAX fsync/msync Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:50 +0100
[PATCH v6 5/7] ext2: call dax_pfn_mkwrite() for DAX fsync/msync Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:50 +0100
[PATCH v6 7/7] xfs: call dax_pfn_mkwrite() for DAX fsync/msync Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:50 +0100
[PATCH v6 3/7] mm: add find_get_entries_tag() Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:50 +0100
RE: [PATCH v6 3/7] mm: add find_get_entries_tag() "Elliott, Robert (Persistent Memory)" <elliott@hpe.com> - 2015-12-24 01:30 +0100
[PATCH v6 2/7] dax: support dirty DAX entries in radix tree Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:50 +0100
Re: [PATCH v6 2/7] dax: support dirty DAX entries in radix tree Bob Liu <bob.liu@oracle.com> - 2015-12-30 09:10 +0100
Re: [PATCH v6 2/7] dax: support dirty DAX entries in radix tree Dan Williams <dan.j.williams@intel.com> - 2015-12-30 21:40 +0100
Re: [PATCH v6 2/7] dax: support dirty DAX entries in radix tree Bob Liu <bob.liu@oracle.com> - 2015-12-31 04:30 +0100
Re: [PATCH v6 2/7] dax: support dirty DAX entries in radix tree Dan Williams <dan.j.williams@intel.com> - 2015-12-31 23:10 +0100
[PATCH v6 4/7] dax: add support for fsync/msync Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-12-23 20:50 +0100
csiph-web