summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c60
1 files changed, 27 insertions, 33 deletions
diff --git a/fs/namei.c b/fs/namei.c
index f415c6683a83..0ab9e6756f3d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2256,19 +2256,22 @@ umount_lookup_last(struct nameidata *nd, struct path *path)
struct dentry *dentry;
struct dentry *dir = nd->path.dentry;
- if (unlikely(nd->flags & LOOKUP_RCU)) {
- WARN_ON_ONCE(1);
- error = -ECHILD;
- goto error_check;
+ /* If we're in rcuwalk, drop out of it to handle last component */
+ if (nd->flags & LOOKUP_RCU) {
+ if (unlazy_walk(nd, NULL)) {
+ error = -ECHILD;
+ goto out;
+ }
}
nd->flags &= ~LOOKUP_PARENT;
if (unlikely(nd->last_type != LAST_NORM)) {
error = handle_dots(nd, nd->last_type);
- if (!error)
- dentry = dget(nd->path.dentry);
- goto error_check;
+ if (error)
+ goto out;
+ dentry = dget(nd->path.dentry);
+ goto done;
}
mutex_lock(&dir->d_inode->i_mutex);
@@ -2282,28 +2285,28 @@ umount_lookup_last(struct nameidata *nd, struct path *path)
dentry = d_alloc(dir, &nd->last);
if (!dentry) {
error = -ENOMEM;
- } else {
- dentry = lookup_real(dir->d_inode, dentry, nd->flags);
- if (IS_ERR(dentry))
- error = PTR_ERR(dentry);
+ goto out;
}
+ dentry = lookup_real(dir->d_inode, dentry, nd->flags);
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
+ goto out;
}
mutex_unlock(&dir->d_inode->i_mutex);
-error_check:
- if (!error) {
- if (!dentry->d_inode) {
- error = -ENOENT;
- dput(dentry);
- } else {
- path->dentry = dentry;
- path->mnt = mntget(nd->path.mnt);
- if (should_follow_link(dentry->d_inode,
- nd->flags & LOOKUP_FOLLOW))
- return 1;
- follow_mount(path);
- }
+done:
+ if (!dentry->d_inode) {
+ error = -ENOENT;
+ dput(dentry);
+ goto out;
}
+ path->dentry = dentry;
+ path->mnt = mntget(nd->path.mnt);
+ if (should_follow_link(dentry->d_inode, nd->flags & LOOKUP_FOLLOW))
+ return 1;
+ follow_mount(path);
+ error = 0;
+out:
terminate_walk(nd);
return error;
}
@@ -2334,15 +2337,6 @@ path_umountat(int dfd, const char *name, struct path *path, unsigned int flags)
if (err)
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);
while (err > 0) {
void *cookie;