lkml.org 
[lkml]   [2018]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 012/107] make sure that __dentry_kill() always invalidates d_seq, unhashed or not
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

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

    From: Al Viro <viro@zeniv.linux.org.uk>

    commit 4c0d7cd5c8416b1ef41534d19163cb07ffaa03ab upstream.

    RCU pathwalk relies upon the assumption that anything that changes
    ->d_inode of a dentry will invalidate its ->d_seq. That's almost
    true - the one exception is that the final dput() of already unhashed
    dentry does *not* touch ->d_seq at all. Unhashing does, though,
    so for anything we'd found by RCU dcache lookup we are fine.
    Unfortunately, we can *start* with an unhashed dentry or jump into
    it.

    We could try and be careful in the (few) places where that could
    happen. Or we could just make the final dput() invalidate the damn
    thing, unhashed or not. The latter is much simpler and easier to
    backport, so let's do it that way.

    Reported-by: "Dae R. Jeong" <threeearcat@gmail.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/dcache.c | 7 ++-----
    1 file changed, 2 insertions(+), 5 deletions(-)

    --- a/fs/dcache.c
    +++ b/fs/dcache.c
    @@ -352,14 +352,11 @@ static void dentry_unlink_inode(struct d
    __releases(dentry->d_inode->i_lock)
    {
    struct inode *inode = dentry->d_inode;
    - bool hashed = !d_unhashed(dentry);

    - if (hashed)
    - raw_write_seqcount_begin(&dentry->d_seq);
    + raw_write_seqcount_begin(&dentry->d_seq);
    __d_clear_type_and_inode(dentry);
    hlist_del_init(&dentry->d_u.d_alias);
    - if (hashed)
    - raw_write_seqcount_end(&dentry->d_seq);
    + raw_write_seqcount_end(&dentry->d_seq);
    spin_unlock(&dentry->d_lock);
    spin_unlock(&inode->i_lock);
    if (!inode->i_nlink)

    \
     
     \ /
      Last update: 2018-08-14 19:58    [W:4.163 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site