lkml.org 
[lkml]   [2019]   [Aug]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 073/157] sunrpc: don't mark uninitialised items as VALID.
    3.16.72-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: NeilBrown <neilb@suse.com>

    commit d58431eacb226222430940134d97bfd72f292fcd upstream.

    A recent commit added a call to cache_fresh_locked()
    when an expired item was found.
    The call sets the CACHE_VALID flag, so it is important
    that the item actually is valid.
    There are two ways it could be valid:
    1/ If ->update has been called to fill in relevant content
    2/ if CACHE_NEGATIVE is set, to say that content doesn't exist.

    An expired item that is waiting for an update will be neither.
    Setting CACHE_VALID will mean that a subsequent call to cache_put()
    will be likely to dereference uninitialised pointers.

    So we must make sure the item is valid, and we already have code to do
    that in try_to_negate_entry(). This takes the hash lock and so cannot
    be used directly, so take out the two lines that we need and use them.

    Now cache_fresh_locked() is certain to be called only on
    a valid item.

    Fixes: 4ecd55ea0742 ("sunrpc: fix cache_head leak due to queued request")
    Signed-off-by: NeilBrown <neilb@suse.com>
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    [bwh: Backported to 3.16: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    net/sunrpc/cache.c | 3 +++
    1 file changed, 3 insertions(+)

    --- a/net/sunrpc/cache.c
    +++ b/net/sunrpc/cache.c
    @@ -50,6 +50,7 @@ static void cache_init(struct cache_head
    h->last_refresh = now;
    }

    +static inline int cache_is_valid(struct cache_head *h);
    static void cache_fresh_locked(struct cache_head *head, time_t expiry);
    static void cache_fresh_unlocked(struct cache_head *head,
    struct cache_detail *detail);
    @@ -98,6 +99,8 @@ struct cache_head *sunrpc_cache_lookup(s
    *hp = tmp->next;
    tmp->next = NULL;
    detail->entries --;
    + if (cache_is_valid(tmp) == -EAGAIN)
    + set_bit(CACHE_NEGATIVE, &tmp->flags);
    cache_fresh_locked(tmp, 0);
    freeme = tmp;
    break;
    \
     
     \ /
      Last update: 2019-08-10 22:46    [W:3.390 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site