forked from luck/tmp_suning_uos_patched
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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
9e6697e26f
commit
ef55d91700
22
fs/namei.c
22
fs/namei.c
@ -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)
|
|||||||
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)
|
|||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user