diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ioctl.c | 19 | ||||
-rw-r--r-- | fs/btrfs/ioctl.h | 9 |
2 files changed, 26 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 8cb86d4d763c..b6985d33eede 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -638,9 +638,11 @@ static int btrfs_defrag_file(struct file *file, | |||
638 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 638 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
639 | struct btrfs_ordered_extent *ordered; | 639 | struct btrfs_ordered_extent *ordered; |
640 | struct page *page; | 640 | struct page *page; |
641 | struct btrfs_super_block *disk_super; | ||
641 | unsigned long last_index; | 642 | unsigned long last_index; |
642 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; | 643 | unsigned long ra_pages = root->fs_info->bdi.ra_pages; |
643 | unsigned long total_read = 0; | 644 | unsigned long total_read = 0; |
645 | u64 features; | ||
644 | u64 page_start; | 646 | u64 page_start; |
645 | u64 page_end; | 647 | u64 page_end; |
646 | u64 last_len = 0; | 648 | u64 last_len = 0; |
@@ -648,6 +650,14 @@ static int btrfs_defrag_file(struct file *file, | |||
648 | u64 defrag_end = 0; | 650 | u64 defrag_end = 0; |
649 | unsigned long i; | 651 | unsigned long i; |
650 | int ret; | 652 | int ret; |
653 | int compress_type = BTRFS_COMPRESS_ZLIB; | ||
654 | |||
655 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) { | ||
656 | if (range->compress_type > BTRFS_COMPRESS_TYPES) | ||
657 | return -EINVAL; | ||
658 | if (range->compress_type) | ||
659 | compress_type = range->compress_type; | ||
660 | } | ||
651 | 661 | ||
652 | if (inode->i_size == 0) | 662 | if (inode->i_size == 0) |
653 | return 0; | 663 | return 0; |
@@ -683,7 +693,7 @@ static int btrfs_defrag_file(struct file *file, | |||
683 | total_read++; | 693 | total_read++; |
684 | mutex_lock(&inode->i_mutex); | 694 | mutex_lock(&inode->i_mutex); |
685 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) | 695 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) |
686 | BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_ZLIB; | 696 | BTRFS_I(inode)->force_compress = compress_type; |
687 | 697 | ||
688 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 698 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
689 | if (ret) | 699 | if (ret) |
@@ -785,6 +795,13 @@ loop_unlock: | |||
785 | mutex_unlock(&inode->i_mutex); | 795 | mutex_unlock(&inode->i_mutex); |
786 | } | 796 | } |
787 | 797 | ||
798 | disk_super = &root->fs_info->super_copy; | ||
799 | features = btrfs_super_incompat_flags(disk_super); | ||
800 | if (range->compress_type == BTRFS_COMPRESS_LZO) { | ||
801 | features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; | ||
802 | btrfs_set_super_incompat_flags(disk_super, features); | ||
803 | } | ||
804 | |||
788 | return 0; | 805 | return 0; |
789 | 806 | ||
790 | err_reservations: | 807 | err_reservations: |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index c344d12c646b..24d0f4628240 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
@@ -133,8 +133,15 @@ struct btrfs_ioctl_defrag_range_args { | |||
133 | */ | 133 | */ |
134 | __u32 extent_thresh; | 134 | __u32 extent_thresh; |
135 | 135 | ||
136 | /* | ||
137 | * which compression method to use if turning on compression | ||
138 | * for this defrag operation. If unspecified, zlib will | ||
139 | * be used | ||
140 | */ | ||
141 | __u32 compress_type; | ||
142 | |||
136 | /* spare for later */ | 143 | /* spare for later */ |
137 | __u32 unused[5]; | 144 | __u32 unused[4]; |
138 | }; | 145 | }; |
139 | 146 | ||
140 | struct btrfs_ioctl_space_info { | 147 | struct btrfs_ioctl_space_info { |