|
@@ -638,9 +638,11 @@ static int btrfs_defrag_file(struct file *file,
|
|
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
|
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
|
struct btrfs_ordered_extent *ordered;
|
|
struct btrfs_ordered_extent *ordered;
|
|
struct page *page;
|
|
struct page *page;
|
|
|
|
+ struct btrfs_super_block *disk_super;
|
|
unsigned long last_index;
|
|
unsigned long last_index;
|
|
unsigned long ra_pages = root->fs_info->bdi.ra_pages;
|
|
unsigned long ra_pages = root->fs_info->bdi.ra_pages;
|
|
unsigned long total_read = 0;
|
|
unsigned long total_read = 0;
|
|
|
|
+ u64 features;
|
|
u64 page_start;
|
|
u64 page_start;
|
|
u64 page_end;
|
|
u64 page_end;
|
|
u64 last_len = 0;
|
|
u64 last_len = 0;
|
|
@@ -648,6 +650,14 @@ static int btrfs_defrag_file(struct file *file,
|
|
u64 defrag_end = 0;
|
|
u64 defrag_end = 0;
|
|
unsigned long i;
|
|
unsigned long i;
|
|
int ret;
|
|
int ret;
|
|
|
|
+ int compress_type = BTRFS_COMPRESS_ZLIB;
|
|
|
|
+
|
|
|
|
+ if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) {
|
|
|
|
+ if (range->compress_type > BTRFS_COMPRESS_TYPES)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (range->compress_type)
|
|
|
|
+ compress_type = range->compress_type;
|
|
|
|
+ }
|
|
|
|
|
|
if (inode->i_size == 0)
|
|
if (inode->i_size == 0)
|
|
return 0;
|
|
return 0;
|
|
@@ -683,7 +693,7 @@ static int btrfs_defrag_file(struct file *file,
|
|
total_read++;
|
|
total_read++;
|
|
mutex_lock(&inode->i_mutex);
|
|
mutex_lock(&inode->i_mutex);
|
|
if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
|
|
if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
|
|
- BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_ZLIB;
|
|
|
|
|
|
+ BTRFS_I(inode)->force_compress = compress_type;
|
|
|
|
|
|
ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
|
|
ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
|
|
if (ret)
|
|
if (ret)
|
|
@@ -785,6 +795,13 @@ loop_unlock:
|
|
mutex_unlock(&inode->i_mutex);
|
|
mutex_unlock(&inode->i_mutex);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ disk_super = &root->fs_info->super_copy;
|
|
|
|
+ features = btrfs_super_incompat_flags(disk_super);
|
|
|
|
+ if (range->compress_type == BTRFS_COMPRESS_LZO) {
|
|
|
|
+ features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
|
|
|
|
+ btrfs_set_super_incompat_flags(disk_super, features);
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
err_reservations:
|
|
err_reservations:
|