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); |
