diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-04-07 11:44:16 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-11 21:35:58 -0400 |
commit | 9b4a9b14a793bc69b505ed916051f6f32db13bb8 (patch) | |
tree | 5e4aa273b714b3e10a360f71c2178de66f83bd66 /fs | |
parent | 4e44b6852e03c915618ca6776b6697b436246b00 (diff) |
Preparations to caching root in path_walk()
Split do_path_lookup(), opencode the call from do_filp_open()
do_filp_open() is the only caller of do_path_lookup() that
cares about root afterwards (it keeps resolving symlinks on
O_CREAT path after it'd done LOOKUP_PARENT walk). So when
we start caching fs->root in path_walk(), it'll need a different
treatment.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/namei.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/fs/namei.c b/fs/namei.c index c82805d088e1..895733efc6b9 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1017,9 +1017,7 @@ static int path_walk(const char *name, struct nameidata *nd) | |||
1017 | return link_path_walk(name, nd); | 1017 | return link_path_walk(name, nd); |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ | 1020 | static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd) |
1021 | static int do_path_lookup(int dfd, const char *name, | ||
1022 | unsigned int flags, struct nameidata *nd) | ||
1023 | { | 1021 | { |
1024 | int retval = 0; | 1022 | int retval = 0; |
1025 | int fput_needed; | 1023 | int fput_needed; |
@@ -1063,17 +1061,25 @@ static int do_path_lookup(int dfd, const char *name, | |||
1063 | 1061 | ||
1064 | fput_light(file, fput_needed); | 1062 | fput_light(file, fput_needed); |
1065 | } | 1063 | } |
1064 | return 0; | ||
1066 | 1065 | ||
1067 | retval = path_walk(name, nd); | 1066 | fput_fail: |
1067 | fput_light(file, fput_needed); | ||
1068 | out_fail: | ||
1069 | return retval; | ||
1070 | } | ||
1071 | |||
1072 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ | ||
1073 | static int do_path_lookup(int dfd, const char *name, | ||
1074 | unsigned int flags, struct nameidata *nd) | ||
1075 | { | ||
1076 | int retval = path_init(dfd, name, flags, nd); | ||
1077 | if (!retval) | ||
1078 | retval = path_walk(name, nd); | ||
1068 | if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && | 1079 | if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && |
1069 | nd->path.dentry->d_inode)) | 1080 | nd->path.dentry->d_inode)) |
1070 | audit_inode(name, nd->path.dentry); | 1081 | audit_inode(name, nd->path.dentry); |
1071 | out_fail: | ||
1072 | return retval; | 1082 | return retval; |
1073 | |||
1074 | fput_fail: | ||
1075 | fput_light(file, fput_needed); | ||
1076 | goto out_fail; | ||
1077 | } | 1083 | } |
1078 | 1084 | ||
1079 | int path_lookup(const char *name, unsigned int flags, | 1085 | int path_lookup(const char *name, unsigned int flags, |
@@ -1676,9 +1682,14 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
1676 | /* | 1682 | /* |
1677 | * Create - we need to know the parent. | 1683 | * Create - we need to know the parent. |
1678 | */ | 1684 | */ |
1679 | error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd); | 1685 | error = path_init(dfd, pathname, LOOKUP_PARENT, &nd); |
1680 | if (error) | 1686 | if (error) |
1681 | return ERR_PTR(error); | 1687 | return ERR_PTR(error); |
1688 | error = path_walk(pathname, &nd); | ||
1689 | if (error) | ||
1690 | return ERR_PTR(error); | ||
1691 | if (unlikely(!audit_dummy_context())) | ||
1692 | audit_inode(pathname, nd.path.dentry); | ||
1682 | 1693 | ||
1683 | /* | 1694 | /* |
1684 | * We have the parent and last component. First of all, check | 1695 | * We have the parent and last component. First of all, check |