diff options
-rw-r--r-- | fs/ext4/ext4.h | 3 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 21 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 10 |
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); | |||
1084 | extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); | 1084 | extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); |
1085 | 1085 | ||
1086 | /* migrate.c */ | 1086 | /* migrate.c */ |
1087 | extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int, | 1087 | extern int ext4_ext_migrate(struct inode *); |
1088 | unsigned long); | ||
1089 | /* namei.c */ | 1088 | /* namei.c */ |
1090 | extern int ext4_orphan_add(handle_t *, struct inode *); | 1089 | extern int ext4_orphan_add(handle_t *, struct inode *); |
1091 | extern int ext4_orphan_del(handle_t *, struct inode *); | 1090 | extern 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 | ||
450 | int ext4_ext_migrate(struct inode *inode, struct file *filp, | 450 | int 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); |