mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 13:43:51 +00:00
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>
This commit is contained in:
parent
fab51e8ab2
commit
e8bb73dfb0
29
fs/namei.c
29
fs/namei.c
@ -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)
|
|||||||
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;
|
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)))
|
if (likely(!(nd->flags & LOOKUP_JUMPED)))
|
||||||
@ -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,
|
|||||||
* 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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user