19
19
#include <linux/crc32c.h>
20
20
#include <linux/sched/mm.h>
21
21
#include <asm/unaligned.h>
22
+ #include <crypto/hash.h>
22
23
#include "ctree.h"
23
24
#include "disk-io.h"
24
25
#include "transaction.h"
@@ -2256,6 +2257,29 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
2256
2257
return 0 ;
2257
2258
}
2258
2259
2260
+ static int btrfs_init_csum_hash (struct btrfs_fs_info * fs_info , u16 csum_type )
2261
+ {
2262
+ struct crypto_shash * csum_shash ;
2263
+ const char * csum_name = btrfs_super_csum_name (csum_type );
2264
+
2265
+ csum_shash = crypto_alloc_shash (csum_name , 0 , 0 );
2266
+
2267
+ if (IS_ERR (csum_shash )) {
2268
+ btrfs_err (fs_info , "error allocating %s hash for checksum" ,
2269
+ csum_name );
2270
+ return PTR_ERR (csum_shash );
2271
+ }
2272
+
2273
+ fs_info -> csum_shash = csum_shash ;
2274
+
2275
+ return 0 ;
2276
+ }
2277
+
2278
+ static void btrfs_free_csum_hash (struct btrfs_fs_info * fs_info )
2279
+ {
2280
+ crypto_free_shash (fs_info -> csum_shash );
2281
+ }
2282
+
2259
2283
static int btrfs_replay_log (struct btrfs_fs_info * fs_info ,
2260
2284
struct btrfs_fs_devices * fs_devices )
2261
2285
{
@@ -2820,6 +2844,12 @@ int open_ctree(struct super_block *sb,
2820
2844
goto fail_alloc ;
2821
2845
}
2822
2846
2847
+ ret = btrfs_init_csum_hash (fs_info , csum_type );
2848
+ if (ret ) {
2849
+ err = ret ;
2850
+ goto fail_alloc ;
2851
+ }
2852
+
2823
2853
/*
2824
2854
* We want to check superblock checksum, the type is stored inside.
2825
2855
* Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
@@ -2828,7 +2858,7 @@ int open_ctree(struct super_block *sb,
2828
2858
btrfs_err (fs_info , "superblock checksum mismatch" );
2829
2859
err = - EINVAL ;
2830
2860
brelse (bh );
2831
- goto fail_alloc ;
2861
+ goto fail_csum ;
2832
2862
}
2833
2863
2834
2864
/*
@@ -2865,11 +2895,11 @@ int open_ctree(struct super_block *sb,
2865
2895
if (ret ) {
2866
2896
btrfs_err (fs_info , "superblock contains fatal errors" );
2867
2897
err = - EINVAL ;
2868
- goto fail_alloc ;
2898
+ goto fail_csum ;
2869
2899
}
2870
2900
2871
2901
if (!btrfs_super_root (disk_super ))
2872
- goto fail_alloc ;
2902
+ goto fail_csum ;
2873
2903
2874
2904
/* check FS state, whether FS is broken. */
2875
2905
if (btrfs_super_flags (disk_super ) & BTRFS_SUPER_FLAG_ERROR )
@@ -2891,7 +2921,7 @@ int open_ctree(struct super_block *sb,
2891
2921
ret = btrfs_parse_options (fs_info , options , sb -> s_flags );
2892
2922
if (ret ) {
2893
2923
err = ret ;
2894
- goto fail_alloc ;
2924
+ goto fail_csum ;
2895
2925
}
2896
2926
2897
2927
features = btrfs_super_incompat_flags (disk_super ) &
@@ -2901,7 +2931,7 @@ int open_ctree(struct super_block *sb,
2901
2931
"cannot mount because of unsupported optional features (%llx)" ,
2902
2932
features );
2903
2933
err = - EINVAL ;
2904
- goto fail_alloc ;
2934
+ goto fail_csum ;
2905
2935
}
2906
2936
2907
2937
features = btrfs_super_incompat_flags (disk_super );
@@ -2945,7 +2975,7 @@ int open_ctree(struct super_block *sb,
2945
2975
btrfs_err (fs_info ,
2946
2976
"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups" ,
2947
2977
nodesize , sectorsize );
2948
- goto fail_alloc ;
2978
+ goto fail_csum ;
2949
2979
}
2950
2980
2951
2981
/*
@@ -2961,7 +2991,7 @@ int open_ctree(struct super_block *sb,
2961
2991
"cannot mount read-write because of unsupported optional features (%llx)" ,
2962
2992
features );
2963
2993
err = - EINVAL ;
2964
- goto fail_alloc ;
2994
+ goto fail_csum ;
2965
2995
}
2966
2996
2967
2997
ret = btrfs_init_workqueues (fs_info , fs_devices );
@@ -3339,6 +3369,8 @@ int open_ctree(struct super_block *sb,
3339
3369
fail_sb_buffer :
3340
3370
btrfs_stop_all_workers (fs_info );
3341
3371
btrfs_free_block_groups (fs_info );
3372
+ fail_csum :
3373
+ btrfs_free_csum_hash (fs_info );
3342
3374
fail_alloc :
3343
3375
fail_iput :
3344
3376
btrfs_mapping_tree_free (& fs_info -> mapping_tree );
0 commit comments