lkml.org 
[lkml]   [2016]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 5/9] mm: add find_get_entries_tag()
    Date
    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.5.0


    \
     
     \ /
      Last update: 2016-01-06 19:21    [W:4.455 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site