summaryrefslogtreecommitdiff
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 8dd7874816cc..60e17152374a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1536,6 +1536,9 @@ static inline int handle_mounts(struct nameidata *nd, struct dentry *dentry,
path->dentry = dentry;
if (nd->flags & LOOKUP_RCU) {
unsigned int seq = nd->next_seq;
+ *inode = dentry->d_inode;
+ if (read_seqcount_retry(&dentry->d_seq, seq))
+ return -ECHILD;
if (unlikely(!*inode))
return -ENOENT;
if (likely(__follow_mount_rcu(nd, path, inode)))
@@ -1848,9 +1851,10 @@ all_done: // pure jump
* NOTE: dentry must be what nd->next_seq had been sampled from.
*/
static const char *step_into(struct nameidata *nd, int flags,
- struct dentry *dentry, struct inode *inode)
+ struct dentry *dentry)
{
struct path path;
+ struct inode *inode;
int err = handle_mounts(nd, dentry, &path, &inode);
if (err < 0)
@@ -1976,7 +1980,7 @@ static const char *handle_dots(struct nameidata *nd, int type)
parent = follow_dotdot(nd, &inode);
if (IS_ERR(parent))
return ERR_CAST(parent);
- error = step_into(nd, WALK_NOFOLLOW, parent, inode);
+ error = step_into(nd, WALK_NOFOLLOW, parent);
if (unlikely(error))
return error;
@@ -2021,7 +2025,7 @@ static const char *walk_component(struct nameidata *nd, int flags)
}
if (!(flags & WALK_MORE) && nd->depth)
put_link(nd);
- return step_into(nd, flags, dentry, inode);
+ return step_into(nd, flags, dentry);
}
/*
@@ -2480,8 +2484,7 @@ static int handle_lookup_down(struct nameidata *nd)
if (!(nd->flags & LOOKUP_RCU))
dget(nd->path.dentry);
nd->next_seq = nd->seq;
- return PTR_ERR(step_into(nd, WALK_NOFOLLOW,
- nd->path.dentry, nd->inode));
+ return PTR_ERR(step_into(nd, WALK_NOFOLLOW, nd->path.dentry));
}
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
@@ -3470,7 +3473,7 @@ static const char *open_last_lookups(struct nameidata *nd,
finish_lookup:
if (nd->depth)
put_link(nd);
- res = step_into(nd, WALK_TRAILING, dentry, inode);
+ res = step_into(nd, WALK_TRAILING, dentry);
if (unlikely(res))
nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
return res;