aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/ioctl.c21
-rw-r--r--fs/ext4/migrate.c10
3 files changed, 22 insertions, 12 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 3e47b99a763c..9b6ad8f19bc9 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1084,8 +1084,7 @@ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
1084extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); 1084extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
1085 1085
1086/* migrate.c */ 1086/* migrate.c */
1087extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int, 1087extern int ext4_ext_migrate(struct inode *);
1088 unsigned long);
1089/* namei.c */ 1088/* namei.c */
1090extern int ext4_orphan_add(handle_t *, struct inode *); 1089extern int ext4_orphan_add(handle_t *, struct inode *);
1091extern int ext4_orphan_del(handle_t *, struct inode *); 1090extern int ext4_orphan_del(handle_t *, struct inode *);
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index ca09dd1039ec..9f3044ac6994 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -267,7 +267,26 @@ setversion_out:
267 } 267 }
268 268
269 case EXT4_IOC_MIGRATE: 269 case EXT4_IOC_MIGRATE:
270 return ext4_ext_migrate(inode, filp, cmd, arg); 270 {
271 int err;
272 if (!is_owner_or_cap(inode))
273 return -EACCES;
274
275 err = mnt_want_write(filp->f_path.mnt);
276 if (err)
277 return err;
278 /*
279 * inode_mutex prevent write and truncate on the file.
280 * Read still goes through. We take i_data_sem in
281 * ext4_ext_swap_inode_data before we switch the
282 * inode format to prevent read.
283 */
284 mutex_lock(&(inode->i_mutex));
285 err = ext4_ext_migrate(inode);
286 mutex_unlock(&(inode->i_mutex));
287 mnt_drop_write(filp->f_path.mnt);
288 return err;
289 }
271 290
272 default: 291 default:
273 return -ENOTTY; 292 return -ENOTTY;
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 46fc0b5b12ba..f2a9cf498ecd 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -447,8 +447,7 @@ static int free_ext_block(handle_t *handle, struct inode *inode)
447 447
448} 448}
449 449
450int ext4_ext_migrate(struct inode *inode, struct file *filp, 450int ext4_ext_migrate(struct inode *inode)
451 unsigned int cmd, unsigned long arg)
452{ 451{
453 handle_t *handle; 452 handle_t *handle;
454 int retval = 0, i; 453 int retval = 0, i;
@@ -516,12 +515,6 @@ int ext4_ext_migrate(struct inode *inode, struct file *filp,
516 * when we add extents we extent the journal 515 * when we add extents we extent the journal
517 */ 516 */
518 /* 517 /*
519 * inode_mutex prevent write and truncate on the file. Read still goes
520 * through. We take i_data_sem in ext4_ext_swap_inode_data before we
521 * switch the inode format to prevent read.
522 */
523 mutex_lock(&(inode->i_mutex));
524 /*
525 * Even though we take i_mutex we can still cause block allocation 518 * Even though we take i_mutex we can still cause block allocation
526 * via mmap write to holes. If we have allocated new blocks we fail 519 * via mmap write to holes. If we have allocated new blocks we fail
527 * migrate. New block allocation will clear EXT4_EXT_MIGRATE flag. 520 * migrate. New block allocation will clear EXT4_EXT_MIGRATE flag.
@@ -623,7 +616,6 @@ err_out:
623 tmp_inode->i_nlink = 0; 616 tmp_inode->i_nlink = 0;
624 617
625 ext4_journal_stop(handle); 618 ext4_journal_stop(handle);
626 mutex_unlock(&(inode->i_mutex));
627 619
628 if (tmp_inode) 620 if (tmp_inode)
629 iput(tmp_inode); 621 iput(tmp_inode);