lkml.org 
[lkml]   [2011]   [Jul]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH] vfs: fix race in rcu lookup of pruned dentry
    On Sun, Jul 17, 2011 at 03:00:06PM -0700, Linus Torvalds wrote:

    > Yes. However, looking at it, I'm not very happy with your patch. It
    > doesn't really make sense to me to special-case the NULL inode and
    > only do a seq_retry for that case.
    >
    > I kind of see why you do it for that particular bug, but at the same
    > time, it just makes me go "Eww". If that inode isn't NULL yet, you
    > then return the dentry that can get a NULL d_inode later. So the only
    > special thing there is that we happen to check for a NULL inode there.
    > What protects *later* checks for a NULL d_inode?
    >
    > So my gut feel is that we should instead
    >
    > - either remove the -ENOENT return at that point entirely, and move
    > it to after we have re-verified the dentry lookup for other reasons.
    > That looks pretty involved, though, and those paths do end up
    > accessing inode data structures etc, so it looks less than trivial.
    >
    > OR
    >
    > - simply just not clear d_inode at all in d_kill(), so that when we
    > prune a dentry due to memory pressure, it doesn't actually change the
    > state of the dentry.

    OR

    - keep part of the patch from Hugh, treating negative in RCU mode as
    "need to unlazy". Leaving everything else as-is. Normally we'll
    confirm that sucker is negative and that'll be it. Or we'll see that
    it's being evicted and fall back to non-lazy mode, which is what we'll
    need to do anyway. IOW, this:

    diff --git a/fs/namei.c b/fs/namei.c
    index 5c867dd..48a38de 100644
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -1171,6 +1171,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
    path->dentry = dentry;
    if (unlikely(!__follow_mount_rcu(nd, path, inode)))
    goto unlazy;
    + if (unlikely(!*inode))
    + goto unlazy;
    if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT))
    goto unlazy;
    return 0;

    \
     
     \ /
      Last update: 2011-07-18 01:19    [W:0.026 / U:0.044 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site