aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2010-12-17 01:21:50 -0500
committerLi Zefan <lizf@cn.fujitsu.com>2010-12-22 10:15:45 -0500
commit261507a02ccba9afda919852263b6bc1581ce1ef (patch)
treec16bc657ff4e29a87042ceb379487f24dff01035 /fs/btrfs/inode.c
parent4b72029dc3fd6ba7dc45ccd1cf0aa0ebfa209bd3 (diff)
btrfs: Allow to add new compression algorithm
Make the code aware of compression type, instead of always assuming zlib compression. Also make the zlib workspace function as common code for all compression types. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c82
1 files changed, 51 insertions, 31 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5f9194438f7c..ba563b2a5d6c 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);
337again: 341again:
@@ -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);
@@ -4930,8 +4945,10 @@ static noinline int uncompress_inline(struct btrfs_path *path,
4930 size_t max_size; 4945 size_t max_size;
4931 unsigned long inline_size; 4946 unsigned long inline_size;
4932 unsigned long ptr; 4947 unsigned long ptr;
4948 int compress_type;
4933 4949
4934 WARN_ON(pg_offset != 0); 4950 WARN_ON(pg_offset != 0);
4951 compress_type = btrfs_file_extent_compression(leaf, item);
4935 max_size = btrfs_file_extent_ram_bytes(leaf, item); 4952 max_size = btrfs_file_extent_ram_bytes(leaf, item);
4936 inline_size = btrfs_file_extent_inline_item_len(leaf, 4953 inline_size = btrfs_file_extent_inline_item_len(leaf,
4937 btrfs_item_nr(leaf, path->slots[0])); 4954 btrfs_item_nr(leaf, path->slots[0]));
@@ -4941,8 +4958,8 @@ static noinline int uncompress_inline(struct btrfs_path *path,
4941 read_extent_buffer(leaf, tmp, ptr, inline_size); 4958 read_extent_buffer(leaf, tmp, ptr, inline_size);
4942 4959
4943 max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size); 4960 max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size);
4944 ret = btrfs_zlib_decompress(tmp, page, extent_offset, 4961 ret = btrfs_decompress(compress_type, tmp, page,
4945 inline_size, max_size); 4962 extent_offset, inline_size, max_size);
4946 if (ret) { 4963 if (ret) {
4947 char *kaddr = kmap_atomic(page, KM_USER0); 4964 char *kaddr = kmap_atomic(page, KM_USER0);
4948 unsigned long copy_size = min_t(u64, 4965 unsigned long copy_size = min_t(u64,
@@ -4984,7 +5001,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
4984 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; 5001 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
4985 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 5002 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
4986 struct btrfs_trans_handle *trans = NULL; 5003 struct btrfs_trans_handle *trans = NULL;
4987 int compressed; 5004 int compress_type;
4988 5005
4989again: 5006again:
4990 read_lock(&em_tree->lock); 5007 read_lock(&em_tree->lock);
@@ -5043,7 +5060,7 @@ again:
5043 5060
5044 found_type = btrfs_file_extent_type(leaf, item); 5061 found_type = btrfs_file_extent_type(leaf, item);
5045 extent_start = found_key.offset; 5062 extent_start = found_key.offset;
5046 compressed = btrfs_file_extent_compression(leaf, item); 5063 compress_type = btrfs_file_extent_compression(leaf, item);
5047 if (found_type == BTRFS_FILE_EXTENT_REG || 5064 if (found_type == BTRFS_FILE_EXTENT_REG ||
5048 found_type == BTRFS_FILE_EXTENT_PREALLOC) { 5065 found_type == BTRFS_FILE_EXTENT_PREALLOC) {
5049 extent_end = extent_start + 5066 extent_end = extent_start +
@@ -5089,8 +5106,9 @@ again:
5089 em->block_start = EXTENT_MAP_HOLE; 5106 em->block_start = EXTENT_MAP_HOLE;
5090 goto insert; 5107 goto insert;
5091 } 5108 }
5092 if (compressed) { 5109 if (compress_type != BTRFS_COMPRESS_NONE) {
5093 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); 5110 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
5111 em->compress_type = compress_type;
5094 em->block_start = bytenr; 5112 em->block_start = bytenr;
5095 em->block_len = btrfs_file_extent_disk_num_bytes(leaf, 5113 em->block_len = btrfs_file_extent_disk_num_bytes(leaf,
5096 item); 5114 item);
@@ -5124,12 +5142,14 @@ again:
5124 em->len = (copy_size + root->sectorsize - 1) & 5142 em->len = (copy_size + root->sectorsize - 1) &
5125 ~((u64)root->sectorsize - 1); 5143 ~((u64)root->sectorsize - 1);
5126 em->orig_start = EXTENT_MAP_INLINE; 5144 em->orig_start = EXTENT_MAP_INLINE;
5127 if (compressed) 5145 if (compress_type) {
5128 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); 5146 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
5147 em->compress_type = compress_type;
5148 }
5129 ptr = btrfs_file_extent_inline_start(item) + extent_offset; 5149 ptr = btrfs_file_extent_inline_start(item) + extent_offset;
5130 if (create == 0 && !PageUptodate(page)) { 5150 if (create == 0 && !PageUptodate(page)) {
5131 if (btrfs_file_extent_compression(leaf, item) == 5151 if (btrfs_file_extent_compression(leaf, item) !=
5132 BTRFS_COMPRESS_ZLIB) { 5152 BTRFS_COMPRESS_NONE) {
5133 ret = uncompress_inline(path, inode, page, 5153 ret = uncompress_inline(path, inode, page,
5134 pg_offset, 5154 pg_offset,
5135 extent_offset, item); 5155 extent_offset, item);
@@ -6479,7 +6499,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
6479 ei->ordered_data_close = 0; 6499 ei->ordered_data_close = 0;
6480 ei->orphan_meta_reserved = 0; 6500 ei->orphan_meta_reserved = 0;
6481 ei->dummy_inode = 0; 6501 ei->dummy_inode = 0;
6482 ei->force_compress = 0; 6502 ei->force_compress = BTRFS_COMPRESS_NONE;
6483 6503
6484 inode = &ei->vfs_inode; 6504 inode = &ei->vfs_inode;
6485 extent_map_tree_init(&ei->extent_tree, GFP_NOFS); 6505 extent_map_tree_init(&ei->extent_tree, GFP_NOFS);