lkml.org 
[lkml]   [2015]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 090/110] namei: lift terminate_walk() all the way up
    Date
    From: Al Viro <viro@zeniv.linux.org.uk>

    Lift it from link_path_walk(), trailing_symlink(), lookup_last(),
    mountpoint_last(), complete_walk() and do_last(). A _lot_ of
    those suckers merge.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    ---
    fs/namei.c | 106 ++++++++++++++++++++-----------------------------------------
    1 file changed, 34 insertions(+), 72 deletions(-)

    diff --git a/fs/namei.c b/fs/namei.c
    index 46f4266..27c3859 100644
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -563,8 +563,6 @@ static inline int nd_alloc_stack(struct nameidata *nd)
    * to restart the path walk from the beginning in ref-walk mode.
    */

    -static void terminate_walk(struct nameidata *nd);
    -
    /**
    * unlazy_walk - try to switch to ref-walk mode.
    * @nd: nameidata pathwalk data
    @@ -673,10 +671,8 @@ static int complete_walk(struct nameidata *nd)
    if (nd->flags & LOOKUP_RCU) {
    if (!(nd->flags & LOOKUP_ROOT))
    nd->root.mnt = NULL;
    - if (unlikely(unlazy_walk(nd, NULL))) {
    - terminate_walk(nd);
    + if (unlikely(unlazy_walk(nd, NULL)))
    return -ECHILD;
    - }
    }

    if (likely(!(nd->flags & LOOKUP_JUMPED)))
    @@ -692,7 +688,6 @@ static int complete_walk(struct nameidata *nd)
    if (!status)
    status = -ESTALE;

    - terminate_walk(nd);
    return status;
    }

    @@ -1858,7 +1853,6 @@ OK:
    break;
    }
    }
    - terminate_walk(nd);
    return err;
    }

    @@ -1974,38 +1968,26 @@ static const char *trailing_symlink(struct nameidata *nd)
    {
    const char *s;
    int error = may_follow_link(nd);
    - if (unlikely(error)) {
    - terminate_walk(nd);
    + if (unlikely(error))
    return ERR_PTR(error);
    - }
    nd->flags |= LOOKUP_PARENT;
    nd->stack[0].name = NULL;
    s = get_link(nd);
    - if (unlikely(IS_ERR(s))) {
    - terminate_walk(nd);
    - return s;
    - }
    - if (unlikely(!s))
    - s = "";
    - return s;
    + return s ? s : "";
    }

    static inline int lookup_last(struct nameidata *nd)
    {
    - int err;
    if (nd->last_type == LAST_NORM && nd->last.name[nd->last.len])
    nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;

    nd->flags &= ~LOOKUP_PARENT;
    - err = walk_component(nd,
    + return walk_component(nd,
    nd->flags & LOOKUP_FOLLOW
    ? nd->depth
    ? WALK_PUT | WALK_GET
    : WALK_GET
    : 0);
    - if (err < 0)
    - terminate_walk(nd);
    - return err;
    }

    /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
    @@ -2025,16 +2007,14 @@ static int path_lookupat(int dfd, const struct filename *name,
    break;
    }
    }
    -
    if (!err)
    err = complete_walk(nd);

    - if (!err && nd->flags & LOOKUP_DIRECTORY) {
    - if (!d_can_lookup(nd->path.dentry)) {
    - path_put(&nd->path);
    + if (!err && nd->flags & LOOKUP_DIRECTORY)
    + if (!d_can_lookup(nd->path.dentry))
    err = -ENOTDIR;
    - }
    - }
    + if (err)
    + terminate_walk(nd);

    path_cleanup(nd);
    return err;
    @@ -2069,6 +2049,8 @@ static int path_parentat(int dfd, const struct filename *name,
    err = link_path_walk(s, nd);
    if (!err)
    err = complete_walk(nd);
    + if (err)
    + terminate_walk(nd);
    path_cleanup(nd);
    return err;
    }
    @@ -2320,10 +2302,8 @@ mountpoint_last(struct nameidata *nd, struct path *path)

    /* If we're in rcuwalk, drop out of it to handle last component */
    if (nd->flags & LOOKUP_RCU) {
    - if (unlazy_walk(nd, NULL)) {
    - error = -ECHILD;
    - goto out;
    - }
    + if (unlazy_walk(nd, NULL))
    + return -ECHILD;
    }

    nd->flags &= ~LOOKUP_PARENT;
    @@ -2331,7 +2311,7 @@ mountpoint_last(struct nameidata *nd, struct path *path)
    if (unlikely(nd->last_type != LAST_NORM)) {
    error = handle_dots(nd, nd->last_type);
    if (error)
    - goto out;
    + return error;
    dentry = dget(nd->path.dentry);
    goto done;
    }
    @@ -2346,41 +2326,32 @@ mountpoint_last(struct nameidata *nd, struct path *path)
    */
    dentry = d_alloc(dir, &nd->last);
    if (!dentry) {
    - error = -ENOMEM;
    mutex_unlock(&dir->d_inode->i_mutex);
    - goto out;
    + return -ENOMEM;
    }
    dentry = lookup_real(dir->d_inode, dentry, nd->flags);
    - error = PTR_ERR(dentry);
    if (IS_ERR(dentry)) {
    mutex_unlock(&dir->d_inode->i_mutex);
    - goto out;
    + return PTR_ERR(dentry);
    }
    }
    mutex_unlock(&dir->d_inode->i_mutex);

    done:
    if (d_is_negative(dentry)) {
    - error = -ENOENT;
    dput(dentry);
    - goto out;
    + return -ENOENT;
    }
    if (nd->depth)
    put_link(nd);
    path->dentry = dentry;
    path->mnt = nd->path.mnt;
    error = should_follow_link(nd, path, nd->flags & LOOKUP_FOLLOW);
    - if (unlikely(error)) {
    - if (error < 0)
    - goto out;
    + if (unlikely(error))
    return error;
    - }
    mntget(path->mnt);
    follow_mount(path);
    - error = 0;
    -out:
    - terminate_walk(nd);
    - return error;
    + return 0;
    }

    /**
    @@ -2409,6 +2380,7 @@ path_mountpoint(int dfd, const struct filename *name, struct path *path,
    break;
    }
    }
    + terminate_walk(nd);
    path_cleanup(nd);
    return err;
    }
    @@ -2982,10 +2954,8 @@ static int do_last(struct nameidata *nd,

    if (nd->last_type != LAST_NORM) {
    error = handle_dots(nd, nd->last_type);
    - if (unlikely(error)) {
    - terminate_walk(nd);
    + if (unlikely(error))
    return error;
    - }
    goto finish_open;
    }

    @@ -2998,7 +2968,7 @@ static int do_last(struct nameidata *nd,
    goto finish_lookup;

    if (error < 0)
    - goto out;
    + return error;

    BUG_ON(nd->inode != dir->d_inode);
    } else {
    @@ -3013,10 +2983,9 @@ static int do_last(struct nameidata *nd,
    return error;

    audit_inode(name, dir, LOOKUP_PARENT);
    - error = -EISDIR;
    /* trailing slashes? */
    - if (nd->last.name[nd->last.len])
    - goto out;
    + if (unlikely(nd->last.name[nd->last.len]))
    + return -EISDIR;
    }

    retry_lookup:
    @@ -3071,35 +3040,31 @@ retry_lookup:
    got_write = false;
    }

    - error = -EEXIST;
    - if ((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))
    - goto exit_dput;
    + if (unlikely((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) {
    + path_to_nameidata(&path, nd);
    + return -EEXIST;
    + }

    error = follow_managed(&path, nd);
    - if (error < 0)
    - goto out;
    + if (unlikely(error < 0))
    + return error;

    BUG_ON(nd->flags & LOOKUP_RCU);
    inode = path.dentry->d_inode;
    - error = -ENOENT;
    - if (d_is_negative(path.dentry)) {
    + if (unlikely(d_is_negative(path.dentry))) {
    path_to_nameidata(&path, nd);
    - goto out;
    + return -ENOENT;
    }
    finish_lookup:
    if (nd->depth)
    put_link(nd);
    error = should_follow_link(nd, &path, nd->flags & LOOKUP_FOLLOW);
    - if (unlikely(error)) {
    - if (error < 0)
    - goto out;
    + if (unlikely(error))
    return error;
    - }

    if (unlikely(d_is_symlink(path.dentry)) && !(open_flag & O_PATH)) {
    path_to_nameidata(&path, nd);
    - error = -ELOOP;
    - goto out;
    + return -ELOOP;
    }

    if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path.mnt) {
    @@ -3165,12 +3130,8 @@ out:
    if (got_write)
    mnt_drop_write(nd->path.mnt);
    path_put(&save_parent);
    - terminate_walk(nd);
    return error;

    -exit_dput:
    - path_put_conditional(&path, nd);
    - goto out;
    exit_fput:
    fput(file);
    goto out;
    @@ -3289,6 +3250,7 @@ static struct file *path_openat(int dfd, struct filename *pathname,
    break;
    }
    }
    + terminate_walk(nd);
    path_cleanup(nd);
    out2:
    if (!(opened & FILE_OPENED)) {
    --
    2.1.4


    \
     
     \ /
      Last update: 2015-05-11 20:41    [W:3.700 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site