@@ -296,21 +296,32 @@ static int attempt_compress(struct bch_fs *c,
296296 void * workspace ,
297297 void * dst , size_t dst_len ,
298298 void * src , size_t src_len ,
299- enum bch_compression_type compression_type )
299+ struct bch_compression_opt compression )
300300{
301- switch (compression_type ) {
302- case BCH_COMPRESSION_TYPE_lz4 : {
303- int len = src_len ;
304- int ret = LZ4_compress_destSize (
305- src , dst ,
306- & len , dst_len ,
307- workspace );
308-
309- if (len < src_len )
310- return - len ;
301+ enum bch_compression_type compression_type =
302+ __bch2_compression_opt_to_type [compression .type ];
311303
312- return ret ;
313- }
304+ switch (compression_type ) {
305+ case BCH_COMPRESSION_TYPE_lz4 :
306+ if (compression .level < LZ4HC_MIN_CLEVEL ) {
307+ int len = src_len ;
308+ int ret = LZ4_compress_destSize (
309+ src , dst ,
310+ & len , dst_len ,
311+ workspace );
312+ if (len < src_len )
313+ return - len ;
314+
315+ return ret ;
316+ } else {
317+ int ret = LZ4_compress_HC (
318+ src , dst ,
319+ src_len , dst_len ,
320+ compression .level ,
321+ workspace );
322+
323+ return ret ?: -1 ;
324+ }
314325 case BCH_COMPRESSION_TYPE_gzip : {
315326 z_stream strm = {
316327 .next_in = src ,
@@ -320,7 +331,11 @@ static int attempt_compress(struct bch_fs *c,
320331 };
321332
322333 zlib_set_workspace (& strm , workspace );
323- zlib_deflateInit2 (& strm , Z_DEFAULT_COMPRESSION ,
334+ zlib_deflateInit2 (& strm ,
335+ compression .level
336+ ? clamp_t (unsigned , compression .level ,
337+ Z_BEST_SPEED , Z_BEST_COMPRESSION )
338+ : Z_DEFAULT_COMPRESSION ,
324339 Z_DEFLATED , - MAX_WBITS , DEF_MEM_LEVEL ,
325340 Z_DEFAULT_STRATEGY );
326341
@@ -333,8 +348,14 @@ static int attempt_compress(struct bch_fs *c,
333348 return strm .total_out ;
334349 }
335350 case BCH_COMPRESSION_TYPE_zstd : {
351+ /*
352+ * rescale:
353+ * zstd max compression level is 22, our max level is 15
354+ */
355+ unsigned level = min ((compression .level * 3 ) / 2 , zstd_max_clevel ());
356+ ZSTD_parameters params = zstd_get_params (level , c -> opts .encoded_extent_max );
336357 ZSTD_CCtx * ctx = zstd_init_cctx (workspace ,
337- zstd_cctx_workspace_bound (& c -> zstd_params .cParams ));
358+ zstd_cctx_workspace_bound (& params .cParams ));
338359
339360 /*
340361 * ZSTD requires that when we decompress we pass in the exact
@@ -365,10 +386,12 @@ static int attempt_compress(struct bch_fs *c,
365386static unsigned __bio_compress (struct bch_fs * c ,
366387 struct bio * dst , size_t * dst_len ,
367388 struct bio * src , size_t * src_len ,
368- enum bch_compression_type compression_type )
389+ struct bch_compression_opt compression )
369390{
370391 struct bbuf src_data = { NULL }, dst_data = { NULL };
371392 void * workspace ;
393+ enum bch_compression_type compression_type =
394+ __bch2_compression_opt_to_type [compression .type ];
372395 unsigned pad ;
373396 int ret = 0 ;
374397
@@ -400,7 +423,7 @@ static unsigned __bio_compress(struct bch_fs *c,
400423 ret = attempt_compress (c , workspace ,
401424 dst_data .b , * dst_len ,
402425 src_data .b , * src_len ,
403- compression_type );
426+ compression );
404427 if (ret > 0 ) {
405428 * dst_len = ret ;
406429 ret = 0 ;
@@ -447,34 +470,34 @@ static unsigned __bio_compress(struct bch_fs *c,
447470 BUG_ON (!* src_len || * src_len > src -> bi_iter .bi_size );
448471 BUG_ON (* dst_len & (block_bytes (c ) - 1 ));
449472 BUG_ON (* src_len & (block_bytes (c ) - 1 ));
473+ ret = compression_type ;
450474out :
451475 bio_unmap_or_unbounce (c , src_data );
452476 bio_unmap_or_unbounce (c , dst_data );
453- return compression_type ;
477+ return ret ;
454478err :
455- compression_type = BCH_COMPRESSION_TYPE_incompressible ;
479+ ret = BCH_COMPRESSION_TYPE_incompressible ;
456480 goto out ;
457481}
458482
459483unsigned bch2_bio_compress (struct bch_fs * c ,
460484 struct bio * dst , size_t * dst_len ,
461485 struct bio * src , size_t * src_len ,
462- unsigned compression_type )
486+ unsigned compression_opt )
463487{
464488 unsigned orig_dst = dst -> bi_iter .bi_size ;
465489 unsigned orig_src = src -> bi_iter .bi_size ;
490+ unsigned compression_type ;
466491
467492 /* Don't consume more than BCH_ENCODED_EXTENT_MAX from @src: */
468493 src -> bi_iter .bi_size = min_t (unsigned , src -> bi_iter .bi_size ,
469494 c -> opts .encoded_extent_max );
470495 /* Don't generate a bigger output than input: */
471496 dst -> bi_iter .bi_size = min (dst -> bi_iter .bi_size , src -> bi_iter .bi_size );
472497
473- if (compression_type == BCH_COMPRESSION_TYPE_lz4_old )
474- compression_type = BCH_COMPRESSION_TYPE_lz4 ;
475-
476498 compression_type =
477- __bio_compress (c , dst , dst_len , src , src_len , compression_type );
499+ __bio_compress (c , dst , dst_len , src , src_len ,
500+ bch2_compression_decode (compression_opt ));
478501
479502 dst -> bi_iter .bi_size = orig_dst ;
480503 src -> bi_iter .bi_size = orig_src ;
@@ -521,8 +544,10 @@ static int __bch2_check_set_has_compressed_data(struct bch_fs *c, u64 f)
521544}
522545
523546int bch2_check_set_has_compressed_data (struct bch_fs * c ,
524- unsigned compression_type )
547+ unsigned compression_opt )
525548{
549+ unsigned compression_type = bch2_compression_decode (compression_opt ).type ;
550+
526551 BUG_ON (compression_type >= ARRAY_SIZE (bch2_compression_opt_to_feature ));
527552
528553 return compression_type
@@ -546,14 +571,16 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
546571{
547572 size_t decompress_workspace_size = 0 ;
548573 bool decompress_workspace_needed ;
549- ZSTD_parameters params = zstd_get_params (0 , c -> opts .encoded_extent_max );
574+ ZSTD_parameters params = zstd_get_params (zstd_max_clevel (),
575+ c -> opts .encoded_extent_max );
550576 struct {
551- unsigned feature ;
552- unsigned type ;
553- size_t compress_workspace ;
554- size_t decompress_workspace ;
577+ unsigned feature ;
578+ enum bch_compression_type type ;
579+ size_t compress_workspace ;
580+ size_t decompress_workspace ;
555581 } compression_types [] = {
556- { BCH_FEATURE_lz4 , BCH_COMPRESSION_TYPE_lz4 , LZ4_MEM_COMPRESS , 0 },
582+ { BCH_FEATURE_lz4 , BCH_COMPRESSION_TYPE_lz4 ,
583+ max_t (size_t , LZ4_MEM_COMPRESS , LZ4HC_MEM_COMPRESS ) },
557584 { BCH_FEATURE_gzip , BCH_COMPRESSION_TYPE_gzip ,
558585 zlib_deflate_workspacesize (MAX_WBITS , DEF_MEM_LEVEL ),
559586 zlib_inflate_workspacesize (), },
@@ -612,16 +639,74 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
612639 return 0 ;
613640}
614641
642+ static u64 compression_opt_to_feature (unsigned v )
643+ {
644+ unsigned type = bch2_compression_decode (v ).type ;
645+ return 1ULL << bch2_compression_opt_to_feature [type ];
646+ }
647+
615648int bch2_fs_compress_init (struct bch_fs * c )
616649{
617650 u64 f = c -> sb .features ;
618651
619- if (c -> opts .compression )
620- f |= 1ULL << bch2_compression_opt_to_feature [c -> opts .compression ];
621-
622- if (c -> opts .background_compression )
623- f |= 1ULL << bch2_compression_opt_to_feature [c -> opts .background_compression ];
652+ f |= compression_opt_to_feature (c -> opts .compression );
653+ f |= compression_opt_to_feature (c -> opts .background_compression );
624654
625655 return __bch2_fs_compress_init (c , f );
656+ }
657+
658+ int bch2_opt_compression_parse (struct bch_fs * c , const char * _val , u64 * res ,
659+ struct printbuf * err )
660+ {
661+ char * val = kstrdup (_val , GFP_KERNEL );
662+ char * p = val , * type_str , * level_str ;
663+ struct bch_compression_opt opt = { 0 };
664+ int ret ;
665+
666+ if (!val )
667+ return - ENOMEM ;
668+
669+ type_str = strsep (& p , ":" );
670+ level_str = p ;
671+
672+ ret = match_string (bch2_compression_opts , -1 , type_str );
673+ if (ret < 0 && err )
674+ prt_str (err , "invalid compression type" );
675+ if (ret < 0 )
676+ goto err ;
677+
678+ opt .type = ret ;
679+
680+ if (level_str ) {
681+ unsigned level ;
682+
683+ ret = kstrtouint (level_str , 10 , & level );
684+ if (!ret && !opt .type && level )
685+ ret = - EINVAL ;
686+ if (!ret && level > 15 )
687+ ret = - EINVAL ;
688+ if (ret < 0 && err )
689+ prt_str (err , "invalid compression level" );
690+ if (ret < 0 )
691+ goto err ;
692+
693+ opt .level = level ;
694+ }
695+
696+ * res = bch2_compression_encode (opt );
697+ err :
698+ kfree (val );
699+ return ret ;
700+ }
701+
702+ void bch2_opt_compression_to_text (struct printbuf * out ,
703+ struct bch_fs * c ,
704+ struct bch_sb * sb ,
705+ u64 v )
706+ {
707+ struct bch_compression_opt opt = bch2_compression_decode (v );
626708
709+ prt_str (out , bch2_compression_opts [opt .type ]);
710+ if (opt .level )
711+ prt_printf (out , ":%u" , opt .level );
627712}
0 commit comments