diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 166 |
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 | ||
252 | u32 btrfs_csum_data(const char *data, u32 seed, size_t len) | ||
253 | { | ||
254 | return crc32c(seed, data, len); | ||
255 | } | ||
256 | |||
257 | void 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 | */ |
267 | static int csum_tree_block(struct extent_buffer *buf, u8 *result) | 254 | static 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 | ||
350 | static 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 | ||
397 | int btrfs_verify_level_key(struct extent_buffer *eb, int level, | 390 | int 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 | ||
876 | static int check_async_write(struct btrfs_inode *bi) | 869 | static 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 | ||
2257 | static 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 | |||
2275 | static void btrfs_free_csum_hash(struct btrfs_fs_info *fs_info) | ||
2276 | { | ||
2277 | crypto_free_shash(fs_info->csum_shash); | ||
2278 | } | ||
2279 | |||
2265 | static int btrfs_replay_log(struct btrfs_fs_info *fs_info, | 2280 | static 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: | |||
3331 | fail_sb_buffer: | 3368 | fail_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); |
3371 | fail_csum: | ||
3372 | btrfs_free_csum_hash(fs_info); | ||
3334 | fail_alloc: | 3373 | fail_alloc: |
3335 | fail_iput: | 3374 | fail_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) | |||
3472 | static int write_dev_supers(struct btrfs_device *device, | 3511 | static 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 | } |