diff options
author | Chris Mason <chris.mason@fusionio.com> | 2013-02-20 14:06:05 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-02-20 14:06:05 -0500 |
commit | e942f883bc6651d50be139477baf6fb0eed3d5bb (patch) | |
tree | e1d19783e9c8b42198a69c17c9719fb90f302847 /fs/btrfs/disk-io.c | |
parent | b2c6b3e0611c58fbeb6b9c0892b6249f7bdfaf6b (diff) | |
parent | 0e4e02636611dbf89a2f36320a32054f9936d6cb (diff) |
Merge branch 'raid56-experimental' into for-linus-3.9
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Conflicts:
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/inode.c
fs/btrfs/volumes.c
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 779b401cd952..eb7c14308521 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include "check-integrity.h" | 46 | #include "check-integrity.h" |
47 | #include "rcu-string.h" | 47 | #include "rcu-string.h" |
48 | #include "dev-replace.h" | 48 | #include "dev-replace.h" |
49 | #include "raid56.h" | ||
49 | 50 | ||
50 | #ifdef CONFIG_X86 | 51 | #ifdef CONFIG_X86 |
51 | #include <asm/cpufeature.h> | 52 | #include <asm/cpufeature.h> |
@@ -640,8 +641,15 @@ err: | |||
640 | btree_readahead_hook(root, eb, eb->start, ret); | 641 | btree_readahead_hook(root, eb, eb->start, ret); |
641 | } | 642 | } |
642 | 643 | ||
643 | if (ret) | 644 | if (ret) { |
645 | /* | ||
646 | * our io error hook is going to dec the io pages | ||
647 | * again, we have to make sure it has something | ||
648 | * to decrement | ||
649 | */ | ||
650 | atomic_inc(&eb->io_pages); | ||
644 | clear_extent_buffer_uptodate(eb); | 651 | clear_extent_buffer_uptodate(eb); |
652 | } | ||
645 | free_extent_buffer(eb); | 653 | free_extent_buffer(eb); |
646 | out: | 654 | out: |
647 | return ret; | 655 | return ret; |
@@ -655,6 +663,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror) | |||
655 | eb = (struct extent_buffer *)page->private; | 663 | eb = (struct extent_buffer *)page->private; |
656 | set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); | 664 | set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); |
657 | eb->read_mirror = failed_mirror; | 665 | eb->read_mirror = failed_mirror; |
666 | atomic_dec(&eb->io_pages); | ||
658 | if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) | 667 | if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) |
659 | btree_readahead_hook(root, eb, eb->start, -EIO); | 668 | btree_readahead_hook(root, eb, eb->start, -EIO); |
660 | return -EIO; /* we fixed nothing */ | 669 | return -EIO; /* we fixed nothing */ |
@@ -671,17 +680,23 @@ static void end_workqueue_bio(struct bio *bio, int err) | |||
671 | end_io_wq->work.flags = 0; | 680 | end_io_wq->work.flags = 0; |
672 | 681 | ||
673 | if (bio->bi_rw & REQ_WRITE) { | 682 | if (bio->bi_rw & REQ_WRITE) { |
674 | if (end_io_wq->metadata == 1) | 683 | if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) |
675 | btrfs_queue_worker(&fs_info->endio_meta_write_workers, | 684 | btrfs_queue_worker(&fs_info->endio_meta_write_workers, |
676 | &end_io_wq->work); | 685 | &end_io_wq->work); |
677 | else if (end_io_wq->metadata == 2) | 686 | else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_FREE_SPACE) |
678 | btrfs_queue_worker(&fs_info->endio_freespace_worker, | 687 | btrfs_queue_worker(&fs_info->endio_freespace_worker, |
679 | &end_io_wq->work); | 688 | &end_io_wq->work); |
689 | else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56) | ||
690 | btrfs_queue_worker(&fs_info->endio_raid56_workers, | ||
691 | &end_io_wq->work); | ||
680 | else | 692 | else |
681 | btrfs_queue_worker(&fs_info->endio_write_workers, | 693 | btrfs_queue_worker(&fs_info->endio_write_workers, |
682 | &end_io_wq->work); | 694 | &end_io_wq->work); |
683 | } else { | 695 | } else { |
684 | if (end_io_wq->metadata) | 696 | if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56) |
697 | btrfs_queue_worker(&fs_info->endio_raid56_workers, | ||
698 | &end_io_wq->work); | ||
699 | else if (end_io_wq->metadata) | ||
685 | btrfs_queue_worker(&fs_info->endio_meta_workers, | 700 | btrfs_queue_worker(&fs_info->endio_meta_workers, |
686 | &end_io_wq->work); | 701 | &end_io_wq->work); |
687 | else | 702 | else |
@@ -696,6 +711,7 @@ static void end_workqueue_bio(struct bio *bio, int err) | |||
696 | * 0 - if data | 711 | * 0 - if data |
697 | * 1 - if normal metadta | 712 | * 1 - if normal metadta |
698 | * 2 - if writing to the free space cache area | 713 | * 2 - if writing to the free space cache area |
714 | * 3 - raid parity work | ||
699 | */ | 715 | */ |
700 | int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, | 716 | int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, |
701 | int metadata) | 717 | int metadata) |
@@ -2179,6 +2195,12 @@ int open_ctree(struct super_block *sb, | |||
2179 | init_waitqueue_head(&fs_info->transaction_blocked_wait); | 2195 | init_waitqueue_head(&fs_info->transaction_blocked_wait); |
2180 | init_waitqueue_head(&fs_info->async_submit_wait); | 2196 | init_waitqueue_head(&fs_info->async_submit_wait); |
2181 | 2197 | ||
2198 | ret = btrfs_alloc_stripe_hash_table(fs_info); | ||
2199 | if (ret) { | ||
2200 | err = -ENOMEM; | ||
2201 | goto fail_alloc; | ||
2202 | } | ||
2203 | |||
2182 | __setup_root(4096, 4096, 4096, 4096, tree_root, | 2204 | __setup_root(4096, 4096, 4096, 4096, tree_root, |
2183 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 2205 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
2184 | 2206 | ||
@@ -2349,6 +2371,12 @@ int open_ctree(struct super_block *sb, | |||
2349 | btrfs_init_workers(&fs_info->endio_meta_write_workers, | 2371 | btrfs_init_workers(&fs_info->endio_meta_write_workers, |
2350 | "endio-meta-write", fs_info->thread_pool_size, | 2372 | "endio-meta-write", fs_info->thread_pool_size, |
2351 | &fs_info->generic_worker); | 2373 | &fs_info->generic_worker); |
2374 | btrfs_init_workers(&fs_info->endio_raid56_workers, | ||
2375 | "endio-raid56", fs_info->thread_pool_size, | ||
2376 | &fs_info->generic_worker); | ||
2377 | btrfs_init_workers(&fs_info->rmw_workers, | ||
2378 | "rmw", fs_info->thread_pool_size, | ||
2379 | &fs_info->generic_worker); | ||
2352 | btrfs_init_workers(&fs_info->endio_write_workers, "endio-write", | 2380 | btrfs_init_workers(&fs_info->endio_write_workers, "endio-write", |
2353 | fs_info->thread_pool_size, | 2381 | fs_info->thread_pool_size, |
2354 | &fs_info->generic_worker); | 2382 | &fs_info->generic_worker); |
@@ -2367,6 +2395,8 @@ int open_ctree(struct super_block *sb, | |||
2367 | */ | 2395 | */ |
2368 | fs_info->endio_workers.idle_thresh = 4; | 2396 | fs_info->endio_workers.idle_thresh = 4; |
2369 | fs_info->endio_meta_workers.idle_thresh = 4; | 2397 | fs_info->endio_meta_workers.idle_thresh = 4; |
2398 | fs_info->endio_raid56_workers.idle_thresh = 4; | ||
2399 | fs_info->rmw_workers.idle_thresh = 2; | ||
2370 | 2400 | ||
2371 | fs_info->endio_write_workers.idle_thresh = 2; | 2401 | fs_info->endio_write_workers.idle_thresh = 2; |
2372 | fs_info->endio_meta_write_workers.idle_thresh = 2; | 2402 | fs_info->endio_meta_write_workers.idle_thresh = 2; |
@@ -2383,6 +2413,8 @@ int open_ctree(struct super_block *sb, | |||
2383 | ret |= btrfs_start_workers(&fs_info->fixup_workers); | 2413 | ret |= btrfs_start_workers(&fs_info->fixup_workers); |
2384 | ret |= btrfs_start_workers(&fs_info->endio_workers); | 2414 | ret |= btrfs_start_workers(&fs_info->endio_workers); |
2385 | ret |= btrfs_start_workers(&fs_info->endio_meta_workers); | 2415 | ret |= btrfs_start_workers(&fs_info->endio_meta_workers); |
2416 | ret |= btrfs_start_workers(&fs_info->rmw_workers); | ||
2417 | ret |= btrfs_start_workers(&fs_info->endio_raid56_workers); | ||
2386 | ret |= btrfs_start_workers(&fs_info->endio_meta_write_workers); | 2418 | ret |= btrfs_start_workers(&fs_info->endio_meta_write_workers); |
2387 | ret |= btrfs_start_workers(&fs_info->endio_write_workers); | 2419 | ret |= btrfs_start_workers(&fs_info->endio_write_workers); |
2388 | ret |= btrfs_start_workers(&fs_info->endio_freespace_worker); | 2420 | ret |= btrfs_start_workers(&fs_info->endio_freespace_worker); |
@@ -2726,6 +2758,8 @@ fail_sb_buffer: | |||
2726 | btrfs_stop_workers(&fs_info->workers); | 2758 | btrfs_stop_workers(&fs_info->workers); |
2727 | btrfs_stop_workers(&fs_info->endio_workers); | 2759 | btrfs_stop_workers(&fs_info->endio_workers); |
2728 | btrfs_stop_workers(&fs_info->endio_meta_workers); | 2760 | btrfs_stop_workers(&fs_info->endio_meta_workers); |
2761 | btrfs_stop_workers(&fs_info->endio_raid56_workers); | ||
2762 | btrfs_stop_workers(&fs_info->rmw_workers); | ||
2729 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); | 2763 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); |
2730 | btrfs_stop_workers(&fs_info->endio_write_workers); | 2764 | btrfs_stop_workers(&fs_info->endio_write_workers); |
2731 | btrfs_stop_workers(&fs_info->endio_freespace_worker); | 2765 | btrfs_stop_workers(&fs_info->endio_freespace_worker); |
@@ -2747,6 +2781,7 @@ fail_bdi: | |||
2747 | fail_srcu: | 2781 | fail_srcu: |
2748 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 2782 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
2749 | fail: | 2783 | fail: |
2784 | btrfs_free_stripe_hash_table(fs_info); | ||
2750 | btrfs_close_devices(fs_info->fs_devices); | 2785 | btrfs_close_devices(fs_info->fs_devices); |
2751 | return err; | 2786 | return err; |
2752 | 2787 | ||
@@ -3094,11 +3129,16 @@ int btrfs_calc_num_tolerated_disk_barrier_failures( | |||
3094 | ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) | 3129 | ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) |
3095 | == 0))) | 3130 | == 0))) |
3096 | num_tolerated_disk_barrier_failures = 0; | 3131 | num_tolerated_disk_barrier_failures = 0; |
3097 | else if (num_tolerated_disk_barrier_failures > 1 | 3132 | else if (num_tolerated_disk_barrier_failures > 1) { |
3098 | && | 3133 | if (flags & (BTRFS_BLOCK_GROUP_RAID1 | |
3099 | (flags & (BTRFS_BLOCK_GROUP_RAID1 | | 3134 | BTRFS_BLOCK_GROUP_RAID5 | |
3100 | BTRFS_BLOCK_GROUP_RAID10))) | 3135 | BTRFS_BLOCK_GROUP_RAID10)) { |
3101 | num_tolerated_disk_barrier_failures = 1; | 3136 | num_tolerated_disk_barrier_failures = 1; |
3137 | } else if (flags & | ||
3138 | BTRFS_BLOCK_GROUP_RAID5) { | ||
3139 | num_tolerated_disk_barrier_failures = 2; | ||
3140 | } | ||
3141 | } | ||
3102 | } | 3142 | } |
3103 | } | 3143 | } |
3104 | up_read(&sinfo->groups_sem); | 3144 | up_read(&sinfo->groups_sem); |
@@ -3402,6 +3442,8 @@ int close_ctree(struct btrfs_root *root) | |||
3402 | btrfs_stop_workers(&fs_info->workers); | 3442 | btrfs_stop_workers(&fs_info->workers); |
3403 | btrfs_stop_workers(&fs_info->endio_workers); | 3443 | btrfs_stop_workers(&fs_info->endio_workers); |
3404 | btrfs_stop_workers(&fs_info->endio_meta_workers); | 3444 | btrfs_stop_workers(&fs_info->endio_meta_workers); |
3445 | btrfs_stop_workers(&fs_info->endio_raid56_workers); | ||
3446 | btrfs_stop_workers(&fs_info->rmw_workers); | ||
3405 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); | 3447 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); |
3406 | btrfs_stop_workers(&fs_info->endio_write_workers); | 3448 | btrfs_stop_workers(&fs_info->endio_write_workers); |
3407 | btrfs_stop_workers(&fs_info->endio_freespace_worker); | 3449 | btrfs_stop_workers(&fs_info->endio_freespace_worker); |
@@ -3424,6 +3466,8 @@ int close_ctree(struct btrfs_root *root) | |||
3424 | bdi_destroy(&fs_info->bdi); | 3466 | bdi_destroy(&fs_info->bdi); |
3425 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 3467 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
3426 | 3468 | ||
3469 | btrfs_free_stripe_hash_table(fs_info); | ||
3470 | |||
3427 | return 0; | 3471 | return 0; |
3428 | } | 3472 | } |
3429 | 3473 | ||