Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1297606

[PATCH v6 3/7] mm: add find_get_entries_tag()

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

Show all headers | View raw


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 | NextPrevious in thread | Next in thread | Find similar | Unroll thread


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