aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c9ce0b002008..34222bbe4b48 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -19,6 +19,7 @@
19#include <linux/crc32c.h> 19#include <linux/crc32c.h>
20#include <linux/sched/mm.h> 20#include <linux/sched/mm.h>
21#include <asm/unaligned.h> 21#include <asm/unaligned.h>
22#include <crypto/hash.h>
22#include "ctree.h" 23#include "ctree.h"
23#include "disk-io.h" 24#include "disk-io.h"
24#include "transaction.h" 25#include "transaction.h"
@@ -2256,6 +2257,29 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
2256 return 0; 2257 return 0;
2257} 2258}
2258 2259
2260static 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
2278static void btrfs_free_csum_hash(struct btrfs_fs_info *fs_info)
2279{
2280 crypto_free_shash(fs_info->csum_shash);
2281}
2282
2259static int btrfs_replay_log(struct btrfs_fs_info *fs_info, 2283static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
2260 struct btrfs_fs_devices *fs_devices) 2284 struct btrfs_fs_devices *fs_devices)
2261{ 2285{
@@ -2820,6 +2844,12 @@ int open_ctree(struct super_block *sb,
2820 goto fail_alloc; 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 * We want to check superblock checksum, the type is stored inside. 2854 * We want to check superblock checksum, the type is stored inside.
2825 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k). 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 btrfs_err(fs_info, "superblock checksum mismatch"); 2858 btrfs_err(fs_info, "superblock checksum mismatch");
2829 err = -EINVAL; 2859 err = -EINVAL;
2830 brelse(bh); 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 if (ret) { 2895 if (ret) {
2866 btrfs_err(fs_info, "superblock contains fatal errors"); 2896 btrfs_err(fs_info, "superblock contains fatal errors");
2867 err = -EINVAL; 2897 err = -EINVAL;
2868 goto fail_alloc; 2898 goto fail_csum;
2869 } 2899 }
2870 2900
2871 if (!btrfs_super_root(disk_super)) 2901 if (!btrfs_super_root(disk_super))
2872 goto fail_alloc; 2902 goto fail_csum;
2873 2903
2874 /* check FS state, whether FS is broken. */ 2904 /* check FS state, whether FS is broken. */
2875 if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR) 2905 if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR)
@@ -2891,7 +2921,7 @@ int open_ctree(struct super_block *sb,
2891 ret = btrfs_parse_options(fs_info, options, sb->s_flags); 2921 ret = btrfs_parse_options(fs_info, options, sb->s_flags);
2892 if (ret) { 2922 if (ret) {
2893 err = ret; 2923 err = ret;
2894 goto fail_alloc; 2924 goto fail_csum;
2895 } 2925 }
2896 2926
2897 features = btrfs_super_incompat_flags(disk_super) & 2927 features = btrfs_super_incompat_flags(disk_super) &
@@ -2901,7 +2931,7 @@ int open_ctree(struct super_block *sb,
2901 "cannot mount because of unsupported optional features (%llx)", 2931 "cannot mount because of unsupported optional features (%llx)",
2902 features); 2932 features);
2903 err = -EINVAL; 2933 err = -EINVAL;
2904 goto fail_alloc; 2934 goto fail_csum;
2905 } 2935 }
2906 2936
2907 features = btrfs_super_incompat_flags(disk_super); 2937 features = btrfs_super_incompat_flags(disk_super);
@@ -2945,7 +2975,7 @@ int open_ctree(struct super_block *sb,
2945 btrfs_err(fs_info, 2975 btrfs_err(fs_info,
2946"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups", 2976"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
2947 nodesize, sectorsize); 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 "cannot mount read-write because of unsupported optional features (%llx)", 2991 "cannot mount read-write because of unsupported optional features (%llx)",
2962 features); 2992 features);
2963 err = -EINVAL; 2993 err = -EINVAL;
2964 goto fail_alloc; 2994 goto fail_csum;
2965 } 2995 }
2966 2996
2967 ret = btrfs_init_workqueues(fs_info, fs_devices); 2997 ret = btrfs_init_workqueues(fs_info, fs_devices);
@@ -3339,6 +3369,8 @@ fail_tree_roots:
3339fail_sb_buffer: 3369fail_sb_buffer:
3340 btrfs_stop_all_workers(fs_info); 3370 btrfs_stop_all_workers(fs_info);
3341 btrfs_free_block_groups(fs_info); 3371 btrfs_free_block_groups(fs_info);
3372fail_csum:
3373 btrfs_free_csum_hash(fs_info);
3342fail_alloc: 3374fail_alloc:
3343fail_iput: 3375fail_iput:
3344 btrfs_mapping_tree_free(&fs_info->mapping_tree); 3376 btrfs_mapping_tree_free(&fs_info->mapping_tree);