diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-05-09 18:15:21 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-05-15 01:06:28 -0400 |
commit | 8c1b456689ac0b27e8e16b35190e89a02fd1f121 (patch) | |
tree | 7dd6bf6f5a3651986aea1f2066b5690c19197853 /fs/namei.c | |
parent | 8fa9dd24667f2d6997ec21341019657342859d31 (diff) |
enable passing fast relative symlinks without dropping out of RCU mode
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/namei.c b/fs/namei.c index d9f77ff60b55..bf46e1010a74 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -975,11 +975,6 @@ const char *get_link(struct nameidata *nd) | |||
975 | touch_atime(&last->link); | 975 | touch_atime(&last->link); |
976 | } | 976 | } |
977 | 977 | ||
978 | if (nd->flags & LOOKUP_RCU) { | ||
979 | if (unlikely(unlazy_walk(nd, NULL, 0))) | ||
980 | return ERR_PTR(-ECHILD); | ||
981 | } | ||
982 | |||
983 | error = security_inode_follow_link(dentry, inode, | 978 | error = security_inode_follow_link(dentry, inode, |
984 | nd->flags & LOOKUP_RCU); | 979 | nd->flags & LOOKUP_RCU); |
985 | if (unlikely(error)) | 980 | if (unlikely(error)) |
@@ -988,6 +983,10 @@ const char *get_link(struct nameidata *nd) | |||
988 | nd->last_type = LAST_BIND; | 983 | nd->last_type = LAST_BIND; |
989 | res = inode->i_link; | 984 | res = inode->i_link; |
990 | if (!res) { | 985 | if (!res) { |
986 | if (nd->flags & LOOKUP_RCU) { | ||
987 | if (unlikely(unlazy_walk(nd, NULL, 0))) | ||
988 | return ERR_PTR(-ECHILD); | ||
989 | } | ||
991 | res = inode->i_op->follow_link(dentry, &last->cookie); | 990 | res = inode->i_op->follow_link(dentry, &last->cookie); |
992 | if (IS_ERR_OR_NULL(res)) { | 991 | if (IS_ERR_OR_NULL(res)) { |
993 | last->cookie = NULL; | 992 | last->cookie = NULL; |
@@ -995,6 +994,10 @@ const char *get_link(struct nameidata *nd) | |||
995 | } | 994 | } |
996 | } | 995 | } |
997 | if (*res == '/') { | 996 | if (*res == '/') { |
997 | if (nd->flags & LOOKUP_RCU) { | ||
998 | if (unlikely(unlazy_walk(nd, NULL, 0))) | ||
999 | return ERR_PTR(-ECHILD); | ||
1000 | } | ||
998 | if (!nd->root.mnt) | 1001 | if (!nd->root.mnt) |
999 | set_root(nd); | 1002 | set_root(nd); |
1000 | path_put(&nd->path); | 1003 | path_put(&nd->path); |