Message ID | 1642323083-2088-1-git-send-email-zhanglikernel@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: Cleanup BTRFS_INODE_NOCOMPRESS usage and extend | expand |
Allow user set compression type and level by btrfs properties. Old behavior: # mount filesystem with compression level 3 $ sudo mount -o compress=zstd:3 /dev/loop1 /mnt/1 # set file would be compressed by zstd and level 11 $ btrfs property set /mnt/1/1 compression zstd:11 # compress would compressed by zstd and level 3(still use filesystem compression level) $ cat ~/202109091507_210601004_A_PE150_COVID19_iGeneTech_0909_i_D8_F_L01_R1.fq > /mnt/1/1 New behavior: # mount filesystem with compression level 3 $ sudo mount -o compress=zstd:3 /dev/loop1 /mnt/1 # set file would be compressed by zstd and level 11 $ btrfs property set /mnt/1/1 compression zstd:11 # compress would compressed by zstd and level 11 $ cat ~/202109091507_210601004_A_PE150_COVID19_iGeneTech_0909_i_D8_F_L01_R1.fq > /mnt/1/1 Here is my test method after patch adding: First I test all compression types and compression levels, I write the file to the btrfs system (print the compression type and level with btrfs_info to make sure both values are valid), then use diff <btrfs_file> <original file>, it tells me both file is the same. Also, I compress the file with the btrfs filesystem version before adding the patch, and then read it through the patched version, the file can be read without errors and data corruption. Li Zhang <zhanglikernel@gmail.com> 于2022年1月16日周日 16:51写道: > > 1. If the file is being defragmented, combine defrag_compress > and fs_info compression_level (defrag_compress will be > extended in the future). > > 2. Extract the compression type btrfs_inode using and write to extent, > because decompression does not need to know the compression level. > > Signed-off-by: Li Zhang <zhanglikernel@gmail.com> > --- > fs/btrfs/inode.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index 3fe485b..fb44899 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -602,7 +602,8 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) > unsigned long total_in = 0; > int i; > int will_compress; > - int compress_type = fs_info->compress_type; > + int compress_type = btrfs_compress_combine_type_level( > + fs_info->compress_type, fs_info -> compress_level); > int compressed_extents = 0; > int redirty = 0; > > @@ -683,7 +684,8 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) > } > > if (BTRFS_I(inode)->defrag_compress) > - compress_type = BTRFS_I(inode)->defrag_compress; > + compress_type = btrfs_compress_combine_type_level( > + BTRFS_I(inode)->defrag_compress, fs_info->compress_level); > else if (BTRFS_I(inode)->prop_compress) > compress_type = BTRFS_I(inode)->prop_compress; > > @@ -706,7 +708,7 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) > > /* Compression level is applied here and only here */ > ret = btrfs_compress_pages( > - compress_type | (fs_info->compress_level << 4), > + compress_type, > inode->i_mapping, start, > pages, > &nr_pages, > @@ -743,7 +745,7 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) > /* try making a compressed inline extent */ > ret = cow_file_range_inline(BTRFS_I(inode), start, end, > total_compressed, > - compress_type, pages); > + btrfs_compress_type(compress_type), pages); > } > if (ret <= 0) { > unsigned long clear_flags = EXTENT_DELALLOC | > @@ -808,10 +810,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) > * The async work queues will take care of doing actual > * allocation on disk for these compressed pages, and > * will submit them to the elevator. > + * It only need to record compression type, because decompress don't need > + * to know compression level > */ > add_async_extent(async_chunk, start, total_in, > total_compressed, pages, nr_pages, > - compress_type); > + btrfs_compress_type(compress_type)); > > if (start + total_in < end) { > start += total_in; > -- > 1.8.3.1 >
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3fe485b..fb44899 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -602,7 +602,8 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) unsigned long total_in = 0; int i; int will_compress; - int compress_type = fs_info->compress_type; + int compress_type = btrfs_compress_combine_type_level( + fs_info->compress_type, fs_info -> compress_level); int compressed_extents = 0; int redirty = 0; @@ -683,7 +684,8 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) } if (BTRFS_I(inode)->defrag_compress) - compress_type = BTRFS_I(inode)->defrag_compress; + compress_type = btrfs_compress_combine_type_level( + BTRFS_I(inode)->defrag_compress, fs_info->compress_level); else if (BTRFS_I(inode)->prop_compress) compress_type = BTRFS_I(inode)->prop_compress; @@ -706,7 +708,7 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) /* Compression level is applied here and only here */ ret = btrfs_compress_pages( - compress_type | (fs_info->compress_level << 4), + compress_type, inode->i_mapping, start, pages, &nr_pages, @@ -743,7 +745,7 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) /* try making a compressed inline extent */ ret = cow_file_range_inline(BTRFS_I(inode), start, end, total_compressed, - compress_type, pages); + btrfs_compress_type(compress_type), pages); } if (ret <= 0) { unsigned long clear_flags = EXTENT_DELALLOC | @@ -808,10 +810,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) * The async work queues will take care of doing actual * allocation on disk for these compressed pages, and * will submit them to the elevator. + * It only need to record compression type, because decompress don't need + * to know compression level */ add_async_extent(async_chunk, start, total_in, total_compressed, pages, nr_pages, - compress_type); + btrfs_compress_type(compress_type)); if (start + total_in < end) { start += total_in;
1. If the file is being defragmented, combine defrag_compress and fs_info compression_level (defrag_compress will be extended in the future). 2. Extract the compression type btrfs_inode using and write to extent, because decompression does not need to know the compression level. Signed-off-by: Li Zhang <zhanglikernel@gmail.com> --- fs/btrfs/inode.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)