Commit 4bcbb332 authored by Shilong Wang's avatar Shilong Wang Committed by Chris Mason

Btrfs: fix incorrect compression ratio detection

Steps to reproduce:
 # mkfs.btrfs -f /dev/sdb
 # mount -t btrfs /dev/sdb /mnt -o compress=lzo
 # dd if=/dev/zero of=/mnt/data bs=$((33*4096)) count=1

after previous steps, inode will be detected as bad compression ratio,
and NOCOMPRESS flag will be set for that inode.

Reason is that compress have a max limit pages every time(128K), if a
132k write in, it will be splitted into two write(128k+4k), this bug
is a leftover for commit 68bb462d(Btrfs: don't compress for a small write)

Fix this problem by checking every time before compression, if it is a
small write(<=blocksize), we bail out and fall into nocompression directly.
Signed-off-by: default avatarWang Shilong <wangshilong1991@gmail.com>
Reviewed-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 7bdcefc1
...@@ -411,14 +411,6 @@ static noinline int compress_file_range(struct inode *inode, ...@@ -411,14 +411,6 @@ static noinline int compress_file_range(struct inode *inode,
(start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
btrfs_add_inode_defrag(NULL, inode); btrfs_add_inode_defrag(NULL, inode);
/*
* skip compression for a small file range(<=blocksize) that
* isn't an inline extent, since it dosen't save disk space at all.
*/
if ((end - start + 1) <= blocksize &&
(start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
goto cleanup_and_bail_uncompressed;
actual_end = min_t(u64, isize, end + 1); actual_end = min_t(u64, isize, end + 1);
again: again:
will_compress = 0; will_compress = 0;
...@@ -440,6 +432,14 @@ static noinline int compress_file_range(struct inode *inode, ...@@ -440,6 +432,14 @@ static noinline int compress_file_range(struct inode *inode,
total_compressed = actual_end - start; total_compressed = actual_end - start;
/*
* skip compression for a small file range(<=blocksize) that
* isn't an inline extent, since it dosen't save disk space at all.
*/
if (total_compressed <= blocksize &&
(start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
goto cleanup_and_bail_uncompressed;
/* we want to make sure that amount of ram required to uncompress /* we want to make sure that amount of ram required to uncompress
* an extent is reasonable, so we limit the total size in ram * an extent is reasonable, so we limit the total size in ram
* of a compressed extent to 128k. This is a crucial number * of a compressed extent to 128k. This is a crucial number
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment