aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/ioctl.c')
-rw-r--r--fs/ext4/ioctl.c36
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;