summaryrefslogtreecommitdiff
path: root/fs/ext4/ioctl.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-18 10:40:25 -0800
committerSage Weil <sage@newdream.net>2010-02-18 10:40:25 -0800
commiteb9bbff08c35a99f82c5b414b833cec4321c4167 (patch)
tree5063cdf9059e1d8aad9b42cb1229944eceed5337 /fs/ext4/ioctl.c
parent2c27c9a57c93a0757b9b4b0e7dc1abeaf1db1ce2 (diff)
parent716c28c0bc8bcbdd26e819f38dfc8fdfaafc0289 (diff)
Merge remote branch 'vfs/write_inode' into for-next
Conflicts: Documentation/ioctl/ioctl-number.txt
Diffstat (limited to 'fs/ext4/ioctl.c')
-rw-r--r--fs/ext4/ioctl.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index c1cdf613e725..b63d193126db 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -221,31 +221,38 @@ setversion_out:
struct file *donor_filp;
int err;
+ if (!(filp->f_mode & FMODE_READ) ||
+ !(filp->f_mode & FMODE_WRITE))
+ return -EBADF;
+
if (copy_from_user(&me,
(struct move_extent __user *)arg, sizeof(me)))
return -EFAULT;
+ me.moved_len = 0;
donor_filp = fget(me.donor_fd);
if (!donor_filp)
return -EBADF;
- if (!capable(CAP_DAC_OVERRIDE)) {
- if ((current->real_cred->fsuid != inode->i_uid) ||
- !(inode->i_mode & S_IRUSR) ||
- !(donor_filp->f_dentry->d_inode->i_mode &
- S_IRUSR)) {
- fput(donor_filp);
- return -EACCES;
- }
+ if (!(donor_filp->f_mode & FMODE_WRITE)) {
+ err = -EBADF;
+ goto mext_out;
}
+ err = mnt_want_write(filp->f_path.mnt);
+ if (err)
+ goto mext_out;
+
err = ext4_move_extents(filp, donor_filp, me.orig_start,
me.donor_start, me.len, &me.moved_len);
- fput(donor_filp);
+ mnt_drop_write(filp->f_path.mnt);
+ if (me.moved_len > 0)
+ file_remove_suid(donor_filp);
if (copy_to_user((struct move_extent *)arg, &me, sizeof(me)))
- return -EFAULT;
-
+ err = -EFAULT;
+mext_out:
+ fput(donor_filp);
return err;
}