aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-11 15:38:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-11 15:38:25 -0400
commite91eb6204fb826116453e43d4f5cf0f666bf46fe (patch)
treee688157b2ac689e32bacbdba8c8d185431d7f7e2 /fs/btrfs/disk-io.c
parente013f74b60bbd37ee8c3a55214eb351ea3101c15 (diff)
parent527afb4493c2892ce89fb74648e72a30b68ba120 (diff)
Merge branch 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs cleanups and fixes from Chris Mason: "These are small cleanups, and also some fixes for our async worker thread initialization. I was having some trouble testing these, but it ended up being a combination of changing around my test servers and a shiny new schedule while atomic from the new start/finish_plug in writeback_sb_inodes(). That one only hits on btrfs raid5/6 or MD raid10, and if I wasn't changing a bunch of things in my test setup at once it would have been really clear. Fix for writeback_sb_inodes() on the way as well" * 'for-linus-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: cleanup: remove unnecessary check before btrfs_free_path is called btrfs: async_thread: Fix workqueue 'max_active' value when initializing btrfs: Add raid56 support for updating num_tolerated_disk_barrier_failures in btrfs_balance btrfs: Cleanup for btrfs_calc_num_tolerated_disk_barrier_failures btrfs: Remove noused chunk_tree and chunk_objectid from scrub_enumerate_chunks and scrub_chunk btrfs: Update out-of-date "skip parity stripe" comment
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 9ebd34f1c677..0d98aee34fee 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3443,6 +3443,26 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
3443 return 0; 3443 return 0;
3444} 3444}
3445 3445
3446int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
3447{
3448 if ((flags & (BTRFS_BLOCK_GROUP_DUP |
3449 BTRFS_BLOCK_GROUP_RAID0 |
3450 BTRFS_AVAIL_ALLOC_BIT_SINGLE)) ||
3451 ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0))
3452 return 0;
3453
3454 if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3455 BTRFS_BLOCK_GROUP_RAID5 |
3456 BTRFS_BLOCK_GROUP_RAID10))
3457 return 1;
3458
3459 if (flags & BTRFS_BLOCK_GROUP_RAID6)
3460 return 2;
3461
3462 pr_warn("BTRFS: unknown raid type: %llu\n", flags);
3463 return 0;
3464}
3465
3446int btrfs_calc_num_tolerated_disk_barrier_failures( 3466int btrfs_calc_num_tolerated_disk_barrier_failures(
3447 struct btrfs_fs_info *fs_info) 3467 struct btrfs_fs_info *fs_info)
3448{ 3468{
@@ -3452,13 +3472,12 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
3452 BTRFS_BLOCK_GROUP_SYSTEM, 3472 BTRFS_BLOCK_GROUP_SYSTEM,
3453 BTRFS_BLOCK_GROUP_METADATA, 3473 BTRFS_BLOCK_GROUP_METADATA,
3454 BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA}; 3474 BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA};
3455 int num_types = 4;
3456 int i; 3475 int i;
3457 int c; 3476 int c;
3458 int num_tolerated_disk_barrier_failures = 3477 int num_tolerated_disk_barrier_failures =
3459 (int)fs_info->fs_devices->num_devices; 3478 (int)fs_info->fs_devices->num_devices;
3460 3479
3461 for (i = 0; i < num_types; i++) { 3480 for (i = 0; i < ARRAY_SIZE(types); i++) {
3462 struct btrfs_space_info *tmp; 3481 struct btrfs_space_info *tmp;
3463 3482
3464 sinfo = NULL; 3483 sinfo = NULL;
@@ -3476,44 +3495,21 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
3476 3495
3477 down_read(&sinfo->groups_sem); 3496 down_read(&sinfo->groups_sem);
3478 for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) { 3497 for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
3479 if (!list_empty(&sinfo->block_groups[c])) { 3498 u64 flags;
3480 u64 flags; 3499
3481 3500 if (list_empty(&sinfo->block_groups[c]))
3482 btrfs_get_block_group_info( 3501 continue;
3483 &sinfo->block_groups[c], &space); 3502
3484 if (space.total_bytes == 0 || 3503 btrfs_get_block_group_info(&sinfo->block_groups[c],
3485 space.used_bytes == 0) 3504 &space);
3486 continue; 3505 if (space.total_bytes == 0 || space.used_bytes == 0)
3487 flags = space.flags; 3506 continue;
3488 /* 3507 flags = space.flags;
3489 * return 3508
3490 * 0: if dup, single or RAID0 is configured for 3509 num_tolerated_disk_barrier_failures = min(
3491 * any of metadata, system or data, else 3510 num_tolerated_disk_barrier_failures,
3492 * 1: if RAID5 is configured, or if RAID1 or 3511 btrfs_get_num_tolerated_disk_barrier_failures(
3493 * RAID10 is configured and only two mirrors 3512 flags));
3494 * are used, else
3495 * 2: if RAID6 is configured, else
3496 * num_mirrors - 1: if RAID1 or RAID10 is
3497 * configured and more than
3498 * 2 mirrors are used.
3499 */
3500 if (num_tolerated_disk_barrier_failures > 0 &&
3501 ((flags & (BTRFS_BLOCK_GROUP_DUP |
3502 BTRFS_BLOCK_GROUP_RAID0)) ||
3503 ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK)
3504 == 0)))
3505 num_tolerated_disk_barrier_failures = 0;
3506 else if (num_tolerated_disk_barrier_failures > 1) {
3507 if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3508 BTRFS_BLOCK_GROUP_RAID5 |
3509 BTRFS_BLOCK_GROUP_RAID10)) {
3510 num_tolerated_disk_barrier_failures = 1;
3511 } else if (flags &
3512 BTRFS_BLOCK_GROUP_RAID6) {
3513 num_tolerated_disk_barrier_failures = 2;
3514 }
3515 }
3516 }
3517 } 3513 }
3518 up_read(&sinfo->groups_sem); 3514 up_read(&sinfo->groups_sem);
3519 } 3515 }