Skip to content

Commit a4f5b52

Browse files
author
Al Viro
committed
step_into(): lose inode argument
make handle_mounts() always fetch it. This is just the first step - the callers of step_into() will stop trying to calculate the sucker, etc. The passed value should be equal to dentry->d_inode in all cases; in RCU mode - fetched after we'd sampled ->d_seq. Might as well fetch it here. We do need to validate ->d_seq, which duplicates the check currently done in lookup_fast(); that duplication will go away shortly. After that change handle_mounts() always ignores the initial value of *inode and always sets it on success. Signed-off-by: Al Viro <[email protected]>
1 parent 03fa86e commit a4f5b52

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

fs/namei.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,9 @@ static inline int handle_mounts(struct nameidata *nd, struct dentry *dentry,
15361536
path->dentry = dentry;
15371537
if (nd->flags & LOOKUP_RCU) {
15381538
unsigned int seq = nd->next_seq;
1539+
*inode = dentry->d_inode;
1540+
if (read_seqcount_retry(&dentry->d_seq, seq))
1541+
return -ECHILD;
15391542
if (unlikely(!*inode))
15401543
return -ENOENT;
15411544
if (likely(__follow_mount_rcu(nd, path, inode)))
@@ -1848,9 +1851,10 @@ static const char *pick_link(struct nameidata *nd, struct path *link,
18481851
* NOTE: dentry must be what nd->next_seq had been sampled from.
18491852
*/
18501853
static const char *step_into(struct nameidata *nd, int flags,
1851-
struct dentry *dentry, struct inode *inode)
1854+
struct dentry *dentry)
18521855
{
18531856
struct path path;
1857+
struct inode *inode;
18541858
int err = handle_mounts(nd, dentry, &path, &inode);
18551859

18561860
if (err < 0)
@@ -1976,7 +1980,7 @@ static const char *handle_dots(struct nameidata *nd, int type)
19761980
parent = follow_dotdot(nd, &inode);
19771981
if (IS_ERR(parent))
19781982
return ERR_CAST(parent);
1979-
error = step_into(nd, WALK_NOFOLLOW, parent, inode);
1983+
error = step_into(nd, WALK_NOFOLLOW, parent);
19801984
if (unlikely(error))
19811985
return error;
19821986

@@ -2021,7 +2025,7 @@ static const char *walk_component(struct nameidata *nd, int flags)
20212025
}
20222026
if (!(flags & WALK_MORE) && nd->depth)
20232027
put_link(nd);
2024-
return step_into(nd, flags, dentry, inode);
2028+
return step_into(nd, flags, dentry);
20252029
}
20262030

20272031
/*
@@ -2480,8 +2484,7 @@ static int handle_lookup_down(struct nameidata *nd)
24802484
if (!(nd->flags & LOOKUP_RCU))
24812485
dget(nd->path.dentry);
24822486
nd->next_seq = nd->seq;
2483-
return PTR_ERR(step_into(nd, WALK_NOFOLLOW,
2484-
nd->path.dentry, nd->inode));
2487+
return PTR_ERR(step_into(nd, WALK_NOFOLLOW, nd->path.dentry));
24852488
}
24862489

24872490
/* 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,
34703473
finish_lookup:
34713474
if (nd->depth)
34723475
put_link(nd);
3473-
res = step_into(nd, WALK_TRAILING, dentry, inode);
3476+
res = step_into(nd, WALK_TRAILING, dentry);
34743477
if (unlikely(res))
34753478
nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
34763479
return res;

0 commit comments

Comments
 (0)