Commit e8bb73df authored by Al Viro's avatar Al Viro

namei: fold put_link() into the failure case of complete_walk()

... and don't open-code unlazy_walk() in there - the only reason
for that is to avoid verfication of cached nd->root, which is
trivially avoided by discarding said cached nd->root first.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent fab51e8a
...@@ -567,6 +567,8 @@ static inline int nd_alloc_stack(struct nameidata *nd) ...@@ -567,6 +567,8 @@ static inline int nd_alloc_stack(struct nameidata *nd)
* to restart the path walk from the beginning in ref-walk mode. * to restart the path walk from the beginning in ref-walk mode.
*/ */
static void terminate_walk(struct nameidata *nd);
/** /**
* unlazy_walk - try to switch to ref-walk mode. * unlazy_walk - try to switch to ref-walk mode.
* @nd: nameidata pathwalk data * @nd: nameidata pathwalk data
...@@ -673,26 +675,12 @@ static int complete_walk(struct nameidata *nd) ...@@ -673,26 +675,12 @@ static int complete_walk(struct nameidata *nd)
int status; int status;
if (nd->flags & LOOKUP_RCU) { if (nd->flags & LOOKUP_RCU) {
nd->flags &= ~LOOKUP_RCU;
if (!(nd->flags & LOOKUP_ROOT)) if (!(nd->flags & LOOKUP_ROOT))
nd->root.mnt = NULL; nd->root.mnt = NULL;
if (unlikely(unlazy_walk(nd, NULL))) {
if (!legitimize_mnt(nd->path.mnt, nd->m_seq)) { terminate_walk(nd);
rcu_read_unlock();
return -ECHILD;
}
if (unlikely(!lockref_get_not_dead(&dentry->d_lockref))) {
rcu_read_unlock();
mntput(nd->path.mnt);
return -ECHILD;
}
if (read_seqcount_retry(&dentry->d_seq, nd->seq)) {
rcu_read_unlock();
dput(dentry);
mntput(nd->path.mnt);
return -ECHILD; return -ECHILD;
} }
rcu_read_unlock();
} }
if (likely(!(nd->flags & LOOKUP_JUMPED))) if (likely(!(nd->flags & LOOKUP_JUMPED)))
...@@ -708,7 +696,7 @@ static int complete_walk(struct nameidata *nd) ...@@ -708,7 +696,7 @@ static int complete_walk(struct nameidata *nd)
if (!status) if (!status)
status = -ESTALE; status = -ESTALE;
path_put(&nd->path); terminate_walk(nd);
return status; return status;
} }
...@@ -3008,11 +2996,8 @@ static int do_last(struct nameidata *nd, ...@@ -3008,11 +2996,8 @@ static int do_last(struct nameidata *nd,
* about to look up * about to look up
*/ */
error = complete_walk(nd); error = complete_walk(nd);
if (error) { if (error)
if (nd->depth)
put_link(nd);
return error; return error;
}
audit_inode(name, dir, LOOKUP_PARENT); audit_inode(name, dir, LOOKUP_PARENT);
error = -EISDIR; error = -EISDIR;
...@@ -3117,8 +3102,6 @@ static int do_last(struct nameidata *nd, ...@@ -3117,8 +3102,6 @@ static int do_last(struct nameidata *nd,
finish_open: finish_open:
error = complete_walk(nd); error = complete_walk(nd);
if (error) { if (error) {
if (nd->depth)
put_link(nd);
path_put(&save_parent); path_put(&save_parent);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment