@@ -296,21 +296,32 @@ static int attempt_compress(struct bch_fs *c,
296
296
void * workspace ,
297
297
void * dst , size_t dst_len ,
298
298
void * src , size_t src_len ,
299
- enum bch_compression_type compression_type )
299
+ struct bch_compression_opt compression )
300
300
{
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 ];
311
303
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
+ }
314
325
case BCH_COMPRESSION_TYPE_gzip : {
315
326
z_stream strm = {
316
327
.next_in = src ,
@@ -320,7 +331,11 @@ static int attempt_compress(struct bch_fs *c,
320
331
};
321
332
322
333
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 ,
324
339
Z_DEFLATED , - MAX_WBITS , DEF_MEM_LEVEL ,
325
340
Z_DEFAULT_STRATEGY );
326
341
@@ -333,8 +348,14 @@ static int attempt_compress(struct bch_fs *c,
333
348
return strm .total_out ;
334
349
}
335
350
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 );
336
357
ZSTD_CCtx * ctx = zstd_init_cctx (workspace ,
337
- zstd_cctx_workspace_bound (& c -> zstd_params .cParams ));
358
+ zstd_cctx_workspace_bound (& params .cParams ));
338
359
339
360
/*
340
361
* ZSTD requires that when we decompress we pass in the exact
@@ -365,10 +386,12 @@ static int attempt_compress(struct bch_fs *c,
365
386
static unsigned __bio_compress (struct bch_fs * c ,
366
387
struct bio * dst , size_t * dst_len ,
367
388
struct bio * src , size_t * src_len ,
368
- enum bch_compression_type compression_type )
389
+ struct bch_compression_opt compression )
369
390
{
370
391
struct bbuf src_data = { NULL }, dst_data = { NULL };
371
392
void * workspace ;
393
+ enum bch_compression_type compression_type =
394
+ __bch2_compression_opt_to_type [compression .type ];
372
395
unsigned pad ;
373
396
int ret = 0 ;
374
397
@@ -400,7 +423,7 @@ static unsigned __bio_compress(struct bch_fs *c,
400
423
ret = attempt_compress (c , workspace ,
401
424
dst_data .b , * dst_len ,
402
425
src_data .b , * src_len ,
403
- compression_type );
426
+ compression );
404
427
if (ret > 0 ) {
405
428
* dst_len = ret ;
406
429
ret = 0 ;
@@ -447,34 +470,34 @@ static unsigned __bio_compress(struct bch_fs *c,
447
470
BUG_ON (!* src_len || * src_len > src -> bi_iter .bi_size );
448
471
BUG_ON (* dst_len & (block_bytes (c ) - 1 ));
449
472
BUG_ON (* src_len & (block_bytes (c ) - 1 ));
473
+ ret = compression_type ;
450
474
out :
451
475
bio_unmap_or_unbounce (c , src_data );
452
476
bio_unmap_or_unbounce (c , dst_data );
453
- return compression_type ;
477
+ return ret ;
454
478
err :
455
- compression_type = BCH_COMPRESSION_TYPE_incompressible ;
479
+ ret = BCH_COMPRESSION_TYPE_incompressible ;
456
480
goto out ;
457
481
}
458
482
459
483
unsigned bch2_bio_compress (struct bch_fs * c ,
460
484
struct bio * dst , size_t * dst_len ,
461
485
struct bio * src , size_t * src_len ,
462
- unsigned compression_type )
486
+ unsigned compression_opt )
463
487
{
464
488
unsigned orig_dst = dst -> bi_iter .bi_size ;
465
489
unsigned orig_src = src -> bi_iter .bi_size ;
490
+ unsigned compression_type ;
466
491
467
492
/* Don't consume more than BCH_ENCODED_EXTENT_MAX from @src: */
468
493
src -> bi_iter .bi_size = min_t (unsigned , src -> bi_iter .bi_size ,
469
494
c -> opts .encoded_extent_max );
470
495
/* Don't generate a bigger output than input: */
471
496
dst -> bi_iter .bi_size = min (dst -> bi_iter .bi_size , src -> bi_iter .bi_size );
472
497
473
- if (compression_type == BCH_COMPRESSION_TYPE_lz4_old )
474
- compression_type = BCH_COMPRESSION_TYPE_lz4 ;
475
-
476
498
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 ));
478
501
479
502
dst -> bi_iter .bi_size = orig_dst ;
480
503
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)
521
544
}
522
545
523
546
int bch2_check_set_has_compressed_data (struct bch_fs * c ,
524
- unsigned compression_type )
547
+ unsigned compression_opt )
525
548
{
549
+ unsigned compression_type = bch2_compression_decode (compression_opt ).type ;
550
+
526
551
BUG_ON (compression_type >= ARRAY_SIZE (bch2_compression_opt_to_feature ));
527
552
528
553
return compression_type
@@ -546,14 +571,16 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
546
571
{
547
572
size_t decompress_workspace_size = 0 ;
548
573
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 );
550
576
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 ;
555
581
} 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 ) },
557
584
{ BCH_FEATURE_gzip , BCH_COMPRESSION_TYPE_gzip ,
558
585
zlib_deflate_workspacesize (MAX_WBITS , DEF_MEM_LEVEL ),
559
586
zlib_inflate_workspacesize (), },
@@ -612,16 +639,74 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
612
639
return 0 ;
613
640
}
614
641
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
+
615
648
int bch2_fs_compress_init (struct bch_fs * c )
616
649
{
617
650
u64 f = c -> sb .features ;
618
651
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 );
624
654
625
655
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 );
626
708
709
+ prt_str (out , bch2_compression_opts [opt .type ]);
710
+ if (opt .level )
711
+ prt_printf (out , ":%u" , opt .level );
627
712
}
0 commit comments