diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-05-12 18:43:07 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-05-15 01:10:43 -0400 |
commit | c8a53ee5ee4fcab5ee252f61a69609b65e5e74b8 (patch) | |
tree | 7921af5dbfd064540fa47855f6ad18287d6377d2 /fs/namei.c | |
parent | 102b8af266fbce07b7f8d2396bf2286ba80c93bd (diff) |
namei: stash dfd and name into nameidata
fewer arguments to pass around...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/fs/namei.c b/fs/namei.c index 14aaf00f8ee7..970456fc9ea8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -498,6 +498,8 @@ struct nameidata { | |||
498 | struct qstr last; | 498 | struct qstr last; |
499 | struct path root; | 499 | struct path root; |
500 | struct inode *inode; /* path.dentry.d_inode */ | 500 | struct inode *inode; /* path.dentry.d_inode */ |
501 | struct filename *name; | ||
502 | int dfd; | ||
501 | unsigned int flags; | 503 | unsigned int flags; |
502 | unsigned seq, m_seq, root_seq; | 504 | unsigned seq, m_seq, root_seq; |
503 | int last_type; | 505 | int last_type; |
@@ -512,10 +514,13 @@ struct nameidata { | |||
512 | } *stack, internal[EMBEDDED_LEVELS]; | 514 | } *stack, internal[EMBEDDED_LEVELS]; |
513 | }; | 515 | }; |
514 | 516 | ||
515 | static struct nameidata *set_nameidata(struct nameidata *p) | 517 | static struct nameidata *set_nameidata(struct nameidata *p, int dfd, |
518 | struct filename *name) | ||
516 | { | 519 | { |
517 | struct nameidata *old = current->nameidata; | 520 | struct nameidata *old = current->nameidata; |
518 | p->stack = p->internal; | 521 | p->stack = p->internal; |
522 | p->dfd = dfd; | ||
523 | p->name = name; | ||
519 | p->total_link_count = old ? old->total_link_count : 0; | 524 | p->total_link_count = old ? old->total_link_count : 0; |
520 | current->nameidata = p; | 525 | current->nameidata = p; |
521 | return old; | 526 | return old; |
@@ -1954,11 +1959,10 @@ OK: | |||
1954 | } | 1959 | } |
1955 | } | 1960 | } |
1956 | 1961 | ||
1957 | static const char *path_init(int dfd, const struct filename *name, | 1962 | static const char *path_init(struct nameidata *nd, unsigned flags) |
1958 | unsigned int flags, struct nameidata *nd) | ||
1959 | { | 1963 | { |
1960 | int retval = 0; | 1964 | int retval = 0; |
1961 | const char *s = name->name; | 1965 | const char *s = nd->name->name; |
1962 | 1966 | ||
1963 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 1967 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
1964 | nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; | 1968 | nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; |
@@ -1999,7 +2003,7 @@ static const char *path_init(int dfd, const struct filename *name, | |||
1999 | path_get(&nd->root); | 2003 | path_get(&nd->root); |
2000 | } | 2004 | } |
2001 | nd->path = nd->root; | 2005 | nd->path = nd->root; |
2002 | } else if (dfd == AT_FDCWD) { | 2006 | } else if (nd->dfd == AT_FDCWD) { |
2003 | if (flags & LOOKUP_RCU) { | 2007 | if (flags & LOOKUP_RCU) { |
2004 | struct fs_struct *fs = current->fs; | 2008 | struct fs_struct *fs = current->fs; |
2005 | unsigned seq; | 2009 | unsigned seq; |
@@ -2016,7 +2020,7 @@ static const char *path_init(int dfd, const struct filename *name, | |||
2016 | } | 2020 | } |
2017 | } else { | 2021 | } else { |
2018 | /* Caller must check execute permissions on the starting path component */ | 2022 | /* Caller must check execute permissions on the starting path component */ |
2019 | struct fd f = fdget_raw(dfd); | 2023 | struct fd f = fdget_raw(nd->dfd); |
2020 | struct dentry *dentry; | 2024 | struct dentry *dentry; |
2021 | 2025 | ||
2022 | if (!f.file) | 2026 | if (!f.file) |
@@ -2082,10 +2086,9 @@ static inline int lookup_last(struct nameidata *nd) | |||
2082 | } | 2086 | } |
2083 | 2087 | ||
2084 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ | 2088 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ |
2085 | static int path_lookupat(int dfd, const struct filename *name, unsigned flags, | 2089 | static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path) |
2086 | struct nameidata *nd, struct path *path) | ||
2087 | { | 2090 | { |
2088 | const char *s = path_init(dfd, name, flags, nd); | 2091 | const char *s = path_init(nd, flags); |
2089 | int err; | 2092 | int err; |
2090 | 2093 | ||
2091 | if (IS_ERR(s)) | 2094 | if (IS_ERR(s)) |
@@ -2120,17 +2123,16 @@ static int filename_lookup(int dfd, struct filename *name, unsigned flags, | |||
2120 | struct nameidata nd, *saved_nd; | 2123 | struct nameidata nd, *saved_nd; |
2121 | if (IS_ERR(name)) | 2124 | if (IS_ERR(name)) |
2122 | return PTR_ERR(name); | 2125 | return PTR_ERR(name); |
2123 | saved_nd = set_nameidata(&nd); | 2126 | saved_nd = set_nameidata(&nd, dfd, name); |
2124 | if (unlikely(root)) { | 2127 | if (unlikely(root)) { |
2125 | nd.root = *root; | 2128 | nd.root = *root; |
2126 | flags |= LOOKUP_ROOT; | 2129 | flags |= LOOKUP_ROOT; |
2127 | } | 2130 | } |
2128 | retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, &nd, path); | 2131 | retval = path_lookupat(&nd, flags | LOOKUP_RCU, path); |
2129 | if (unlikely(retval == -ECHILD)) | 2132 | if (unlikely(retval == -ECHILD)) |
2130 | retval = path_lookupat(dfd, name, flags, &nd, path); | 2133 | retval = path_lookupat(&nd, flags, path); |
2131 | if (unlikely(retval == -ESTALE)) | 2134 | if (unlikely(retval == -ESTALE)) |
2132 | retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, | 2135 | retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path); |
2133 | &nd, path); | ||
2134 | 2136 | ||
2135 | if (likely(!retval)) | 2137 | if (likely(!retval)) |
2136 | audit_inode(name, path->dentry, flags & LOOKUP_PARENT); | 2138 | audit_inode(name, path->dentry, flags & LOOKUP_PARENT); |
@@ -2140,11 +2142,10 @@ static int filename_lookup(int dfd, struct filename *name, unsigned flags, | |||
2140 | } | 2142 | } |
2141 | 2143 | ||
2142 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ | 2144 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ |
2143 | static int path_parentat(int dfd, const struct filename *name, | 2145 | static int path_parentat(struct nameidata *nd, unsigned flags, |
2144 | unsigned int flags, struct nameidata *nd, | ||
2145 | struct path *parent) | 2146 | struct path *parent) |
2146 | { | 2147 | { |
2147 | const char *s = path_init(dfd, name, flags, nd); | 2148 | const char *s = path_init(nd, flags); |
2148 | int err; | 2149 | int err; |
2149 | if (IS_ERR(s)) | 2150 | if (IS_ERR(s)) |
2150 | return PTR_ERR(s); | 2151 | return PTR_ERR(s); |
@@ -2169,13 +2170,12 @@ static struct filename *filename_parentat(int dfd, struct filename *name, | |||
2169 | 2170 | ||
2170 | if (IS_ERR(name)) | 2171 | if (IS_ERR(name)) |
2171 | return name; | 2172 | return name; |
2172 | saved_nd = set_nameidata(&nd); | 2173 | saved_nd = set_nameidata(&nd, dfd, name); |
2173 | retval = path_parentat(dfd, name, flags | LOOKUP_RCU, &nd, parent); | 2174 | retval = path_parentat(&nd, flags | LOOKUP_RCU, parent); |
2174 | if (unlikely(retval == -ECHILD)) | 2175 | if (unlikely(retval == -ECHILD)) |
2175 | retval = path_parentat(dfd, name, flags, &nd, parent); | 2176 | retval = path_parentat(&nd, flags, parent); |
2176 | if (unlikely(retval == -ESTALE)) | 2177 | if (unlikely(retval == -ESTALE)) |
2177 | retval = path_parentat(dfd, name, flags | LOOKUP_REVAL, | 2178 | retval = path_parentat(&nd, flags | LOOKUP_REVAL, parent); |
2178 | &nd, parent); | ||
2179 | if (likely(!retval)) { | 2179 | if (likely(!retval)) { |
2180 | *last = nd.last; | 2180 | *last = nd.last; |
2181 | *type = nd.last_type; | 2181 | *type = nd.last_type; |
@@ -2415,19 +2415,17 @@ done: | |||
2415 | 2415 | ||
2416 | /** | 2416 | /** |
2417 | * path_mountpoint - look up a path to be umounted | 2417 | * path_mountpoint - look up a path to be umounted |
2418 | * @dfd: directory file descriptor to start walk from | 2418 | * @nameidata: lookup context |
2419 | * @name: full pathname to walk | ||
2420 | * @path: pointer to container for result | ||
2421 | * @flags: lookup flags | 2419 | * @flags: lookup flags |
2420 | * @path: pointer to container for result | ||
2422 | * | 2421 | * |
2423 | * Look up the given name, but don't attempt to revalidate the last component. | 2422 | * Look up the given name, but don't attempt to revalidate the last component. |
2424 | * Returns 0 and "path" will be valid on success; Returns error otherwise. | 2423 | * Returns 0 and "path" will be valid on success; Returns error otherwise. |
2425 | */ | 2424 | */ |
2426 | static int | 2425 | static int |
2427 | path_mountpoint(int dfd, const struct filename *name, struct path *path, | 2426 | path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path) |
2428 | struct nameidata *nd, unsigned int flags) | ||
2429 | { | 2427 | { |
2430 | const char *s = path_init(dfd, name, flags, nd); | 2428 | const char *s = path_init(nd, flags); |
2431 | int err; | 2429 | int err; |
2432 | if (IS_ERR(s)) | 2430 | if (IS_ERR(s)) |
2433 | return PTR_ERR(s); | 2431 | return PTR_ERR(s); |
@@ -2451,12 +2449,12 @@ filename_mountpoint(int dfd, struct filename *name, struct path *path, | |||
2451 | int error; | 2449 | int error; |
2452 | if (IS_ERR(name)) | 2450 | if (IS_ERR(name)) |
2453 | return PTR_ERR(name); | 2451 | return PTR_ERR(name); |
2454 | saved = set_nameidata(&nd); | 2452 | saved = set_nameidata(&nd, dfd, name); |
2455 | error = path_mountpoint(dfd, name, path, &nd, flags | LOOKUP_RCU); | 2453 | error = path_mountpoint(&nd, flags | LOOKUP_RCU, path); |
2456 | if (unlikely(error == -ECHILD)) | 2454 | if (unlikely(error == -ECHILD)) |
2457 | error = path_mountpoint(dfd, name, path, &nd, flags); | 2455 | error = path_mountpoint(&nd, flags, path); |
2458 | if (unlikely(error == -ESTALE)) | 2456 | if (unlikely(error == -ESTALE)) |
2459 | error = path_mountpoint(dfd, name, path, &nd, flags | LOOKUP_REVAL); | 2457 | error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path); |
2460 | if (likely(!error)) | 2458 | if (likely(!error)) |
2461 | audit_inode(name, path->dentry, 0); | 2459 | audit_inode(name, path->dentry, 0); |
2462 | restore_nameidata(saved); | 2460 | restore_nameidata(saved); |
@@ -3217,8 +3215,7 @@ stale_open: | |||
3217 | goto retry_lookup; | 3215 | goto retry_lookup; |
3218 | } | 3216 | } |
3219 | 3217 | ||
3220 | static int do_tmpfile(int dfd, struct filename *pathname, | 3218 | static int do_tmpfile(struct nameidata *nd, unsigned flags, |
3221 | struct nameidata *nd, int flags, | ||
3222 | const struct open_flags *op, | 3219 | const struct open_flags *op, |
3223 | struct file *file, int *opened) | 3220 | struct file *file, int *opened) |
3224 | { | 3221 | { |
@@ -3226,8 +3223,7 @@ static int do_tmpfile(int dfd, struct filename *pathname, | |||
3226 | struct dentry *child; | 3223 | struct dentry *child; |
3227 | struct inode *dir; | 3224 | struct inode *dir; |
3228 | struct path path; | 3225 | struct path path; |
3229 | int error = path_lookupat(dfd, pathname, | 3226 | int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path); |
3230 | flags | LOOKUP_DIRECTORY, nd, &path); | ||
3231 | if (unlikely(error)) | 3227 | if (unlikely(error)) |
3232 | return error; | 3228 | return error; |
3233 | error = mnt_want_write(path.mnt); | 3229 | error = mnt_want_write(path.mnt); |
@@ -3252,7 +3248,7 @@ static int do_tmpfile(int dfd, struct filename *pathname, | |||
3252 | error = dir->i_op->tmpfile(dir, child, op->mode); | 3248 | error = dir->i_op->tmpfile(dir, child, op->mode); |
3253 | if (error) | 3249 | if (error) |
3254 | goto out2; | 3250 | goto out2; |
3255 | audit_inode(pathname, child, 0); | 3251 | audit_inode(nd->name, child, 0); |
3256 | /* Don't check for other permissions, the inode was just created */ | 3252 | /* Don't check for other permissions, the inode was just created */ |
3257 | error = may_open(&path, MAY_OPEN, op->open_flag); | 3253 | error = may_open(&path, MAY_OPEN, op->open_flag); |
3258 | if (error) | 3254 | if (error) |
@@ -3277,8 +3273,8 @@ out: | |||
3277 | return error; | 3273 | return error; |
3278 | } | 3274 | } |
3279 | 3275 | ||
3280 | static struct file *path_openat(int dfd, struct filename *pathname, | 3276 | static struct file *path_openat(struct nameidata *nd, |
3281 | struct nameidata *nd, const struct open_flags *op, int flags) | 3277 | const struct open_flags *op, unsigned flags) |
3282 | { | 3278 | { |
3283 | const char *s; | 3279 | const char *s; |
3284 | struct file *file; | 3280 | struct file *file; |
@@ -3292,17 +3288,17 @@ static struct file *path_openat(int dfd, struct filename *pathname, | |||
3292 | file->f_flags = op->open_flag; | 3288 | file->f_flags = op->open_flag; |
3293 | 3289 | ||
3294 | if (unlikely(file->f_flags & __O_TMPFILE)) { | 3290 | if (unlikely(file->f_flags & __O_TMPFILE)) { |
3295 | error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); | 3291 | error = do_tmpfile(nd, flags, op, file, &opened); |
3296 | goto out2; | 3292 | goto out2; |
3297 | } | 3293 | } |
3298 | 3294 | ||
3299 | s = path_init(dfd, pathname, flags, nd); | 3295 | s = path_init(nd, flags); |
3300 | if (IS_ERR(s)) { | 3296 | if (IS_ERR(s)) { |
3301 | put_filp(file); | 3297 | put_filp(file); |
3302 | return ERR_CAST(s); | 3298 | return ERR_CAST(s); |
3303 | } | 3299 | } |
3304 | while (!(error = link_path_walk(s, nd)) && | 3300 | while (!(error = link_path_walk(s, nd)) && |
3305 | (error = do_last(nd, file, op, &opened, pathname)) > 0) { | 3301 | (error = do_last(nd, file, op, &opened, nd->name)) > 0) { |
3306 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); | 3302 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); |
3307 | s = trailing_symlink(nd); | 3303 | s = trailing_symlink(nd); |
3308 | if (IS_ERR(s)) { | 3304 | if (IS_ERR(s)) { |
@@ -3331,15 +3327,15 @@ out2: | |||
3331 | struct file *do_filp_open(int dfd, struct filename *pathname, | 3327 | struct file *do_filp_open(int dfd, struct filename *pathname, |
3332 | const struct open_flags *op) | 3328 | const struct open_flags *op) |
3333 | { | 3329 | { |
3334 | struct nameidata nd, *saved_nd = set_nameidata(&nd); | 3330 | struct nameidata nd, *saved_nd = set_nameidata(&nd, dfd, pathname); |
3335 | int flags = op->lookup_flags; | 3331 | int flags = op->lookup_flags; |
3336 | struct file *filp; | 3332 | struct file *filp; |
3337 | 3333 | ||
3338 | filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU); | 3334 | filp = path_openat(&nd, op, flags | LOOKUP_RCU); |
3339 | if (unlikely(filp == ERR_PTR(-ECHILD))) | 3335 | if (unlikely(filp == ERR_PTR(-ECHILD))) |
3340 | filp = path_openat(dfd, pathname, &nd, op, flags); | 3336 | filp = path_openat(&nd, op, flags); |
3341 | if (unlikely(filp == ERR_PTR(-ESTALE))) | 3337 | if (unlikely(filp == ERR_PTR(-ESTALE))) |
3342 | filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_REVAL); | 3338 | filp = path_openat(&nd, op, flags | LOOKUP_REVAL); |
3343 | restore_nameidata(saved_nd); | 3339 | restore_nameidata(saved_nd); |
3344 | return filp; | 3340 | return filp; |
3345 | } | 3341 | } |
@@ -3362,12 +3358,12 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
3362 | if (unlikely(IS_ERR(filename))) | 3358 | if (unlikely(IS_ERR(filename))) |
3363 | return ERR_CAST(filename); | 3359 | return ERR_CAST(filename); |
3364 | 3360 | ||
3365 | saved_nd = set_nameidata(&nd); | 3361 | saved_nd = set_nameidata(&nd, -1, filename); |
3366 | file = path_openat(-1, filename, &nd, op, flags | LOOKUP_RCU); | 3362 | file = path_openat(&nd, op, flags | LOOKUP_RCU); |
3367 | if (unlikely(file == ERR_PTR(-ECHILD))) | 3363 | if (unlikely(file == ERR_PTR(-ECHILD))) |
3368 | file = path_openat(-1, filename, &nd, op, flags); | 3364 | file = path_openat(&nd, op, flags); |
3369 | if (unlikely(file == ERR_PTR(-ESTALE))) | 3365 | if (unlikely(file == ERR_PTR(-ESTALE))) |
3370 | file = path_openat(-1, filename, &nd, op, flags | LOOKUP_REVAL); | 3366 | file = path_openat(&nd, op, flags | LOOKUP_REVAL); |
3371 | restore_nameidata(saved_nd); | 3367 | restore_nameidata(saved_nd); |
3372 | putname(filename); | 3368 | putname(filename); |
3373 | return file; | 3369 | return file; |