diff options
Diffstat (limited to 'fs/ext4/ioctl.c')
-rw-r--r-- | fs/ext4/ioctl.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 91e75f7a9e73..bb415408fdb6 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
15 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
16 | #include <linux/mount.h> | 16 | #include <linux/mount.h> |
17 | #include <linux/file.h> | ||
17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
18 | #include "ext4_jbd2.h" | 19 | #include "ext4_jbd2.h" |
19 | #include "ext4.h" | 20 | #include "ext4.h" |
@@ -213,6 +214,41 @@ setversion_out: | |||
213 | 214 | ||
214 | return err; | 215 | return err; |
215 | } | 216 | } |
217 | |||
218 | case EXT4_IOC_MOVE_EXT: { | ||
219 | struct move_extent me; | ||
220 | struct file *donor_filp; | ||
221 | int err; | ||
222 | |||
223 | if (copy_from_user(&me, | ||
224 | (struct move_extent __user *)arg, sizeof(me))) | ||
225 | return -EFAULT; | ||
226 | |||
227 | donor_filp = fget(me.donor_fd); | ||
228 | if (!donor_filp) | ||
229 | return -EBADF; | ||
230 | |||
231 | if (!capable(CAP_DAC_OVERRIDE)) { | ||
232 | if ((current->real_cred->fsuid != inode->i_uid) || | ||
233 | !(inode->i_mode & S_IRUSR) || | ||
234 | !(donor_filp->f_dentry->d_inode->i_mode & | ||
235 | S_IRUSR)) { | ||
236 | fput(donor_filp); | ||
237 | return -EACCES; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | err = ext4_move_extents(filp, donor_filp, me.orig_start, | ||
242 | me.donor_start, me.len, &me.moved_len); | ||
243 | fput(donor_filp); | ||
244 | |||
245 | if (!err) | ||
246 | if (copy_to_user((struct move_extent *)arg, | ||
247 | &me, sizeof(me))) | ||
248 | return -EFAULT; | ||
249 | return err; | ||
250 | } | ||
251 | |||
216 | case EXT4_IOC_GROUP_ADD: { | 252 | case EXT4_IOC_GROUP_ADD: { |
217 | struct ext4_new_group_data input; | 253 | struct ext4_new_group_data input; |
218 | struct super_block *sb = inode->i_sb; | 254 | struct super_block *sb = inode->i_sb; |