diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ad1983524f97..a506a22b522a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -643,9 +643,11 @@ static int btrfs_defrag_file(struct file *file, | |||
643 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 643 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
644 | struct btrfs_ordered_extent *ordered; | 644 | struct btrfs_ordered_extent *ordered; |
645 | struct page *page; | 645 | struct page *page; |
646 | struct btrfs_super_block *disk_super; | ||
646 | unsigned long last_index; | 647 | unsigned long last_index; |
647 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; | 648 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; |
648 | unsigned long total_read = 0; | 649 | unsigned long total_read = 0; |
650 | u64 features; | ||
649 | u64 page_start; | 651 | u64 page_start; |
650 | u64 page_end; | 652 | u64 page_end; |
651 | u64 last_len = 0; | 653 | u64 last_len = 0; |
@@ -653,6 +655,14 @@ static int btrfs_defrag_file(struct file *file, | |||
653 | u64 defrag_end = 0; | 655 | u64 defrag_end = 0; |
654 | unsigned long i; | 656 | unsigned long i; |
655 | int ret; | 657 | int ret; |
658 | int compress_type = BTRFS_COMPRESS_ZLIB; | ||
659 | |||
660 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) { | ||
661 | if (range->compress_type > BTRFS_COMPRESS_TYPES) | ||
662 | return -EINVAL; | ||
663 | if (range->compress_type) | ||
664 | compress_type = range->compress_type; | ||
665 | } | ||
656 | 666 | ||
657 | if (inode->i_size == 0) | 667 | if (inode->i_size == 0) |
658 | return 0; | 668 | return 0; |
@@ -688,7 +698,7 @@ static int btrfs_defrag_file(struct file *file, | |||
688 | total_read++; | 698 | total_read++; |
689 | mutex_lock(&inode->i_mutex); | 699 | mutex_lock(&inode->i_mutex); |
690 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) | 700 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) |
691 | BTRFS_I(inode)->force_compress = 1; | 701 | BTRFS_I(inode)->force_compress = compress_type; |
692 | 702 | ||
693 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 703 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
694 | if (ret) | 704 | if (ret) |
@@ -786,10 +796,17 @@ loop_unlock: | |||
786 | atomic_dec(&root->fs_info->async_submit_draining); | 796 | atomic_dec(&root->fs_info->async_submit_draining); |
787 | 797 | ||
788 | mutex_lock(&inode->i_mutex); | 798 | mutex_lock(&inode->i_mutex); |
789 | BTRFS_I(inode)->force_compress = 0; | 799 | BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE; |
790 | mutex_unlock(&inode->i_mutex); | 800 | mutex_unlock(&inode->i_mutex); |
791 | } | 801 | } |
792 | 802 | ||
803 | disk_super = &root->fs_info->super_copy; | ||
804 | features = btrfs_super_incompat_flags(disk_super); | ||
805 | if (range->compress_type == BTRFS_COMPRESS_LZO) { | ||
806 | features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; | ||
807 | btrfs_set_super_incompat_flags(disk_super, features); | ||
808 | } | ||
809 | |||
793 | return 0; | 810 | return 0; |
794 | 811 | ||
795 | err_reservations: | 812 | err_reservations: |