diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-05-12 16:44:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-05-15 01:10:40 -0400 |
commit | 9ad1aaa61522ffba001a5599623182fe23083a94 (patch) | |
tree | 16d3a2d928d3b2eb2b82a892ab18d23208449ab9 /fs/namei.c | |
parent | e4bd1c1a95409131ad3948accab98f0d6b8093f0 (diff) |
namei: shift nameidata inside filename_lookup()
pass root instead; non-NULL => copy to nd.root and
set LOOKUP_ROOT in flags
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/fs/namei.c b/fs/namei.c index 847c61a48078..2999404c8d30 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2119,17 +2119,20 @@ static int path_lookupat(int dfd, const struct filename *name, unsigned flags, | |||
2119 | } | 2119 | } |
2120 | 2120 | ||
2121 | static int filename_lookup(int dfd, struct filename *name, unsigned flags, | 2121 | static int filename_lookup(int dfd, struct filename *name, unsigned flags, |
2122 | struct nameidata *nd, struct path *path) | 2122 | struct path *path, struct path *root) |
2123 | { | 2123 | { |
2124 | int retval; | 2124 | int retval; |
2125 | struct nameidata *saved_nd = set_nameidata(nd); | 2125 | struct nameidata nd, *saved_nd = set_nameidata(&nd); |
2126 | 2126 | if (unlikely(root)) { | |
2127 | retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, nd, path); | 2127 | nd.root = *root; |
2128 | flags |= LOOKUP_ROOT; | ||
2129 | } | ||
2130 | retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, &nd, path); | ||
2128 | if (unlikely(retval == -ECHILD)) | 2131 | if (unlikely(retval == -ECHILD)) |
2129 | retval = path_lookupat(dfd, name, flags, nd, path); | 2132 | retval = path_lookupat(dfd, name, flags, &nd, path); |
2130 | if (unlikely(retval == -ESTALE)) | 2133 | if (unlikely(retval == -ESTALE)) |
2131 | retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, | 2134 | retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, |
2132 | nd, path); | 2135 | &nd, path); |
2133 | 2136 | ||
2134 | if (likely(!retval)) | 2137 | if (likely(!retval)) |
2135 | audit_inode(name, path->dentry, flags & LOOKUP_PARENT); | 2138 | audit_inode(name, path->dentry, flags & LOOKUP_PARENT); |
@@ -2209,11 +2212,10 @@ out: | |||
2209 | 2212 | ||
2210 | int kern_path(const char *name, unsigned int flags, struct path *path) | 2213 | int kern_path(const char *name, unsigned int flags, struct path *path) |
2211 | { | 2214 | { |
2212 | struct nameidata nd; | ||
2213 | struct filename *filename = getname_kernel(name); | 2215 | struct filename *filename = getname_kernel(name); |
2214 | if (IS_ERR(filename)) | 2216 | if (IS_ERR(filename)) |
2215 | return PTR_ERR(filename); | 2217 | return PTR_ERR(filename); |
2216 | return filename_lookup(AT_FDCWD, filename, flags, &nd, path); | 2218 | return filename_lookup(AT_FDCWD, filename, flags, path, NULL); |
2217 | } | 2219 | } |
2218 | EXPORT_SYMBOL(kern_path); | 2220 | EXPORT_SYMBOL(kern_path); |
2219 | 2221 | ||
@@ -2229,7 +2231,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
2229 | const char *name, unsigned int flags, | 2231 | const char *name, unsigned int flags, |
2230 | struct path *path) | 2232 | struct path *path) |
2231 | { | 2233 | { |
2232 | struct nameidata nd; | 2234 | struct path root = {.mnt = mnt, .dentry = dentry}; |
2233 | struct filename *filename = getname_kernel(name); | 2235 | struct filename *filename = getname_kernel(name); |
2234 | 2236 | ||
2235 | BUG_ON(flags & LOOKUP_PARENT); | 2237 | BUG_ON(flags & LOOKUP_PARENT); |
@@ -2237,11 +2239,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
2237 | if (IS_ERR(filename)) | 2239 | if (IS_ERR(filename)) |
2238 | return PTR_ERR(filename); | 2240 | return PTR_ERR(filename); |
2239 | 2241 | ||
2240 | nd.root.dentry = dentry; | 2242 | /* the first argument of filename_lookup() is ignored with root */ |
2241 | nd.root.mnt = mnt; | 2243 | return filename_lookup(AT_FDCWD, filename, flags , path, &root); |
2242 | /* the first argument of filename_lookup() is ignored with LOOKUP_ROOT */ | ||
2243 | return filename_lookup(AT_FDCWD, filename, | ||
2244 | flags | LOOKUP_ROOT, &nd, path); | ||
2245 | } | 2244 | } |
2246 | EXPORT_SYMBOL(vfs_path_lookup); | 2245 | EXPORT_SYMBOL(vfs_path_lookup); |
2247 | 2246 | ||
@@ -2299,14 +2298,13 @@ EXPORT_SYMBOL(lookup_one_len); | |||
2299 | int user_path_at_empty(int dfd, const char __user *name, unsigned flags, | 2298 | int user_path_at_empty(int dfd, const char __user *name, unsigned flags, |
2300 | struct path *path, int *empty) | 2299 | struct path *path, int *empty) |
2301 | { | 2300 | { |
2302 | struct nameidata nd; | ||
2303 | struct filename *tmp = getname_flags(name, flags, empty); | 2301 | struct filename *tmp = getname_flags(name, flags, empty); |
2304 | if (IS_ERR(tmp)) | 2302 | if (IS_ERR(tmp)) |
2305 | return PTR_ERR(tmp); | 2303 | return PTR_ERR(tmp); |
2306 | 2304 | ||
2307 | BUG_ON(flags & LOOKUP_PARENT); | 2305 | BUG_ON(flags & LOOKUP_PARENT); |
2308 | 2306 | ||
2309 | return filename_lookup(dfd, tmp, flags, &nd, path); | 2307 | return filename_lookup(dfd, tmp, flags, path, NULL); |
2310 | } | 2308 | } |
2311 | 2309 | ||
2312 | int user_path_at(int dfd, const char __user *name, unsigned flags, | 2310 | int user_path_at(int dfd, const char __user *name, unsigned flags, |