Loading fs/namei.c +27 −33 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading Loading @@ -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; Loading Loading
fs/namei.c +27 −33 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading Loading @@ -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; Loading