[PATCH 3/6] vfs: add __d_instantiate() helper - Kernel

This is a discussion on [PATCH 3/6] vfs: add __d_instantiate() helper - Kernel ; This adds __d_instantiate() for users which is already taking dcache_lock, and replace with it. The part of d_add_ci() isn't equivalent. But it should be needed fsnotify_d_instantiate() actually, because the path is to add the inode to negative dentry. fsnotify_d_instantiate() should ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: [PATCH 3/6] vfs: add __d_instantiate() helper

  1. [PATCH 3/6] vfs: add __d_instantiate() helper


    This adds __d_instantiate() for users which is already taking
    dcache_lock, and replace with it.

    The part of d_add_ci() isn't equivalent. But it should be needed
    fsnotify_d_instantiate() actually, because the path is to add the
    inode to negative dentry. fsnotify_d_instantiate() should be called
    after change from negative to positive.

    __d_instantiate_unique() and d_materialise_unique() does opencoded
    optimized version. From history, it seems a intent, so just add comment.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/dcache.c | 29 ++++++++++++++++-------------
    1 file changed, 16 insertions(+), 13 deletions(-)

    diff -puN fs/dcache.c~dcache-cleanup-3 fs/dcache.c
    --- linux-2.6/fs/dcache.c~dcache-cleanup-3 2008-09-30 05:24:37.000000000 +0900
    +++ linux-2.6-hirofumi/fs/dcache.c 2008-09-30 05:24:37.000000000 +0900
    @@ -981,6 +981,15 @@ struct dentry *d_alloc_name(struct dentr
    return d_alloc(parent, &q);
    }

    +/* the caller must hold dcache_lock */
    +static void __d_instantiate(struct dentry *dentry, struct inode *inode)
    +{
    + if (inode)
    + list_add(&dentry->d_alias, &inode->i_dentry);
    + dentry->d_inode = inode;
    + fsnotify_d_instantiate(dentry, inode);
    +}
    +
    /**
    * d_instantiate - fill in inode information for a dentry
    * @entry: dentry to complete
    @@ -1000,10 +1009,7 @@ void d_instantiate(struct dentry *entry,
    {
    BUG_ON(!list_empty(&entry->d_alias));
    spin_lock(&dcache_lock);
    - if (inode)
    - list_add(&entry->d_alias, &inode->i_dentry);
    - entry->d_inode = inode;
    - fsnotify_d_instantiate(entry, inode);
    + __d_instantiate(entry, inode);
    spin_unlock(&dcache_lock);
    security_d_instantiate(entry, inode);
    }
    @@ -1033,6 +1039,7 @@ static struct dentry *__d_instantiate_un
    unsigned int hash = entry->d_name.hash;

    if (!inode) {
    + /* __d_instantiate() by hand */
    entry->d_inode = NULL;
    return NULL;
    }
    @@ -1052,9 +1059,7 @@ static struct dentry *__d_instantiate_un
    return alias;
    }

    - list_add(&entry->d_alias, &inode->i_dentry);
    - entry->d_inode = inode;
    - fsnotify_d_instantiate(entry, inode);
    + __d_instantiate(entry, inode);
    return NULL;
    }

    @@ -1211,10 +1216,8 @@ struct dentry *d_splice_alias(struct ino
    d_move(new, dentry);
    iput(inode);
    } else {
    - /* d_instantiate takes dcache_lock, so we do it by hand */
    - list_add(&dentry->d_alias, &inode->i_dentry);
    - dentry->d_inode = inode;
    - fsnotify_d_instantiate(dentry, inode);
    + /* already taking dcache_lock, so d_add() by hand */
    + __d_instantiate(dentry, inode);
    spin_unlock(&dcache_lock);
    security_d_instantiate(dentry, inode);
    d_rehash(dentry);
    @@ -1297,8 +1300,7 @@ struct dentry *d_add_ci(struct dentry *d
    * d_instantiate() by hand because it takes dcache_lock which
    * we already hold.
    */
    - list_add(&found->d_alias, &inode->i_dentry);
    - found->d_inode = inode;
    + __d_instantiate(found, inode);
    spin_unlock(&dcache_lock);
    security_d_instantiate(found, inode);
    return found;
    @@ -1827,6 +1829,7 @@ struct dentry *d_materialise_unique(stru

    if (!inode) {
    actual = dentry;
    + /* __d_instantiate() by hand */
    dentry->d_inode = NULL;
    goto found_lock;
    }
    _
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. [PATCH 5/6] vfs: remove LOOKUP_PARENT from non LOOKUP_PARENT lookup


    lookup_hash() with LOOKUP_PARENT is bogus. And this prepares to add
    new intent on those path.

    The user of LOOKUP_PARENT intent is nfs only, and it checks whether
    nd->flags has LOOKUP_CREATE or LOOKUP_OPEN, so the result is same.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/namei.c | 27 ++++++++++++++++++---------
    1 file changed, 18 insertions(+), 9 deletions(-)

    diff -puN fs/namei.c~dcache-remove-parent fs/namei.c
    --- linux-2.6/fs/namei.c~dcache-remove-parent 2008-08-26 11:13:30.000000000 +0900
    +++ linux-2.6-hirofumi/fs/namei.c 2008-08-26 11:13:30.000000000 +0900
    @@ -2176,16 +2176,19 @@ static long do_rmdir(int dfd, const char
    return error;

    switch(nd.last_type) {
    - case LAST_DOTDOT:
    - error = -ENOTEMPTY;
    - goto exit1;
    - case LAST_DOT:
    - error = -EINVAL;
    - goto exit1;
    - case LAST_ROOT:
    - error = -EBUSY;
    - goto exit1;
    + case LAST_DOTDOT:
    + error = -ENOTEMPTY;
    + goto exit1;
    + case LAST_DOT:
    + error = -EINVAL;
    + goto exit1;
    + case LAST_ROOT:
    + error = -EBUSY;
    + goto exit1;
    }
    +
    + nd.flags &= ~LOOKUP_PARENT;
    +
    mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    dentry = lookup_hash(&nd);
    error = PTR_ERR(dentry);
    @@ -2263,6 +2266,9 @@ static long do_unlinkat(int dfd, const c
    error = -EISDIR;
    if (nd.last_type != LAST_NORM)
    goto exit1;
    +
    + nd.flags &= ~LOOKUP_PARENT;
    +
    mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    dentry = lookup_hash(&nd);
    error = PTR_ERR(dentry);
    @@ -2652,6 +2658,9 @@ asmlinkage long sys_renameat(int olddfd,
    if (newnd.last_type != LAST_NORM)
    goto exit2;

    + oldnd.flags &= ~LOOKUP_PARENT;
    + newnd.flags &= ~LOOKUP_PARENT;
    +
    trap = lock_rename(new_dir, old_dir);

    old_dentry = lookup_hash(&oldnd);
    _
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. [PATCH 4/6] vfs: remove unnecessary fsnotify_d_instantiate()


    This calls d_move(), so fsnotify_d_instantiate() is unnecessary like
    rename path.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/dcache.c | 1 -
    1 file changed, 1 deletion(-)

    diff -puN fs/dcache.c~dcache-cleanup-4 fs/dcache.c
    --- linux-2.6/fs/dcache.c~dcache-cleanup-4 2008-08-26 11:13:29.000000000 +0900
    +++ linux-2.6-hirofumi/fs/dcache.c 2008-08-26 11:13:29.000000000 +0900
    @@ -1209,7 +1209,6 @@ struct dentry *d_splice_alias(struct ino
    new = __d_find_alias(inode, 1);
    if (new) {
    BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
    - fsnotify_d_instantiate(new, inode);
    spin_unlock(&dcache_lock);
    security_d_instantiate(new, inode);
    d_rehash(dentry);
    _
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread