lkml.org 
[lkml]   [2018]   [May]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 7/8] rhashtable: add rhashtable_walk_prev()
    rhashtable_walk_prev() returns the object returned by
    the previous rhashtable_walk_next(), providing it is still in the
    table (or was during this grace period).
    This works even if rhashtable_walk_stop() and rhashtable_talk_start()
    have been called since the last rhashtable_walk_next().

    If there have been no calls to rhashtable_walk_next(), or if the
    object is gone from the table, then NULL is returned.

    This can usefully be used in a seq_file ->start() function.
    If the pos is the same as was returned by the last ->next() call,
    then rhashtable_walk_prev() can be used to re-establish the
    current location in the table. If it returns NULL, then
    rhashtable_walk_next() should be used.

    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
    include/linux/rhashtable.h | 1 +
    lib/rhashtable.c | 31 +++++++++++++++++++++++++++++++
    2 files changed, 32 insertions(+)

    diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
    index 20684a451cb0..82d061ff96d6 100644
    --- a/include/linux/rhashtable.h
    +++ b/include/linux/rhashtable.h
    @@ -367,6 +367,7 @@ static inline void rhashtable_walk_start(struct rhashtable_iter *iter)
    }

    void *rhashtable_walk_next(struct rhashtable_iter *iter);
    +void *rhashtable_walk_prev(struct rhashtable_iter *iter);
    void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU);

    void rhashtable_free_and_destroy(struct rhashtable *ht,
    diff --git a/lib/rhashtable.c b/lib/rhashtable.c
    index 038c4156b66a..d0267e37e7e1 100644
    --- a/lib/rhashtable.c
    +++ b/lib/rhashtable.c
    @@ -921,6 +921,37 @@ void *rhashtable_walk_next(struct rhashtable_iter *iter)
    }
    EXPORT_SYMBOL_GPL(rhashtable_walk_next);

    +/**
    + * rhashtable_walk_prev - Return the previously returned object, if available
    + * @iter: Hash table iterator
    + *
    + * If rhashtable_walk_next() has previously been called and the object
    + * it returned is still in the hash table, that object is returned again,
    + * otherwise %NULL is returned.
    + *
    + * If the recent rhashtable_walk_next() call was since the most recent
    + * rhashtable_walk_start() call then the returned object may not, strictly
    + * speaking, still be in the table. It will be safe to dereference.
    + *
    + * Note that the iterator is not changed and in particular it does not
    + * step backwards.
    + */
    +void *rhashtable_walk_prev(struct rhashtable_iter *iter)
    +{
    + struct rhashtable *ht = iter->ht;
    + struct rhash_head *p = iter->p;
    +
    + if (!p)
    + return NULL;
    + if (!iter->p_is_unsafe || ht->rhlist)
    + return p;
    + rht_for_each_rcu(p, iter->walker.tbl, iter->slot)
    + if (p == iter->p)
    + return p;
    + return NULL;
    +}
    +EXPORT_SYMBOL_GPL(rhashtable_walk_prev);
    +
    /**
    * rhashtable_walk_stop - Finish a hash table walk
    * @iter: Hash table iterator

    \
     
     \ /
      Last update: 2018-05-04 05:56    [W:3.736 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site