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.c166
1 files changed, 104 insertions, 62 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index deb74a8c191a..41a2bd2e0c56 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"
@@ -40,10 +41,6 @@
40#include "tree-checker.h" 41#include "tree-checker.h"
41#include "ref-verify.h" 42#include "ref-verify.h"
42 43
43#ifdef CONFIG_X86
44#include <asm/cpufeature.h>
45#endif
46
47#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN |\ 44#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN |\
48 BTRFS_HEADER_FLAG_RELOC |\ 45 BTRFS_HEADER_FLAG_RELOC |\
49 BTRFS_SUPER_FLAG_ERROR |\ 46 BTRFS_SUPER_FLAG_ERROR |\
@@ -249,16 +246,6 @@ out:
249 return em; 246 return em;
250} 247}
251 248
252u32 btrfs_csum_data(const char *data, u32 seed, size_t len)
253{
254 return crc32c(seed, data, len);
255}
256
257void btrfs_csum_final(u32 crc, u8 *result)
258{
259 put_unaligned_le32(~crc, result);
260}
261
262/* 249/*
263 * Compute the csum of a btree block and store the result to provided buffer. 250 * Compute the csum of a btree block and store the result to provided buffer.
264 * 251 *
@@ -266,6 +253,8 @@ void btrfs_csum_final(u32 crc, u8 *result)
266 */ 253 */
267static int csum_tree_block(struct extent_buffer *buf, u8 *result) 254static int csum_tree_block(struct extent_buffer *buf, u8 *result)
268{ 255{
256 struct btrfs_fs_info *fs_info = buf->fs_info;
257 SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
269 unsigned long len; 258 unsigned long len;
270 unsigned long cur_len; 259 unsigned long cur_len;
271 unsigned long offset = BTRFS_CSUM_SIZE; 260 unsigned long offset = BTRFS_CSUM_SIZE;
@@ -273,9 +262,12 @@ static int csum_tree_block(struct extent_buffer *buf, u8 *result)
273 unsigned long map_start; 262 unsigned long map_start;
274 unsigned long map_len; 263 unsigned long map_len;
275 int err; 264 int err;
276 u32 crc = ~(u32)0; 265
266 shash->tfm = fs_info->csum_shash;
267 crypto_shash_init(shash);
277 268
278 len = buf->len - offset; 269 len = buf->len - offset;
270
279 while (len > 0) { 271 while (len > 0) {
280 /* 272 /*
281 * Note: we don't need to check for the err == 1 case here, as 273 * Note: we don't need to check for the err == 1 case here, as
@@ -288,14 +280,13 @@ static int csum_tree_block(struct extent_buffer *buf, u8 *result)
288 if (WARN_ON(err)) 280 if (WARN_ON(err))
289 return err; 281 return err;
290 cur_len = min(len, map_len - (offset - map_start)); 282 cur_len = min(len, map_len - (offset - map_start));
291 crc = btrfs_csum_data(kaddr + offset - map_start, 283 crypto_shash_update(shash, kaddr + offset - map_start, cur_len);
292 crc, cur_len);
293 len -= cur_len; 284 len -= cur_len;
294 offset += cur_len; 285 offset += cur_len;
295 } 286 }
296 memset(result, 0, BTRFS_CSUM_SIZE); 287 memset(result, 0, BTRFS_CSUM_SIZE);
297 288
298 btrfs_csum_final(crc, result); 289 crypto_shash_final(shash, result);
299 290
300 return 0; 291 return 0;
301} 292}
@@ -356,6 +347,16 @@ out:
356 return ret; 347 return ret;
357} 348}
358 349
350static bool btrfs_supported_super_csum(u16 csum_type)
351{
352 switch (csum_type) {
353 case BTRFS_CSUM_TYPE_CRC32:
354 return true;
355 default:
356 return false;
357 }
358}
359
359/* 360/*
360 * Return 0 if the superblock checksum type matches the checksum value of that 361 * Return 0 if the superblock checksum type matches the checksum value of that
361 * algorithm. Pass the raw disk superblock data. 362 * algorithm. Pass the raw disk superblock data.
@@ -365,33 +366,25 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
365{ 366{
366 struct btrfs_super_block *disk_sb = 367 struct btrfs_super_block *disk_sb =
367 (struct btrfs_super_block *)raw_disk_sb; 368 (struct btrfs_super_block *)raw_disk_sb;
368 u16 csum_type = btrfs_super_csum_type(disk_sb); 369 char result[BTRFS_CSUM_SIZE];
369 int ret = 0; 370 SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
370 371
371 if (csum_type == BTRFS_CSUM_TYPE_CRC32) { 372 shash->tfm = fs_info->csum_shash;
372 u32 crc = ~(u32)0; 373 crypto_shash_init(shash);
373 char result[sizeof(crc)];
374 374
375 /* 375 /*
376 * The super_block structure does not span the whole 376 * The super_block structure does not span the whole
377 * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space 377 * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is
378 * is filled with zeros and is included in the checksum. 378 * filled with zeros and is included in the checksum.
379 */ 379 */
380 crc = btrfs_csum_data(raw_disk_sb + BTRFS_CSUM_SIZE, 380 crypto_shash_update(shash, raw_disk_sb + BTRFS_CSUM_SIZE,
381 crc, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); 381 BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
382 btrfs_csum_final(crc, result); 382 crypto_shash_final(shash, result);
383 383
384 if (memcmp(raw_disk_sb, result, sizeof(result))) 384 if (memcmp(disk_sb->csum, result, btrfs_super_csum_size(disk_sb)))
385 ret = 1; 385 return 1;
386 }
387 386
388 if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes)) { 387 return 0;
389 btrfs_err(fs_info, "unsupported checksum algorithm %u",
390 csum_type);
391 ret = 1;
392 }
393
394 return ret;
395} 388}
396 389
397int btrfs_verify_level_key(struct extent_buffer *eb, int level, 390int btrfs_verify_level_key(struct extent_buffer *eb, int level,
@@ -873,14 +866,13 @@ static blk_status_t btree_submit_bio_start(void *private_data, struct bio *bio,
873 return btree_csum_one_bio(bio); 866 return btree_csum_one_bio(bio);
874} 867}
875 868
876static int check_async_write(struct btrfs_inode *bi) 869static int check_async_write(struct btrfs_fs_info *fs_info,
870 struct btrfs_inode *bi)
877{ 871{
878 if (atomic_read(&bi->sync_writers)) 872 if (atomic_read(&bi->sync_writers))
879 return 0; 873 return 0;
880#ifdef CONFIG_X86 874 if (test_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags))
881 if (static_cpu_has(X86_FEATURE_XMM4_2))
882 return 0; 875 return 0;
883#endif
884 return 1; 876 return 1;
885} 877}
886 878
@@ -889,7 +881,7 @@ static blk_status_t btree_submit_bio_hook(struct inode *inode, struct bio *bio,
889 unsigned long bio_flags) 881 unsigned long bio_flags)
890{ 882{
891 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 883 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
892 int async = check_async_write(BTRFS_I(inode)); 884 int async = check_async_write(fs_info, BTRFS_I(inode));
893 blk_status_t ret; 885 blk_status_t ret;
894 886
895 if (bio_op(bio) != REQ_OP_WRITE) { 887 if (bio_op(bio) != REQ_OP_WRITE) {
@@ -2262,6 +2254,29 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
2262 return 0; 2254 return 0;
2263} 2255}
2264 2256
2257static int btrfs_init_csum_hash(struct btrfs_fs_info *fs_info, u16 csum_type)
2258{
2259 struct crypto_shash *csum_shash;
2260 const char *csum_name = btrfs_super_csum_name(csum_type);
2261
2262 csum_shash = crypto_alloc_shash(csum_name, 0, 0);
2263
2264 if (IS_ERR(csum_shash)) {
2265 btrfs_err(fs_info, "error allocating %s hash for checksum",
2266 csum_name);
2267 return PTR_ERR(csum_shash);
2268 }
2269
2270 fs_info->csum_shash = csum_shash;
2271
2272 return 0;
2273}
2274
2275static void btrfs_free_csum_hash(struct btrfs_fs_info *fs_info)
2276{
2277 crypto_free_shash(fs_info->csum_shash);
2278}
2279
2265static int btrfs_replay_log(struct btrfs_fs_info *fs_info, 2280static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
2266 struct btrfs_fs_devices *fs_devices) 2281 struct btrfs_fs_devices *fs_devices)
2267{ 2282{
@@ -2577,7 +2592,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
2577 ret = validate_super(fs_info, sb, -1); 2592 ret = validate_super(fs_info, sb, -1);
2578 if (ret < 0) 2593 if (ret < 0)
2579 goto out; 2594 goto out;
2580 if (btrfs_super_csum_type(sb) != BTRFS_CSUM_TYPE_CRC32) { 2595 if (!btrfs_supported_super_csum(btrfs_super_csum_type(sb))) {
2581 ret = -EUCLEAN; 2596 ret = -EUCLEAN;
2582 btrfs_err(fs_info, "invalid csum type, has %u want %u", 2597 btrfs_err(fs_info, "invalid csum type, has %u want %u",
2583 btrfs_super_csum_type(sb), BTRFS_CSUM_TYPE_CRC32); 2598 btrfs_super_csum_type(sb), BTRFS_CSUM_TYPE_CRC32);
@@ -2607,6 +2622,7 @@ int open_ctree(struct super_block *sb,
2607 u32 stripesize; 2622 u32 stripesize;
2608 u64 generation; 2623 u64 generation;
2609 u64 features; 2624 u64 features;
2625 u16 csum_type;
2610 struct btrfs_key location; 2626 struct btrfs_key location;
2611 struct buffer_head *bh; 2627 struct buffer_head *bh;
2612 struct btrfs_super_block *disk_super; 2628 struct btrfs_super_block *disk_super;
@@ -2689,7 +2705,7 @@ int open_ctree(struct super_block *sb,
2689 INIT_LIST_HEAD(&fs_info->space_info); 2705 INIT_LIST_HEAD(&fs_info->space_info);
2690 INIT_LIST_HEAD(&fs_info->tree_mod_seq_list); 2706 INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
2691 INIT_LIST_HEAD(&fs_info->unused_bgs); 2707 INIT_LIST_HEAD(&fs_info->unused_bgs);
2692 btrfs_mapping_init(&fs_info->mapping_tree); 2708 extent_map_tree_init(&fs_info->mapping_tree);
2693 btrfs_init_block_rsv(&fs_info->global_block_rsv, 2709 btrfs_init_block_rsv(&fs_info->global_block_rsv,
2694 BTRFS_BLOCK_RSV_GLOBAL); 2710 BTRFS_BLOCK_RSV_GLOBAL);
2695 btrfs_init_block_rsv(&fs_info->trans_block_rsv, BTRFS_BLOCK_RSV_TRANS); 2711 btrfs_init_block_rsv(&fs_info->trans_block_rsv, BTRFS_BLOCK_RSV_TRANS);
@@ -2793,6 +2809,8 @@ int open_ctree(struct super_block *sb,
2793 spin_lock_init(&fs_info->swapfile_pins_lock); 2809 spin_lock_init(&fs_info->swapfile_pins_lock);
2794 fs_info->swapfile_pins = RB_ROOT; 2810 fs_info->swapfile_pins = RB_ROOT;
2795 2811
2812 fs_info->send_in_progress = 0;
2813
2796 ret = btrfs_alloc_stripe_hash_table(fs_info); 2814 ret = btrfs_alloc_stripe_hash_table(fs_info);
2797 if (ret) { 2815 if (ret) {
2798 err = ret; 2816 err = ret;
@@ -2813,6 +2831,25 @@ int open_ctree(struct super_block *sb,
2813 } 2831 }
2814 2832
2815 /* 2833 /*
2834 * Verify the type first, if that or the the checksum value are
2835 * corrupted, we'll find out
2836 */
2837 csum_type = btrfs_super_csum_type((struct btrfs_super_block *)bh->b_data);
2838 if (!btrfs_supported_super_csum(csum_type)) {
2839 btrfs_err(fs_info, "unsupported checksum algorithm: %u",
2840 csum_type);
2841 err = -EINVAL;
2842 brelse(bh);
2843 goto fail_alloc;
2844 }
2845
2846 ret = btrfs_init_csum_hash(fs_info, csum_type);
2847 if (ret) {
2848 err = ret;
2849 goto fail_alloc;
2850 }
2851
2852 /*
2816 * We want to check superblock checksum, the type is stored inside. 2853 * We want to check superblock checksum, the type is stored inside.
2817 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k). 2854 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
2818 */ 2855 */
@@ -2820,7 +2857,7 @@ int open_ctree(struct super_block *sb,
2820 btrfs_err(fs_info, "superblock checksum mismatch"); 2857 btrfs_err(fs_info, "superblock checksum mismatch");
2821 err = -EINVAL; 2858 err = -EINVAL;
2822 brelse(bh); 2859 brelse(bh);
2823 goto fail_alloc; 2860 goto fail_csum;
2824 } 2861 }
2825 2862
2826 /* 2863 /*
@@ -2857,11 +2894,11 @@ int open_ctree(struct super_block *sb,
2857 if (ret) { 2894 if (ret) {
2858 btrfs_err(fs_info, "superblock contains fatal errors"); 2895 btrfs_err(fs_info, "superblock contains fatal errors");
2859 err = -EINVAL; 2896 err = -EINVAL;
2860 goto fail_alloc; 2897 goto fail_csum;
2861 } 2898 }
2862 2899
2863 if (!btrfs_super_root(disk_super)) 2900 if (!btrfs_super_root(disk_super))
2864 goto fail_alloc; 2901 goto fail_csum;
2865 2902
2866 /* check FS state, whether FS is broken. */ 2903 /* check FS state, whether FS is broken. */
2867 if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR) 2904 if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR)
@@ -2883,7 +2920,7 @@ int open_ctree(struct super_block *sb,
2883 ret = btrfs_parse_options(fs_info, options, sb->s_flags); 2920 ret = btrfs_parse_options(fs_info, options, sb->s_flags);
2884 if (ret) { 2921 if (ret) {
2885 err = ret; 2922 err = ret;
2886 goto fail_alloc; 2923 goto fail_csum;
2887 } 2924 }
2888 2925
2889 features = btrfs_super_incompat_flags(disk_super) & 2926 features = btrfs_super_incompat_flags(disk_super) &
@@ -2893,7 +2930,7 @@ int open_ctree(struct super_block *sb,
2893 "cannot mount because of unsupported optional features (%llx)", 2930 "cannot mount because of unsupported optional features (%llx)",
2894 features); 2931 features);
2895 err = -EINVAL; 2932 err = -EINVAL;
2896 goto fail_alloc; 2933 goto fail_csum;
2897 } 2934 }
2898 2935
2899 features = btrfs_super_incompat_flags(disk_super); 2936 features = btrfs_super_incompat_flags(disk_super);
@@ -2937,7 +2974,7 @@ int open_ctree(struct super_block *sb,
2937 btrfs_err(fs_info, 2974 btrfs_err(fs_info,
2938"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups", 2975"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
2939 nodesize, sectorsize); 2976 nodesize, sectorsize);
2940 goto fail_alloc; 2977 goto fail_csum;
2941 } 2978 }
2942 2979
2943 /* 2980 /*
@@ -2953,7 +2990,7 @@ int open_ctree(struct super_block *sb,
2953 "cannot mount read-write because of unsupported optional features (%llx)", 2990 "cannot mount read-write because of unsupported optional features (%llx)",
2954 features); 2991 features);
2955 err = -EINVAL; 2992 err = -EINVAL;
2956 goto fail_alloc; 2993 goto fail_csum;
2957 } 2994 }
2958 2995
2959 ret = btrfs_init_workqueues(fs_info, fs_devices); 2996 ret = btrfs_init_workqueues(fs_info, fs_devices);
@@ -3331,6 +3368,8 @@ fail_tree_roots:
3331fail_sb_buffer: 3368fail_sb_buffer:
3332 btrfs_stop_all_workers(fs_info); 3369 btrfs_stop_all_workers(fs_info);
3333 btrfs_free_block_groups(fs_info); 3370 btrfs_free_block_groups(fs_info);
3371fail_csum:
3372 btrfs_free_csum_hash(fs_info);
3334fail_alloc: 3373fail_alloc:
3335fail_iput: 3374fail_iput:
3336 btrfs_mapping_tree_free(&fs_info->mapping_tree); 3375 btrfs_mapping_tree_free(&fs_info->mapping_tree);
@@ -3472,17 +3511,20 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
3472static int write_dev_supers(struct btrfs_device *device, 3511static int write_dev_supers(struct btrfs_device *device,
3473 struct btrfs_super_block *sb, int max_mirrors) 3512 struct btrfs_super_block *sb, int max_mirrors)
3474{ 3513{
3514 struct btrfs_fs_info *fs_info = device->fs_info;
3515 SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
3475 struct buffer_head *bh; 3516 struct buffer_head *bh;
3476 int i; 3517 int i;
3477 int ret; 3518 int ret;
3478 int errors = 0; 3519 int errors = 0;
3479 u32 crc;
3480 u64 bytenr; 3520 u64 bytenr;
3481 int op_flags; 3521 int op_flags;
3482 3522
3483 if (max_mirrors == 0) 3523 if (max_mirrors == 0)
3484 max_mirrors = BTRFS_SUPER_MIRROR_MAX; 3524 max_mirrors = BTRFS_SUPER_MIRROR_MAX;
3485 3525
3526 shash->tfm = fs_info->csum_shash;
3527
3486 for (i = 0; i < max_mirrors; i++) { 3528 for (i = 0; i < max_mirrors; i++) {
3487 bytenr = btrfs_sb_offset(i); 3529 bytenr = btrfs_sb_offset(i);
3488 if (bytenr + BTRFS_SUPER_INFO_SIZE >= 3530 if (bytenr + BTRFS_SUPER_INFO_SIZE >=
@@ -3491,10 +3533,10 @@ static int write_dev_supers(struct btrfs_device *device,
3491 3533
3492 btrfs_set_super_bytenr(sb, bytenr); 3534 btrfs_set_super_bytenr(sb, bytenr);
3493 3535
3494 crc = ~(u32)0; 3536 crypto_shash_init(shash);
3495 crc = btrfs_csum_data((const char *)sb + BTRFS_CSUM_SIZE, crc, 3537 crypto_shash_update(shash, (const char *)sb + BTRFS_CSUM_SIZE,
3496 BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); 3538 BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
3497 btrfs_csum_final(crc, sb->csum); 3539 crypto_shash_final(shash, sb->csum);
3498 3540
3499 /* One reference for us, and we leave it for the caller */ 3541 /* One reference for us, and we leave it for the caller */
3500 bh = __getblk(device->bdev, bytenr / BTRFS_BDEV_BLOCKSIZE, 3542 bh = __getblk(device->bdev, bytenr / BTRFS_BDEV_BLOCKSIZE,
@@ -3709,7 +3751,7 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
3709 3751
3710 if ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 || 3752 if ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 ||
3711 (flags & BTRFS_AVAIL_ALLOC_BIT_SINGLE)) 3753 (flags & BTRFS_AVAIL_ALLOC_BIT_SINGLE))
3712 min_tolerated = min(min_tolerated, 3754 min_tolerated = min_t(int, min_tolerated,
3713 btrfs_raid_array[BTRFS_RAID_SINGLE]. 3755 btrfs_raid_array[BTRFS_RAID_SINGLE].
3714 tolerated_failures); 3756 tolerated_failures);
3715 3757
@@ -3718,7 +3760,7 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
3718 continue; 3760 continue;
3719 if (!(flags & btrfs_raid_array[raid_type].bg_flag)) 3761 if (!(flags & btrfs_raid_array[raid_type].bg_flag))
3720 continue; 3762 continue;
3721 min_tolerated = min(min_tolerated, 3763 min_tolerated = min_t(int, min_tolerated,
3722 btrfs_raid_array[raid_type]. 3764 btrfs_raid_array[raid_type].
3723 tolerated_failures); 3765 tolerated_failures);
3724 } 3766 }