@@ -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);
This allows keeping the LOOKUP_ROOT case for vfs_path_lookup entirely out of the normal fast path. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/namei.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)