mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
pull mnt_want_write()/mnt_drop_write() into kern_path_create()/done_path_create() resp.
One side effect - attempt to create a cross-device link on a read-only fs fails with EROFS instead of EXDEV now. Makes more sense, POSIX allows, etc. Change-Id: I264b03a230dbd310f3b3671d2da06ceb2930179b Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
9d58c3048f
commit
579400a5b2
3 changed files with 18 additions and 49 deletions
52
fs/namei.c
52
fs/namei.c
|
@ -2905,10 +2905,11 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path
|
|||
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
|
||||
dentry = lookup_hash(&nd);
|
||||
if (IS_ERR(dentry))
|
||||
goto fail;
|
||||
goto unlock;
|
||||
|
||||
error = -EEXIST;
|
||||
if (dentry->d_inode)
|
||||
goto eexist;
|
||||
goto fail;
|
||||
/*
|
||||
* Special case - lookup gave negative, but... we had foo/bar/
|
||||
* From the vfs_mknod() POV we just have a negative dentry -
|
||||
|
@ -2916,16 +2917,18 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path
|
|||
* been asking for (non-existent) directory. -ENOENT for you.
|
||||
*/
|
||||
if (unlikely(!is_dir && nd.last.name[nd.last.len])) {
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-ENOENT);
|
||||
error = -ENOENT;
|
||||
goto fail;
|
||||
}
|
||||
error = mnt_want_write(nd.path.mnt);
|
||||
if (error)
|
||||
goto fail;
|
||||
*path = nd.path;
|
||||
return dentry;
|
||||
eexist:
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(-EEXIST);
|
||||
fail:
|
||||
dput(dentry);
|
||||
dentry = ERR_PTR(error);
|
||||
unlock:
|
||||
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
|
||||
out:
|
||||
path_put(&nd.path);
|
||||
|
@ -2937,6 +2940,7 @@ void done_path_create(struct path *path, struct dentry *dentry)
|
|||
{
|
||||
dput(dentry);
|
||||
mutex_unlock(&path->dentry->d_inode->i_mutex);
|
||||
mnt_drop_write(path->mnt);
|
||||
path_put(path);
|
||||
}
|
||||
EXPORT_SYMBOL(done_path_create);
|
||||
|
@ -3021,12 +3025,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
|
|||
|
||||
if (!IS_POSIXACL(path.dentry->d_inode))
|
||||
mode &= ~current_umask();
|
||||
error = mnt_want_write(path.mnt);
|
||||
if (error)
|
||||
goto out_dput;
|
||||
error = security_path_mknod(&path, dentry, mode, dev);
|
||||
if (error)
|
||||
goto out_drop_write;
|
||||
goto out;
|
||||
switch (mode & S_IFMT) {
|
||||
case 0: case S_IFREG:
|
||||
error = vfs_create2(path.mnt, path.dentry->d_inode,dentry,mode,true);
|
||||
|
@ -3039,9 +3040,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
|
|||
error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
|
||||
break;
|
||||
}
|
||||
out_drop_write:
|
||||
mnt_drop_write(path.mnt);
|
||||
out_dput:
|
||||
out:
|
||||
done_path_create(&path, dentry);
|
||||
|
||||
return error;
|
||||
|
@ -3096,16 +3095,9 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
|
|||
|
||||
if (!IS_POSIXACL(path.dentry->d_inode))
|
||||
mode &= ~current_umask();
|
||||
error = mnt_want_write(path.mnt);
|
||||
if (error)
|
||||
goto out_dput;
|
||||
error = security_path_mkdir(&path, dentry, mode);
|
||||
if (error)
|
||||
goto out_drop_write;
|
||||
if (!error)
|
||||
error = vfs_mkdir2(path.mnt, path.dentry->d_inode, dentry, mode);
|
||||
out_drop_write:
|
||||
mnt_drop_write(path.mnt);
|
||||
out_dput:
|
||||
done_path_create(&path, dentry);
|
||||
return error;
|
||||
}
|
||||
|
@ -3401,16 +3393,9 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
|
|||
if (IS_ERR(dentry))
|
||||
goto out_putname;
|
||||
|
||||
error = mnt_want_write(path.mnt);
|
||||
if (error)
|
||||
goto out_dput;
|
||||
error = security_path_symlink(&path, dentry, from);
|
||||
if (error)
|
||||
goto out_drop_write;
|
||||
if (!error)
|
||||
error = vfs_symlink2(path.mnt, path.dentry->d_inode, dentry, from);
|
||||
out_drop_write:
|
||||
mnt_drop_write(path.mnt);
|
||||
out_dput:
|
||||
done_path_create(&path, dentry);
|
||||
out_putname:
|
||||
putname(from);
|
||||
|
@ -3518,15 +3503,10 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
|
|||
error = -EXDEV;
|
||||
if (old_path.mnt != new_path.mnt)
|
||||
goto out_dput;
|
||||
error = mnt_want_write(new_path.mnt);
|
||||
if (error)
|
||||
goto out_dput;
|
||||
error = security_path_link(old_path.dentry, &new_path, new_dentry);
|
||||
if (error)
|
||||
goto out_drop_write;
|
||||
goto out_dput;
|
||||
error = vfs_link2(old_path.mnt, old_path.dentry, new_path.dentry->d_inode, new_dentry);
|
||||
out_drop_write:
|
||||
mnt_drop_write(new_path.mnt);
|
||||
out_dput:
|
||||
done_path_create(&new_path, new_dentry);
|
||||
out:
|
||||
|
|
|
@ -4466,16 +4466,9 @@ int ocfs2_reflink_ioctl(struct inode *inode,
|
|||
goto out_dput;
|
||||
}
|
||||
|
||||
error = mnt_want_write(new_path.mnt);
|
||||
if (error) {
|
||||
mlog_errno(error);
|
||||
goto out_dput;
|
||||
}
|
||||
|
||||
error = ocfs2_vfs_reflink(old_path.dentry,
|
||||
new_path.dentry->d_inode,
|
||||
new_dentry, preserve);
|
||||
mnt_drop_write(new_path.mnt);
|
||||
out_dput:
|
||||
done_path_create(&new_path, new_dentry);
|
||||
out:
|
||||
|
|
|
@ -998,15 +998,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
*/
|
||||
mode = S_IFSOCK |
|
||||
(SOCK_INODE(sock)->i_mode & ~current_umask());
|
||||
err = mnt_want_write(path.mnt);
|
||||
if (err)
|
||||
goto out_mknod_dput;
|
||||
err = security_path_mknod(&path, dentry, mode, 0);
|
||||
if (err)
|
||||
goto out_mknod_drop_write;
|
||||
err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
|
||||
out_mknod_drop_write:
|
||||
mnt_drop_write(path.mnt);
|
||||
if (err)
|
||||
goto out_mknod_dput;
|
||||
mntget(path.mnt);
|
||||
|
|
Loading…
Reference in a new issue