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 089/110] namei: lift link_path_walk() call out of trailing_symlink()
Date
From: Al Viro <viro@zeniv.linux.org.uk>

Make trailing_symlink() return the pathname to traverse or ERR_PTR(-E...).
A subtle point is that for "magic" symlinks it returns "" now - that
leads to link_path_walk("", nd), which is immediately returning 0 and
we are back to the treatment of the last component, at whereever the
damn thing has left us.

Reduces the stack footprint - link_path_walk() called on more shallow
stack now.

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

diff --git a/fs/namei.c b/fs/namei.c
index 06c7120..46f4266 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1970,24 +1970,24 @@ static void path_cleanup(struct nameidata *nd)
}
}

-static int trailing_symlink(struct nameidata *nd)
+static const char *trailing_symlink(struct nameidata *nd)
{
const char *s;
int error = may_follow_link(nd);
if (unlikely(error)) {
terminate_walk(nd);
- return 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 PTR_ERR(s);
+ return s;
}
if (unlikely(!s))
- return 0;
- return link_path_walk(s, nd);
+ s = "";
+ return s;
}

static inline int lookup_last(struct nameidata *nd)
@@ -2017,12 +2017,12 @@ static int path_lookupat(int dfd, const struct filename *name,

if (IS_ERR(s))
return PTR_ERR(s);
- err = link_path_walk(s, nd);
- if (!err) {
- while ((err = lookup_last(nd)) > 0) {
- err = trailing_symlink(nd);
- if (err)
- break;
+ while (!(err = link_path_walk(s, nd))
+ && ((err = lookup_last(nd)) > 0)) {
+ s = trailing_symlink(nd);
+ if (IS_ERR(s)) {
+ err = PTR_ERR(s);
+ break;
}
}

@@ -2401,16 +2401,14 @@ path_mountpoint(int dfd, const struct filename *name, struct path *path,
int err;
if (IS_ERR(s))
return PTR_ERR(s);
- err = link_path_walk(s, nd);
- if (unlikely(err))
- goto out;
-
- while ((err = mountpoint_last(nd, path)) > 0) {
- err = trailing_symlink(nd);
- if (err)
+ while (!(err = link_path_walk(s, nd)) &&
+ (err = mountpoint_last(nd, path)) > 0) {
+ s = trailing_symlink(nd);
+ if (IS_ERR(s)) {
+ err = PTR_ERR(s);
break;
+ }
}
-out:
path_cleanup(nd);
return err;
}
@@ -3282,17 +3280,15 @@ static struct file *path_openat(int dfd, struct filename *pathname,
put_filp(file);
return ERR_CAST(s);
}
- error = link_path_walk(s, nd);
- if (unlikely(error))
- goto out;
-
- while ((error = do_last(nd, file, op, &opened, pathname)) > 0) {
+ while (!(error = link_path_walk(s, nd)) &&
+ (error = do_last(nd, file, op, &opened, pathname)) > 0) {
nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
- error = trailing_symlink(nd);
- if (unlikely(error))
+ s = trailing_symlink(nd);
+ if (IS_ERR(s)) {
+ error = PTR_ERR(s);
break;
+ }
}
-out:
path_cleanup(nd);
out2:
if (!(opened & FILE_OPENED)) {
--
2.1.4


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