This allows keeping the LOOKUP_ROOT case for vfs_path_lookup entirely out of the normal fast path. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/namei.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 7963f97a130442..90e1cb008ae449 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2352,22 +2352,18 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path } static int filename_lookup(int dfd, struct filename *name, unsigned flags, - struct path *path, struct path *root) + struct path *path, struct nameidata *nd) { int retval; - struct nameidata nd; + if (IS_ERR(name)) return PTR_ERR(name); - if (unlikely(root)) { - nd.root = *root; - flags |= LOOKUP_ROOT; - } - set_nameidata(&nd, dfd, name); - retval = path_lookupat(&nd, flags | LOOKUP_RCU, path); + set_nameidata(nd, dfd, name); + retval = path_lookupat(nd, flags | LOOKUP_RCU, path); if (unlikely(retval == -ECHILD)) - retval = path_lookupat(&nd, flags, path); + retval = path_lookupat(nd, flags, path); if (unlikely(retval == -ESTALE)) - retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path); + retval = path_lookupat(nd, flags | LOOKUP_REVAL, path); if (likely(!retval)) audit_inode(name, path->dentry, @@ -2450,8 +2446,10 @@ struct dentry *kern_path_locked(const char *name, struct path *path) int kern_path(const char *name, unsigned int flags, struct path *path) { - return filename_lookup(AT_FDCWD, getname_kernel(name), - flags, path, NULL); + struct nameidata nd; + + return filename_lookup(AT_FDCWD, getname_kernel(name), flags, path, + &nd); } EXPORT_SYMBOL(kern_path); @@ -2467,10 +2465,12 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, const char *name, unsigned int flags, struct path *path) { - struct path root = {.mnt = mnt, .dentry = dentry}; - /* the first argument of filename_lookup() is ignored with root */ + struct nameidata nd; + + nd.root.mnt = mnt; + nd.root.dentry = dentry; return filename_lookup(AT_FDCWD, getname_kernel(name), - flags , path, &root); + flags | LOOKUP_ROOT, path, &nd); } EXPORT_SYMBOL(vfs_path_lookup); @@ -2643,8 +2643,10 @@ int path_pts(struct path *path) int user_path_at_empty(int dfd, const char __user *name, unsigned flags, struct path *path, int *empty) { + struct nameidata nd; + return filename_lookup(dfd, getname_flags(name, flags, empty), - flags, path, NULL); + flags, path, &nd); } EXPORT_SYMBOL(user_path_at_empty); -- 2.28.0