From: Al Viro <viro@xxxxxxxxxxxxxxxxxx> move the stack of saved states out of link_path_walk() stack frame to that of callers, put a reference to it into struct nameidata as nd->stack, move nd->saved_names[] elements in there. Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> --- fs/namei.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index e03c18f..1c967d1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -504,7 +504,12 @@ struct nameidata { int link_count, total_link_count; struct file *base; - char *saved_names[MAX_NESTED_LINKS + 1]; + struct saved { + struct path link; + const char *name; + void *cookie; + char *body; + } *stack; }; static struct nameidata *set_nameidata(struct nameidata *p) @@ -738,13 +743,13 @@ void nd_set_link(char *path) { struct nameidata *nd = current->nameidata; - nd->saved_names[nd->depth] = path; + nd->stack[nd->depth].body = path; } EXPORT_SYMBOL(nd_set_link); static inline char *nd_get_link(struct nameidata *nd) { - return nd->saved_names[nd->depth]; + return nd->stack[nd->depth].body; } static inline void put_link(struct nameidata *nd, struct path *link, void *cookie) @@ -1770,11 +1775,7 @@ static inline u64 hash_name(const char *name) */ static int link_path_walk(const char *name, struct nameidata *nd) { - struct saved { - struct path link; - void *cookie; - const char *name; - } stack[MAX_NESTED_LINKS], *last = stack + nd->depth - 1; + struct saved *last = nd->stack; struct path next; int err; @@ -2092,7 +2093,11 @@ static int filename_lookup(int dfd, struct filename *name, unsigned int flags, struct nameidata *nd) { int retval; - struct nameidata *saved_nd = set_nameidata(nd); + struct saved stack[MAX_NESTED_LINKS + 1]; + struct nameidata *saved_nd; + + nd->stack = stack; + saved_nd = set_nameidata(nd); retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, nd); if (unlikely(retval == -ECHILD)) @@ -2409,9 +2414,12 @@ static int path_mountpoint(int dfd, const struct filename *name, struct path *path, unsigned int flags) { - struct nameidata nd, *saved = set_nameidata(&nd); + struct saved stack[MAX_NESTED_LINKS + 1]; + struct nameidata nd, *saved; int err; + nd.stack = stack; + saved = set_nameidata(&nd); err = path_init(dfd, name, flags, &nd); if (unlikely(err)) goto out; @@ -3280,6 +3288,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, struct path path; int opened = 0; int error; + struct saved stack[MAX_NESTED_LINKS + 1]; struct nameidata *saved_nd; file = get_empty_filp(); @@ -3287,6 +3296,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, return file; file->f_flags = op->open_flag; + nd->stack = stack; saved_nd = set_nameidata(nd); if (unlikely(file->f_flags & __O_TMPFILE)) { @@ -4491,11 +4501,14 @@ EXPORT_SYMBOL(readlink_copy); */ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) { - struct nameidata nd, *saved = set_nameidata(&nd); + struct saved stack; + struct nameidata nd, *saved; void *cookie; int res; nd.depth = 0; + nd.stack = &stack; + saved = set_nameidata(&nd); cookie = dentry->d_inode->i_op->follow_link(dentry); if (IS_ERR(cookie)) res = PTR_ERR(cookie); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html