diff mbox series

[5/5] btrfs: Compresses files using a combination of compression type and compression level.

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

Commit Message

Li Zhang Jan. 16, 2022, 8:51 a.m. UTC
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(-)

Comments

Li Zhang Jan. 20, 2022, 3:38 a.m. UTC | #1
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 mbox series

Patch

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;