提交 ef55d917 编写于 作者: A Al Viro

path_init(): set nd->inode earlier in cwd-relative case

that allows to kill the recheck of nd->seq on the way out in
this case, and this check on the way out is left only for
absolute pathnames.
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 9e6697e2
...@@ -2028,6 +2028,15 @@ static const char *path_init(struct nameidata *nd, unsigned flags) ...@@ -2028,6 +2028,15 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
path_get(&nd->root); path_get(&nd->root);
nd->path = nd->root; nd->path = nd->root;
} }
nd->inode = nd->path.dentry->d_inode;
if (!(flags & LOOKUP_RCU))
return s;
if (likely(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)))
return s;
if (!(nd->flags & LOOKUP_ROOT))
nd->root.mnt = NULL;
rcu_read_unlock();
return ERR_PTR(-ECHILD);
} else if (nd->dfd == AT_FDCWD) { } else if (nd->dfd == AT_FDCWD) {
if (flags & LOOKUP_RCU) { if (flags & LOOKUP_RCU) {
struct fs_struct *fs = current->fs; struct fs_struct *fs = current->fs;
...@@ -2038,11 +2047,14 @@ static const char *path_init(struct nameidata *nd, unsigned flags) ...@@ -2038,11 +2047,14 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
do { do {
seq = read_seqcount_begin(&fs->seq); seq = read_seqcount_begin(&fs->seq);
nd->path = fs->pwd; nd->path = fs->pwd;
nd->inode = nd->path.dentry->d_inode;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
} while (read_seqcount_retry(&fs->seq, seq)); } while (read_seqcount_retry(&fs->seq, seq));
} else { } else {
get_fs_pwd(current->fs, &nd->path); get_fs_pwd(current->fs, &nd->path);
nd->inode = nd->path.dentry->d_inode;
} }
return s;
} else { } else {
/* Caller must check execute permissions on the starting path component */ /* Caller must check execute permissions on the starting path component */
struct fd f = fdget_raw(nd->dfd); struct fd f = fdget_raw(nd->dfd);
...@@ -2072,16 +2084,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags) ...@@ -2072,16 +2084,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
fdput(f); fdput(f);
return s; return s;
} }
nd->inode = nd->path.dentry->d_inode;
if (!(flags & LOOKUP_RCU))
return s;
if (likely(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)))
return s;
if (!(nd->flags & LOOKUP_ROOT))
nd->root.mnt = NULL;
rcu_read_unlock();
return ERR_PTR(-ECHILD);
} }
static const char *trailing_symlink(struct nameidata *nd) static const char *trailing_symlink(struct nameidata *nd)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册