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 079/110] namei: take the treatment of absolute symlinks to get_link()
    Date
    From: Al Viro <viro@zeniv.linux.org.uk>

    rather than letting the callers handle the jump-to-root part of
    semantics, do it right in get_link() and return the rest of the
    body for the caller to deal with - at that point it's treated
    the same way as relative symlinks would be. And return NULL
    when there's no "rest of the body" - those are treated the same
    as pure jump symlink would be.

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

    diff --git a/fs/namei.c b/fs/namei.c
    index c5eb77a..c6ff9da 100644
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -918,9 +918,24 @@ const char *get_link(struct nameidata *nd)
    res = inode->i_link;
    if (!res) {
    res = inode->i_op->follow_link(dentry, &last->cookie);
    - if (IS_ERR_OR_NULL(res))
    + if (IS_ERR_OR_NULL(res)) {
    last->cookie = NULL;
    + return res;
    + }
    + }
    + if (*res == '/') {
    + if (!nd->root.mnt)
    + set_root(nd);
    + path_put(&nd->path);
    + nd->path = nd->root;
    + path_get(&nd->root);
    + nd->inode = nd->path.dentry->d_inode;
    + nd->flags |= LOOKUP_JUMPED;
    + while (unlikely(*++res == '/'))
    + ;
    }
    + if (!*res)
    + res = NULL;
    return res;
    }

    @@ -1854,24 +1869,9 @@ OK:
    /* jumped */
    put_link(nd);
    } else {
    - if (*s == '/') {
    - if (!nd->root.mnt)
    - set_root(nd);
    - path_put(&nd->path);
    - nd->path = nd->root;
    - path_get(&nd->root);
    - nd->flags |= LOOKUP_JUMPED;
    - while (unlikely(*++s == '/'))
    - ;
    - }
    - nd->inode = nd->path.dentry->d_inode;
    - if (unlikely(!*s)) {
    - put_link(nd);
    - } else {
    - nd->stack[nd->depth - 1].name = name;
    - name = s;
    - continue;
    - }
    + nd->stack[nd->depth - 1].name = name;
    + name = s;
    + continue;
    }
    }
    if (!d_can_lookup(nd->path.dentry)) {
    @@ -2002,6 +2002,7 @@ static int trailing_symlink(struct nameidata *nd)
    if (unlikely(error))
    return error;
    nd->flags |= LOOKUP_PARENT;
    + nd->stack[0].name = NULL;
    s = get_link(nd);
    if (unlikely(IS_ERR(s))) {
    terminate_walk(nd);
    @@ -2009,16 +2010,6 @@ static int trailing_symlink(struct nameidata *nd)
    }
    if (unlikely(!s))
    return 0;
    - if (*s == '/') {
    - if (!nd->root.mnt)
    - set_root(nd);
    - path_put(&nd->path);
    - nd->path = nd->root;
    - path_get(&nd->root);
    - nd->flags |= LOOKUP_JUMPED;
    - }
    - nd->inode = nd->path.dentry->d_inode;
    - nd->stack[0].name = NULL;
    return link_path_walk(s, nd);
    }

    --
    2.1.4


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