1
0
Fork 0

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: Al Viro <viro@zeniv.linux.org.uk>
hifive-unleashed-5.1
Al Viro 2015-05-08 16:28:42 -04:00
parent fab51e8ab2
commit e8bb73dfb0
1 changed files with 6 additions and 23 deletions

View File

@ -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.
*/
static void terminate_walk(struct nameidata *nd);
/**
* unlazy_walk - try to switch to ref-walk mode.
* @nd: nameidata pathwalk data
@ -673,26 +675,12 @@ static int complete_walk(struct nameidata *nd)
int status;
if (nd->flags & LOOKUP_RCU) {
nd->flags &= ~LOOKUP_RCU;
if (!(nd->flags & LOOKUP_ROOT))
nd->root.mnt = NULL;
if (!legitimize_mnt(nd->path.mnt, nd->m_seq)) {
rcu_read_unlock();
if (unlikely(unlazy_walk(nd, NULL))) {
terminate_walk(nd);
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;
}
rcu_read_unlock();
}
if (likely(!(nd->flags & LOOKUP_JUMPED)))
@ -708,7 +696,7 @@ static int complete_walk(struct nameidata *nd)
if (!status)
status = -ESTALE;
path_put(&nd->path);
terminate_walk(nd);
return status;
}
@ -3008,11 +2996,8 @@ static int do_last(struct nameidata *nd,
* about to look up
*/
error = complete_walk(nd);
if (error) {
if (nd->depth)
put_link(nd);
if (error)
return error;
}
audit_inode(name, dir, LOOKUP_PARENT);
error = -EISDIR;
@ -3117,8 +3102,6 @@ finish_lookup:
finish_open:
error = complete_walk(nd);
if (error) {
if (nd->depth)
put_link(nd);
path_put(&save_parent);
return error;
}