|
@@ -122,10 +122,10 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
|
|
size_t cur_size = size;
|
|
size_t cur_size = size;
|
|
size_t datasize;
|
|
size_t datasize;
|
|
unsigned long offset;
|
|
unsigned long offset;
|
|
- int use_compress = 0;
|
|
|
|
|
|
+ int compress_type = BTRFS_COMPRESS_NONE;
|
|
|
|
|
|
if (compressed_size && compressed_pages) {
|
|
if (compressed_size && compressed_pages) {
|
|
- use_compress = 1;
|
|
|
|
|
|
+ compress_type = root->fs_info->compress_type;
|
|
cur_size = compressed_size;
|
|
cur_size = compressed_size;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -159,7 +159,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
|
|
btrfs_set_file_extent_ram_bytes(leaf, ei, size);
|
|
btrfs_set_file_extent_ram_bytes(leaf, ei, size);
|
|
ptr = btrfs_file_extent_inline_start(ei);
|
|
ptr = btrfs_file_extent_inline_start(ei);
|
|
|
|
|
|
- if (use_compress) {
|
|
|
|
|
|
+ if (compress_type != BTRFS_COMPRESS_NONE) {
|
|
struct page *cpage;
|
|
struct page *cpage;
|
|
int i = 0;
|
|
int i = 0;
|
|
while (compressed_size > 0) {
|
|
while (compressed_size > 0) {
|
|
@@ -176,7 +176,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
|
|
compressed_size -= cur_size;
|
|
compressed_size -= cur_size;
|
|
}
|
|
}
|
|
btrfs_set_file_extent_compression(leaf, ei,
|
|
btrfs_set_file_extent_compression(leaf, ei,
|
|
- BTRFS_COMPRESS_ZLIB);
|
|
|
|
|
|
+ compress_type);
|
|
} else {
|
|
} else {
|
|
page = find_get_page(inode->i_mapping,
|
|
page = find_get_page(inode->i_mapping,
|
|
start >> PAGE_CACHE_SHIFT);
|
|
start >> PAGE_CACHE_SHIFT);
|
|
@@ -263,6 +263,7 @@ struct async_extent {
|
|
u64 compressed_size;
|
|
u64 compressed_size;
|
|
struct page **pages;
|
|
struct page **pages;
|
|
unsigned long nr_pages;
|
|
unsigned long nr_pages;
|
|
|
|
+ int compress_type;
|
|
struct list_head list;
|
|
struct list_head list;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -280,7 +281,8 @@ static noinline int add_async_extent(struct async_cow *cow,
|
|
u64 start, u64 ram_size,
|
|
u64 start, u64 ram_size,
|
|
u64 compressed_size,
|
|
u64 compressed_size,
|
|
struct page **pages,
|
|
struct page **pages,
|
|
- unsigned long nr_pages)
|
|
|
|
|
|
+ unsigned long nr_pages,
|
|
|
|
+ int compress_type)
|
|
{
|
|
{
|
|
struct async_extent *async_extent;
|
|
struct async_extent *async_extent;
|
|
|
|
|
|
@@ -290,6 +292,7 @@ static noinline int add_async_extent(struct async_cow *cow,
|
|
async_extent->compressed_size = compressed_size;
|
|
async_extent->compressed_size = compressed_size;
|
|
async_extent->pages = pages;
|
|
async_extent->pages = pages;
|
|
async_extent->nr_pages = nr_pages;
|
|
async_extent->nr_pages = nr_pages;
|
|
|
|
+ async_extent->compress_type = compress_type;
|
|
list_add_tail(&async_extent->list, &cow->extents);
|
|
list_add_tail(&async_extent->list, &cow->extents);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -332,6 +335,7 @@ static noinline int compress_file_range(struct inode *inode,
|
|
unsigned long max_uncompressed = 128 * 1024;
|
|
unsigned long max_uncompressed = 128 * 1024;
|
|
int i;
|
|
int i;
|
|
int will_compress;
|
|
int will_compress;
|
|
|
|
+ int compress_type = root->fs_info->compress_type;
|
|
|
|
|
|
actual_end = min_t(u64, isize, end + 1);
|
|
actual_end = min_t(u64, isize, end + 1);
|
|
again:
|
|
again:
|
|
@@ -381,12 +385,16 @@ again:
|
|
WARN_ON(pages);
|
|
WARN_ON(pages);
|
|
pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
|
|
pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
|
|
|
|
|
|
- ret = btrfs_zlib_compress_pages(inode->i_mapping, start,
|
|
|
|
- total_compressed, pages,
|
|
|
|
- nr_pages, &nr_pages_ret,
|
|
|
|
- &total_in,
|
|
|
|
- &total_compressed,
|
|
|
|
- max_compressed);
|
|
|
|
|
|
+ if (BTRFS_I(inode)->force_compress)
|
|
|
|
+ compress_type = BTRFS_I(inode)->force_compress;
|
|
|
|
+
|
|
|
|
+ ret = btrfs_compress_pages(compress_type,
|
|
|
|
+ inode->i_mapping, start,
|
|
|
|
+ total_compressed, pages,
|
|
|
|
+ nr_pages, &nr_pages_ret,
|
|
|
|
+ &total_in,
|
|
|
|
+ &total_compressed,
|
|
|
|
+ max_compressed);
|
|
|
|
|
|
if (!ret) {
|
|
if (!ret) {
|
|
unsigned long offset = total_compressed &
|
|
unsigned long offset = total_compressed &
|
|
@@ -493,7 +501,8 @@ again:
|
|
* and will submit them to the elevator.
|
|
* and will submit them to the elevator.
|
|
*/
|
|
*/
|
|
add_async_extent(async_cow, start, num_bytes,
|
|
add_async_extent(async_cow, start, num_bytes,
|
|
- total_compressed, pages, nr_pages_ret);
|
|
|
|
|
|
+ total_compressed, pages, nr_pages_ret,
|
|
|
|
+ compress_type);
|
|
|
|
|
|
if (start + num_bytes < end) {
|
|
if (start + num_bytes < end) {
|
|
start += num_bytes;
|
|
start += num_bytes;
|
|
@@ -515,7 +524,8 @@ cleanup_and_bail_uncompressed:
|
|
__set_page_dirty_nobuffers(locked_page);
|
|
__set_page_dirty_nobuffers(locked_page);
|
|
/* unlocked later on in the async handlers */
|
|
/* unlocked later on in the async handlers */
|
|
}
|
|
}
|
|
- add_async_extent(async_cow, start, end - start + 1, 0, NULL, 0);
|
|
|
|
|
|
+ add_async_extent(async_cow, start, end - start + 1,
|
|
|
|
+ 0, NULL, 0, BTRFS_COMPRESS_NONE);
|
|
*num_added += 1;
|
|
*num_added += 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -640,6 +650,7 @@ retry:
|
|
em->block_start = ins.objectid;
|
|
em->block_start = ins.objectid;
|
|
em->block_len = ins.offset;
|
|
em->block_len = ins.offset;
|
|
em->bdev = root->fs_info->fs_devices->latest_bdev;
|
|
em->bdev = root->fs_info->fs_devices->latest_bdev;
|
|
|
|
+ em->compress_type = async_extent->compress_type;
|
|
set_bit(EXTENT_FLAG_PINNED, &em->flags);
|
|
set_bit(EXTENT_FLAG_PINNED, &em->flags);
|
|
set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
|
set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
|
|
|
|
|
@@ -656,11 +667,13 @@ retry:
|
|
async_extent->ram_size - 1, 0);
|
|
async_extent->ram_size - 1, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- ret = btrfs_add_ordered_extent(inode, async_extent->start,
|
|
|
|
- ins.objectid,
|
|
|
|
- async_extent->ram_size,
|
|
|
|
- ins.offset,
|
|
|
|
- BTRFS_ORDERED_COMPRESSED);
|
|
|
|
|
|
+ ret = btrfs_add_ordered_extent_compress(inode,
|
|
|
|
+ async_extent->start,
|
|
|
|
+ ins.objectid,
|
|
|
|
+ async_extent->ram_size,
|
|
|
|
+ ins.offset,
|
|
|
|
+ BTRFS_ORDERED_COMPRESSED,
|
|
|
|
+ async_extent->compress_type);
|
|
BUG_ON(ret);
|
|
BUG_ON(ret);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1670,7 +1683,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|
struct btrfs_ordered_extent *ordered_extent = NULL;
|
|
struct btrfs_ordered_extent *ordered_extent = NULL;
|
|
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
|
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
|
struct extent_state *cached_state = NULL;
|
|
struct extent_state *cached_state = NULL;
|
|
- int compressed = 0;
|
|
|
|
|
|
+ int compress_type = 0;
|
|
int ret;
|
|
int ret;
|
|
bool nolock = false;
|
|
bool nolock = false;
|
|
|
|
|
|
@@ -1711,9 +1724,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|
trans->block_rsv = &root->fs_info->delalloc_block_rsv;
|
|
trans->block_rsv = &root->fs_info->delalloc_block_rsv;
|
|
|
|
|
|
if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags))
|
|
if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags))
|
|
- compressed = 1;
|
|
|
|
|
|
+ compress_type = ordered_extent->compress_type;
|
|
if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
|
|
if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
|
|
- BUG_ON(compressed);
|
|
|
|
|
|
+ BUG_ON(compress_type);
|
|
ret = btrfs_mark_extent_written(trans, inode,
|
|
ret = btrfs_mark_extent_written(trans, inode,
|
|
ordered_extent->file_offset,
|
|
ordered_extent->file_offset,
|
|
ordered_extent->file_offset +
|
|
ordered_extent->file_offset +
|
|
@@ -1727,7 +1740,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|
ordered_extent->disk_len,
|
|
ordered_extent->disk_len,
|
|
ordered_extent->len,
|
|
ordered_extent->len,
|
|
ordered_extent->len,
|
|
ordered_extent->len,
|
|
- compressed, 0, 0,
|
|
|
|
|
|
+ compress_type, 0, 0,
|
|
BTRFS_FILE_EXTENT_REG);
|
|
BTRFS_FILE_EXTENT_REG);
|
|
unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
|
|
unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
|
|
ordered_extent->file_offset,
|
|
ordered_extent->file_offset,
|
|
@@ -1829,6 +1842,8 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
|
|
if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
|
|
if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
|
|
logical = em->block_start;
|
|
logical = em->block_start;
|
|
failrec->bio_flags = EXTENT_BIO_COMPRESSED;
|
|
failrec->bio_flags = EXTENT_BIO_COMPRESSED;
|
|
|
|
+ extent_set_compress_type(&failrec->bio_flags,
|
|
|
|
+ em->compress_type);
|
|
}
|
|
}
|
|
failrec->logical = logical;
|
|
failrec->logical = logical;
|
|
free_extent_map(em);
|
|
free_extent_map(em);
|
|
@@ -4930,8 +4945,10 @@ static noinline int uncompress_inline(struct btrfs_path *path,
|
|
size_t max_size;
|
|
size_t max_size;
|
|
unsigned long inline_size;
|
|
unsigned long inline_size;
|
|
unsigned long ptr;
|
|
unsigned long ptr;
|
|
|
|
+ int compress_type;
|
|
|
|
|
|
WARN_ON(pg_offset != 0);
|
|
WARN_ON(pg_offset != 0);
|
|
|
|
+ compress_type = btrfs_file_extent_compression(leaf, item);
|
|
max_size = btrfs_file_extent_ram_bytes(leaf, item);
|
|
max_size = btrfs_file_extent_ram_bytes(leaf, item);
|
|
inline_size = btrfs_file_extent_inline_item_len(leaf,
|
|
inline_size = btrfs_file_extent_inline_item_len(leaf,
|
|
btrfs_item_nr(leaf, path->slots[0]));
|
|
btrfs_item_nr(leaf, path->slots[0]));
|
|
@@ -4941,8 +4958,8 @@ static noinline int uncompress_inline(struct btrfs_path *path,
|
|
read_extent_buffer(leaf, tmp, ptr, inline_size);
|
|
read_extent_buffer(leaf, tmp, ptr, inline_size);
|
|
|
|
|
|
max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size);
|
|
max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size);
|
|
- ret = btrfs_zlib_decompress(tmp, page, extent_offset,
|
|
|
|
- inline_size, max_size);
|
|
|
|
|
|
+ ret = btrfs_decompress(compress_type, tmp, page,
|
|
|
|
+ extent_offset, inline_size, max_size);
|
|
if (ret) {
|
|
if (ret) {
|
|
char *kaddr = kmap_atomic(page, KM_USER0);
|
|
char *kaddr = kmap_atomic(page, KM_USER0);
|
|
unsigned long copy_size = min_t(u64,
|
|
unsigned long copy_size = min_t(u64,
|
|
@@ -4984,7 +5001,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
|
|
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
|
|
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
|
|
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
|
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
|
struct btrfs_trans_handle *trans = NULL;
|
|
struct btrfs_trans_handle *trans = NULL;
|
|
- int compressed;
|
|
|
|
|
|
+ int compress_type;
|
|
|
|
|
|
again:
|
|
again:
|
|
read_lock(&em_tree->lock);
|
|
read_lock(&em_tree->lock);
|
|
@@ -5043,7 +5060,7 @@ again:
|
|
|
|
|
|
found_type = btrfs_file_extent_type(leaf, item);
|
|
found_type = btrfs_file_extent_type(leaf, item);
|
|
extent_start = found_key.offset;
|
|
extent_start = found_key.offset;
|
|
- compressed = btrfs_file_extent_compression(leaf, item);
|
|
|
|
|
|
+ compress_type = btrfs_file_extent_compression(leaf, item);
|
|
if (found_type == BTRFS_FILE_EXTENT_REG ||
|
|
if (found_type == BTRFS_FILE_EXTENT_REG ||
|
|
found_type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
found_type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
extent_end = extent_start +
|
|
extent_end = extent_start +
|
|
@@ -5089,8 +5106,9 @@ again:
|
|
em->block_start = EXTENT_MAP_HOLE;
|
|
em->block_start = EXTENT_MAP_HOLE;
|
|
goto insert;
|
|
goto insert;
|
|
}
|
|
}
|
|
- if (compressed) {
|
|
|
|
|
|
+ if (compress_type != BTRFS_COMPRESS_NONE) {
|
|
set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
|
set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
|
|
|
+ em->compress_type = compress_type;
|
|
em->block_start = bytenr;
|
|
em->block_start = bytenr;
|
|
em->block_len = btrfs_file_extent_disk_num_bytes(leaf,
|
|
em->block_len = btrfs_file_extent_disk_num_bytes(leaf,
|
|
item);
|
|
item);
|
|
@@ -5124,12 +5142,14 @@ again:
|
|
em->len = (copy_size + root->sectorsize - 1) &
|
|
em->len = (copy_size + root->sectorsize - 1) &
|
|
~((u64)root->sectorsize - 1);
|
|
~((u64)root->sectorsize - 1);
|
|
em->orig_start = EXTENT_MAP_INLINE;
|
|
em->orig_start = EXTENT_MAP_INLINE;
|
|
- if (compressed)
|
|
|
|
|
|
+ if (compress_type) {
|
|
set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
|
set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
|
|
|
|
+ em->compress_type = compress_type;
|
|
|
|
+ }
|
|
ptr = btrfs_file_extent_inline_start(item) + extent_offset;
|
|
ptr = btrfs_file_extent_inline_start(item) + extent_offset;
|
|
if (create == 0 && !PageUptodate(page)) {
|
|
if (create == 0 && !PageUptodate(page)) {
|
|
- if (btrfs_file_extent_compression(leaf, item) ==
|
|
|
|
- BTRFS_COMPRESS_ZLIB) {
|
|
|
|
|
|
+ if (btrfs_file_extent_compression(leaf, item) !=
|
|
|
|
+ BTRFS_COMPRESS_NONE) {
|
|
ret = uncompress_inline(path, inode, page,
|
|
ret = uncompress_inline(path, inode, page,
|
|
pg_offset,
|
|
pg_offset,
|
|
extent_offset, item);
|
|
extent_offset, item);
|
|
@@ -6479,7 +6499,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
|
|
ei->ordered_data_close = 0;
|
|
ei->ordered_data_close = 0;
|
|
ei->orphan_meta_reserved = 0;
|
|
ei->orphan_meta_reserved = 0;
|
|
ei->dummy_inode = 0;
|
|
ei->dummy_inode = 0;
|
|
- ei->force_compress = 0;
|
|
|
|
|
|
+ ei->force_compress = BTRFS_COMPRESS_NONE;
|
|
|
|
|
|
inode = &ei->vfs_inode;
|
|
inode = &ei->vfs_inode;
|
|
extent_map_tree_init(&ei->extent_tree, GFP_NOFS);
|
|
extent_map_tree_init(&ei->extent_tree, GFP_NOFS);
|