Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755343AbbEKSVL (ORCPT ); Mon, 11 May 2015 14:21:11 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:47406 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755014AbbEKSI0 (ORCPT ); Mon, 11 May 2015 14:08:26 -0400 From: Al Viro To: Linus Torvalds Cc: Neil Brown , Christoph Hellwig , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v3 079/110] namei: take the treatment of absolute symlinks to get_link() Date: Mon, 11 May 2015 19:07:39 +0100 Message-Id: <1431367690-5223-79-git-send-email-viro@ZenIV.linux.org.uk> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <20150511180650.GA4147@ZenIV.linux.org.uk> References: <20150511180650.GA4147@ZenIV.linux.org.uk> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2727 Lines: 105 From: Al Viro 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 --- 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 -- 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/