Commit 35759521 authored by Al Viro's avatar Al Viro
Browse files

take unlazy_walk() into umount_lookup_last()



... and massage it a bit to reduce nesting
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 4e10f3c9
...@@ -2256,19 +2256,22 @@ umount_lookup_last(struct nameidata *nd, struct path *path) ...@@ -2256,19 +2256,22 @@ umount_lookup_last(struct nameidata *nd, struct path *path)
struct dentry *dentry; struct dentry *dentry;
struct dentry *dir = nd->path.dentry; struct dentry *dir = nd->path.dentry;
if (unlikely(nd->flags & LOOKUP_RCU)) { /* If we're in rcuwalk, drop out of it to handle last component */
WARN_ON_ONCE(1); if (nd->flags & LOOKUP_RCU) {
if (unlazy_walk(nd, NULL)) {
error = -ECHILD; error = -ECHILD;
goto error_check; goto out;
}
} }
nd->flags &= ~LOOKUP_PARENT; nd->flags &= ~LOOKUP_PARENT;
if (unlikely(nd->last_type != LAST_NORM)) { if (unlikely(nd->last_type != LAST_NORM)) {
error = handle_dots(nd, nd->last_type); error = handle_dots(nd, nd->last_type);
if (!error) if (error)
goto out;
dentry = dget(nd->path.dentry); dentry = dget(nd->path.dentry);
goto error_check; goto done;
} }
mutex_lock(&dir->d_inode->i_mutex); mutex_lock(&dir->d_inode->i_mutex);
...@@ -2282,28 +2285,28 @@ umount_lookup_last(struct nameidata *nd, struct path *path) ...@@ -2282,28 +2285,28 @@ umount_lookup_last(struct nameidata *nd, struct path *path)
dentry = d_alloc(dir, &nd->last); dentry = d_alloc(dir, &nd->last);
if (!dentry) { if (!dentry) {
error = -ENOMEM; error = -ENOMEM;
} else { goto out;
}
dentry = lookup_real(dir->d_inode, dentry, nd->flags); dentry = lookup_real(dir->d_inode, dentry, nd->flags);
if (IS_ERR(dentry))
error = PTR_ERR(dentry); error = PTR_ERR(dentry);
} if (IS_ERR(dentry))
goto out;
} }
mutex_unlock(&dir->d_inode->i_mutex); mutex_unlock(&dir->d_inode->i_mutex);
error_check: done:
if (!error) {
if (!dentry->d_inode) { if (!dentry->d_inode) {
error = -ENOENT; error = -ENOENT;
dput(dentry); dput(dentry);
} else { goto out;
}
path->dentry = dentry; path->dentry = dentry;
path->mnt = mntget(nd->path.mnt); path->mnt = mntget(nd->path.mnt);
if (should_follow_link(dentry->d_inode, if (should_follow_link(dentry->d_inode, nd->flags & LOOKUP_FOLLOW))
nd->flags & LOOKUP_FOLLOW))
return 1; return 1;
follow_mount(path); follow_mount(path);
} error = 0;
} out:
terminate_walk(nd); terminate_walk(nd);
return error; return error;
} }
...@@ -2334,15 +2337,6 @@ path_umountat(int dfd, const char *name, struct path *path, unsigned int flags) ...@@ -2334,15 +2337,6 @@ path_umountat(int dfd, const char *name, struct path *path, unsigned int flags)
if (err) if (err)
goto out; goto out;
/* If we're in rcuwalk, drop out of it to handle last component */
if (nd.flags & LOOKUP_RCU) {
err = unlazy_walk(&nd, NULL);
if (err) {
terminate_walk(&nd);
goto out;
}
}
err = umount_lookup_last(&nd, path); err = umount_lookup_last(&nd, path);
while (err > 0) { while (err > 0) {
void *cookie; void *cookie;
......
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