diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 82 |
1 files changed, 51 insertions, 31 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 956f1eb913b1..1562765c8e6a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -122,10 +122,10 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
122 | size_t cur_size = size; | 122 | size_t cur_size = size; |
123 | size_t datasize; | 123 | size_t datasize; |
124 | unsigned long offset; | 124 | unsigned long offset; |
125 | int use_compress = 0; | 125 | int compress_type = BTRFS_COMPRESS_NONE; |
126 | 126 | ||
127 | if (compressed_size && compressed_pages) { | 127 | if (compressed_size && compressed_pages) { |
128 | use_compress = 1; | 128 | compress_type = root->fs_info->compress_type; |
129 | cur_size = compressed_size; | 129 | cur_size = compressed_size; |
130 | } | 130 | } |
131 | 131 | ||
@@ -159,7 +159,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
159 | btrfs_set_file_extent_ram_bytes(leaf, ei, size); | 159 | btrfs_set_file_extent_ram_bytes(leaf, ei, size); |
160 | ptr = btrfs_file_extent_inline_start(ei); | 160 | ptr = btrfs_file_extent_inline_start(ei); |
161 | 161 | ||
162 | if (use_compress) { | 162 | if (compress_type != BTRFS_COMPRESS_NONE) { |
163 | struct page *cpage; | 163 | struct page *cpage; |
164 | int i = 0; | 164 | int i = 0; |
165 | while (compressed_size > 0) { | 165 | while (compressed_size > 0) { |
@@ -176,7 +176,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
176 | compressed_size -= cur_size; | 176 | compressed_size -= cur_size; |
177 | } | 177 | } |
178 | btrfs_set_file_extent_compression(leaf, ei, | 178 | btrfs_set_file_extent_compression(leaf, ei, |
179 | BTRFS_COMPRESS_ZLIB); | 179 | compress_type); |
180 | } else { | 180 | } else { |
181 | page = find_get_page(inode->i_mapping, | 181 | page = find_get_page(inode->i_mapping, |
182 | start >> PAGE_CACHE_SHIFT); | 182 | start >> PAGE_CACHE_SHIFT); |
@@ -263,6 +263,7 @@ struct async_extent { | |||
263 | u64 compressed_size; | 263 | u64 compressed_size; |
264 | struct page **pages; | 264 | struct page **pages; |
265 | unsigned long nr_pages; | 265 | unsigned long nr_pages; |
266 | int compress_type; | ||
266 | struct list_head list; | 267 | struct list_head list; |
267 | }; | 268 | }; |
268 | 269 | ||
@@ -280,7 +281,8 @@ static noinline int add_async_extent(struct async_cow *cow, | |||
280 | u64 start, u64 ram_size, | 281 | u64 start, u64 ram_size, |
281 | u64 compressed_size, | 282 | u64 compressed_size, |
282 | struct page **pages, | 283 | struct page **pages, |
283 | unsigned long nr_pages) | 284 | unsigned long nr_pages, |
285 | int compress_type) | ||
284 | { | 286 | { |
285 | struct async_extent *async_extent; | 287 | struct async_extent *async_extent; |
286 | 288 | ||
@@ -290,6 +292,7 @@ static noinline int add_async_extent(struct async_cow *cow, | |||
290 | async_extent->compressed_size = compressed_size; | 292 | async_extent->compressed_size = compressed_size; |
291 | async_extent->pages = pages; | 293 | async_extent->pages = pages; |
292 | async_extent->nr_pages = nr_pages; | 294 | async_extent->nr_pages = nr_pages; |
295 | async_extent->compress_type = compress_type; | ||
293 | list_add_tail(&async_extent->list, &cow->extents); | 296 | list_add_tail(&async_extent->list, &cow->extents); |
294 | return 0; | 297 | return 0; |
295 | } | 298 | } |
@@ -332,6 +335,7 @@ static noinline int compress_file_range(struct inode *inode, | |||
332 | unsigned long max_uncompressed = 128 * 1024; | 335 | unsigned long max_uncompressed = 128 * 1024; |
333 | int i; | 336 | int i; |
334 | int will_compress; | 337 | int will_compress; |
338 | int compress_type = root->fs_info->compress_type; | ||
335 | 339 | ||
336 | actual_end = min_t(u64, isize, end + 1); | 340 | actual_end = min_t(u64, isize, end + 1); |
337 | again: | 341 | again: |
@@ -381,12 +385,16 @@ again: | |||
381 | WARN_ON(pages); | 385 | WARN_ON(pages); |
382 | pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); | 386 | pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); |
383 | 387 | ||
384 | ret = btrfs_zlib_compress_pages(inode->i_mapping, start, | 388 | if (BTRFS_I(inode)->force_compress) |
385 | total_compressed, pages, | 389 | compress_type = BTRFS_I(inode)->force_compress; |
386 | nr_pages, &nr_pages_ret, | 390 | |
387 | &total_in, | 391 | ret = btrfs_compress_pages(compress_type, |
388 | &total_compressed, | 392 | inode->i_mapping, start, |
389 | max_compressed); | 393 | total_compressed, pages, |
394 | nr_pages, &nr_pages_ret, | ||
395 | &total_in, | ||
396 | &total_compressed, | ||
397 | max_compressed); | ||
390 | 398 | ||
391 | if (!ret) { | 399 | if (!ret) { |
392 | unsigned long offset = total_compressed & | 400 | unsigned long offset = total_compressed & |
@@ -493,7 +501,8 @@ again: | |||
493 | * and will submit them to the elevator. | 501 | * and will submit them to the elevator. |
494 | */ | 502 | */ |
495 | add_async_extent(async_cow, start, num_bytes, | 503 | add_async_extent(async_cow, start, num_bytes, |
496 | total_compressed, pages, nr_pages_ret); | 504 | total_compressed, pages, nr_pages_ret, |
505 | compress_type); | ||
497 | 506 | ||
498 | if (start + num_bytes < end) { | 507 | if (start + num_bytes < end) { |
499 | start += num_bytes; | 508 | start += num_bytes; |
@@ -515,7 +524,8 @@ cleanup_and_bail_uncompressed: | |||
515 | __set_page_dirty_nobuffers(locked_page); | 524 | __set_page_dirty_nobuffers(locked_page); |
516 | /* unlocked later on in the async handlers */ | 525 | /* unlocked later on in the async handlers */ |
517 | } | 526 | } |
518 | add_async_extent(async_cow, start, end - start + 1, 0, NULL, 0); | 527 | add_async_extent(async_cow, start, end - start + 1, |
528 | 0, NULL, 0, BTRFS_COMPRESS_NONE); | ||
519 | *num_added += 1; | 529 | *num_added += 1; |
520 | } | 530 | } |
521 | 531 | ||
@@ -640,6 +650,7 @@ retry: | |||
640 | em->block_start = ins.objectid; | 650 | em->block_start = ins.objectid; |
641 | em->block_len = ins.offset; | 651 | em->block_len = ins.offset; |
642 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 652 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
653 | em->compress_type = async_extent->compress_type; | ||
643 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 654 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
644 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 655 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
645 | 656 | ||
@@ -656,11 +667,13 @@ retry: | |||
656 | async_extent->ram_size - 1, 0); | 667 | async_extent->ram_size - 1, 0); |
657 | } | 668 | } |
658 | 669 | ||
659 | ret = btrfs_add_ordered_extent(inode, async_extent->start, | 670 | ret = btrfs_add_ordered_extent_compress(inode, |
660 | ins.objectid, | 671 | async_extent->start, |
661 | async_extent->ram_size, | 672 | ins.objectid, |
662 | ins.offset, | 673 | async_extent->ram_size, |
663 | BTRFS_ORDERED_COMPRESSED); | 674 | ins.offset, |
675 | BTRFS_ORDERED_COMPRESSED, | ||
676 | async_extent->compress_type); | ||
664 | BUG_ON(ret); | 677 | BUG_ON(ret); |
665 | 678 | ||
666 | /* | 679 | /* |
@@ -1670,7 +1683,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1670 | struct btrfs_ordered_extent *ordered_extent = NULL; | 1683 | struct btrfs_ordered_extent *ordered_extent = NULL; |
1671 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 1684 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
1672 | struct extent_state *cached_state = NULL; | 1685 | struct extent_state *cached_state = NULL; |
1673 | int compressed = 0; | 1686 | int compress_type = 0; |
1674 | int ret; | 1687 | int ret; |
1675 | bool nolock = false; | 1688 | bool nolock = false; |
1676 | 1689 | ||
@@ -1711,9 +1724,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1711 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1724 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
1712 | 1725 | ||
1713 | if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) | 1726 | if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) |
1714 | compressed = 1; | 1727 | compress_type = ordered_extent->compress_type; |
1715 | if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { | 1728 | if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { |
1716 | BUG_ON(compressed); | 1729 | BUG_ON(compress_type); |
1717 | ret = btrfs_mark_extent_written(trans, inode, | 1730 | ret = btrfs_mark_extent_written(trans, inode, |
1718 | ordered_extent->file_offset, | 1731 | ordered_extent->file_offset, |
1719 | ordered_extent->file_offset + | 1732 | ordered_extent->file_offset + |
@@ -1727,7 +1740,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1727 | ordered_extent->disk_len, | 1740 | ordered_extent->disk_len, |
1728 | ordered_extent->len, | 1741 | ordered_extent->len, |
1729 | ordered_extent->len, | 1742 | ordered_extent->len, |
1730 | compressed, 0, 0, | 1743 | compress_type, 0, 0, |
1731 | BTRFS_FILE_EXTENT_REG); | 1744 | BTRFS_FILE_EXTENT_REG); |
1732 | unpin_extent_cache(&BTRFS_I(inode)->extent_tree, | 1745 | unpin_extent_cache(&BTRFS_I(inode)->extent_tree, |
1733 | ordered_extent->file_offset, | 1746 | ordered_extent->file_offset, |
@@ -1829,6 +1842,8 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, | |||
1829 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) { | 1842 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) { |
1830 | logical = em->block_start; | 1843 | logical = em->block_start; |
1831 | failrec->bio_flags = EXTENT_BIO_COMPRESSED; | 1844 | failrec->bio_flags = EXTENT_BIO_COMPRESSED; |
1845 | extent_set_compress_type(&failrec->bio_flags, | ||
1846 | em->compress_type); | ||
1832 | } | 1847 | } |
1833 | failrec->logical = logical; | 1848 | failrec->logical = logical; |
1834 | free_extent_map(em); | 1849 | free_extent_map(em); |
@@ -4934,8 +4949,10 @@ static noinline int uncompress_inline(struct btrfs_path *path, | |||
4934 | size_t max_size; | 4949 | size_t max_size; |
4935 | unsigned long inline_size; | 4950 | unsigned long inline_size; |
4936 | unsigned long ptr; | 4951 | unsigned long ptr; |
4952 | int compress_type; | ||
4937 | 4953 | ||
4938 | WARN_ON(pg_offset != 0); | 4954 | WARN_ON(pg_offset != 0); |
4955 | compress_type = btrfs_file_extent_compression(leaf, item); | ||
4939 | max_size = btrfs_file_extent_ram_bytes(leaf, item); | 4956 | max_size = btrfs_file_extent_ram_bytes(leaf, item); |
4940 | inline_size = btrfs_file_extent_inline_item_len(leaf, | 4957 | inline_size = btrfs_file_extent_inline_item_len(leaf, |
4941 | btrfs_item_nr(leaf, path->slots[0])); | 4958 | btrfs_item_nr(leaf, path->slots[0])); |
@@ -4945,8 +4962,8 @@ static noinline int uncompress_inline(struct btrfs_path *path, | |||
4945 | read_extent_buffer(leaf, tmp, ptr, inline_size); | 4962 | read_extent_buffer(leaf, tmp, ptr, inline_size); |
4946 | 4963 | ||
4947 | max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size); | 4964 | max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size); |
4948 | ret = btrfs_zlib_decompress(tmp, page, extent_offset, | 4965 | ret = btrfs_decompress(compress_type, tmp, page, |
4949 | inline_size, max_size); | 4966 | extent_offset, inline_size, max_size); |
4950 | if (ret) { | 4967 | if (ret) { |
4951 | char *kaddr = kmap_atomic(page, KM_USER0); | 4968 | char *kaddr = kmap_atomic(page, KM_USER0); |
4952 | unsigned long copy_size = min_t(u64, | 4969 | unsigned long copy_size = min_t(u64, |
@@ -4988,7 +5005,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
4988 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 5005 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
4989 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 5006 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
4990 | struct btrfs_trans_handle *trans = NULL; | 5007 | struct btrfs_trans_handle *trans = NULL; |
4991 | int compressed; | 5008 | int compress_type; |
4992 | 5009 | ||
4993 | again: | 5010 | again: |
4994 | read_lock(&em_tree->lock); | 5011 | read_lock(&em_tree->lock); |
@@ -5047,7 +5064,7 @@ again: | |||
5047 | 5064 | ||
5048 | found_type = btrfs_file_extent_type(leaf, item); | 5065 | found_type = btrfs_file_extent_type(leaf, item); |
5049 | extent_start = found_key.offset; | 5066 | extent_start = found_key.offset; |
5050 | compressed = btrfs_file_extent_compression(leaf, item); | 5067 | compress_type = btrfs_file_extent_compression(leaf, item); |
5051 | if (found_type == BTRFS_FILE_EXTENT_REG || | 5068 | if (found_type == BTRFS_FILE_EXTENT_REG || |
5052 | found_type == BTRFS_FILE_EXTENT_PREALLOC) { | 5069 | found_type == BTRFS_FILE_EXTENT_PREALLOC) { |
5053 | extent_end = extent_start + | 5070 | extent_end = extent_start + |
@@ -5093,8 +5110,9 @@ again: | |||
5093 | em->block_start = EXTENT_MAP_HOLE; | 5110 | em->block_start = EXTENT_MAP_HOLE; |
5094 | goto insert; | 5111 | goto insert; |
5095 | } | 5112 | } |
5096 | if (compressed) { | 5113 | if (compress_type != BTRFS_COMPRESS_NONE) { |
5097 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 5114 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
5115 | em->compress_type = compress_type; | ||
5098 | em->block_start = bytenr; | 5116 | em->block_start = bytenr; |
5099 | em->block_len = btrfs_file_extent_disk_num_bytes(leaf, | 5117 | em->block_len = btrfs_file_extent_disk_num_bytes(leaf, |
5100 | item); | 5118 | item); |
@@ -5128,12 +5146,14 @@ again: | |||
5128 | em->len = (copy_size + root->sectorsize - 1) & | 5146 | em->len = (copy_size + root->sectorsize - 1) & |
5129 | ~((u64)root->sectorsize - 1); | 5147 | ~((u64)root->sectorsize - 1); |
5130 | em->orig_start = EXTENT_MAP_INLINE; | 5148 | em->orig_start = EXTENT_MAP_INLINE; |
5131 | if (compressed) | 5149 | if (compress_type) { |
5132 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 5150 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
5151 | em->compress_type = compress_type; | ||
5152 | } | ||
5133 | ptr = btrfs_file_extent_inline_start(item) + extent_offset; | 5153 | ptr = btrfs_file_extent_inline_start(item) + extent_offset; |
5134 | if (create == 0 && !PageUptodate(page)) { | 5154 | if (create == 0 && !PageUptodate(page)) { |
5135 | if (btrfs_file_extent_compression(leaf, item) == | 5155 | if (btrfs_file_extent_compression(leaf, item) != |
5136 | BTRFS_COMPRESS_ZLIB) { | 5156 | BTRFS_COMPRESS_NONE) { |
5137 | ret = uncompress_inline(path, inode, page, | 5157 | ret = uncompress_inline(path, inode, page, |
5138 | pg_offset, | 5158 | pg_offset, |
5139 | extent_offset, item); | 5159 | extent_offset, item); |
@@ -6483,7 +6503,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
6483 | ei->ordered_data_close = 0; | 6503 | ei->ordered_data_close = 0; |
6484 | ei->orphan_meta_reserved = 0; | 6504 | ei->orphan_meta_reserved = 0; |
6485 | ei->dummy_inode = 0; | 6505 | ei->dummy_inode = 0; |
6486 | ei->force_compress = 0; | 6506 | ei->force_compress = BTRFS_COMPRESS_NONE; |
6487 | 6507 | ||
6488 | inode = &ei->vfs_inode; | 6508 | inode = &ei->vfs_inode; |
6489 | extent_map_tree_init(&ei->extent_tree, GFP_NOFS); | 6509 | extent_map_tree_init(&ei->extent_tree, GFP_NOFS); |