46
46
#include "check-integrity.h"
47
47
#include "rcu-string.h"
48
48
#include "dev-replace.h"
49
+ #include "raid56.h"
49
50
50
51
#ifdef CONFIG_X86
51
52
#include <asm/cpufeature.h>
@@ -640,8 +641,15 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
640
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
651
clear_extent_buffer_uptodate (eb );
652
+ }
645
653
free_extent_buffer (eb );
646
654
out :
647
655
return ret ;
@@ -655,6 +663,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
655
663
eb = (struct extent_buffer * )page -> private ;
656
664
set_bit (EXTENT_BUFFER_IOERR , & eb -> bflags );
657
665
eb -> read_mirror = failed_mirror ;
666
+ atomic_dec (& eb -> io_pages );
658
667
if (test_and_clear_bit (EXTENT_BUFFER_READAHEAD , & eb -> bflags ))
659
668
btree_readahead_hook (root , eb , eb -> start , - EIO );
660
669
return - EIO ; /* we fixed nothing */
@@ -671,17 +680,23 @@ static void end_workqueue_bio(struct bio *bio, int err)
671
680
end_io_wq -> work .flags = 0 ;
672
681
673
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
684
btrfs_queue_worker (& fs_info -> endio_meta_write_workers ,
676
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
687
btrfs_queue_worker (& fs_info -> endio_freespace_worker ,
679
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
692
else
681
693
btrfs_queue_worker (& fs_info -> endio_write_workers ,
682
694
& end_io_wq -> work );
683
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
700
btrfs_queue_worker (& fs_info -> endio_meta_workers ,
686
701
& end_io_wq -> work );
687
702
else
@@ -696,6 +711,7 @@ static void end_workqueue_bio(struct bio *bio, int err)
696
711
* 0 - if data
697
712
* 1 - if normal metadta
698
713
* 2 - if writing to the free space cache area
714
+ * 3 - raid parity work
699
715
*/
700
716
int btrfs_bio_wq_end_io (struct btrfs_fs_info * info , struct bio * bio ,
701
717
int metadata )
@@ -2179,6 +2195,12 @@ int open_ctree(struct super_block *sb,
2179
2195
init_waitqueue_head (& fs_info -> transaction_blocked_wait );
2180
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
2204
__setup_root (4096 , 4096 , 4096 , 4096 , tree_root ,
2183
2205
fs_info , BTRFS_ROOT_TREE_OBJECTID );
2184
2206
@@ -2349,6 +2371,12 @@ int open_ctree(struct super_block *sb,
2349
2371
btrfs_init_workers (& fs_info -> endio_meta_write_workers ,
2350
2372
"endio-meta-write" , fs_info -> thread_pool_size ,
2351
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
2380
btrfs_init_workers (& fs_info -> endio_write_workers , "endio-write" ,
2353
2381
fs_info -> thread_pool_size ,
2354
2382
& fs_info -> generic_worker );
@@ -2367,6 +2395,8 @@ int open_ctree(struct super_block *sb,
2367
2395
*/
2368
2396
fs_info -> endio_workers .idle_thresh = 4 ;
2369
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
2401
fs_info -> endio_write_workers .idle_thresh = 2 ;
2372
2402
fs_info -> endio_meta_write_workers .idle_thresh = 2 ;
@@ -2383,6 +2413,8 @@ int open_ctree(struct super_block *sb,
2383
2413
ret |= btrfs_start_workers (& fs_info -> fixup_workers );
2384
2414
ret |= btrfs_start_workers (& fs_info -> endio_workers );
2385
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
2418
ret |= btrfs_start_workers (& fs_info -> endio_meta_write_workers );
2387
2419
ret |= btrfs_start_workers (& fs_info -> endio_write_workers );
2388
2420
ret |= btrfs_start_workers (& fs_info -> endio_freespace_worker );
@@ -2726,6 +2758,8 @@ int open_ctree(struct super_block *sb,
2726
2758
btrfs_stop_workers (& fs_info -> workers );
2727
2759
btrfs_stop_workers (& fs_info -> endio_workers );
2728
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
2763
btrfs_stop_workers (& fs_info -> endio_meta_write_workers );
2730
2764
btrfs_stop_workers (& fs_info -> endio_write_workers );
2731
2765
btrfs_stop_workers (& fs_info -> endio_freespace_worker );
@@ -2747,6 +2781,7 @@ int open_ctree(struct super_block *sb,
2747
2781
fail_srcu :
2748
2782
cleanup_srcu_struct (& fs_info -> subvol_srcu );
2749
2783
fail :
2784
+ btrfs_free_stripe_hash_table (fs_info );
2750
2785
btrfs_close_devices (fs_info -> fs_devices );
2751
2786
return err ;
2752
2787
@@ -3094,11 +3129,16 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
3094
3129
((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK )
3095
3130
== 0 )))
3096
3131
num_tolerated_disk_barrier_failures = 0 ;
3097
- else if (num_tolerated_disk_barrier_failures > 1
3098
- &&
3099
- (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3100
- BTRFS_BLOCK_GROUP_RAID10 )))
3101
- num_tolerated_disk_barrier_failures = 1 ;
3132
+ else if (num_tolerated_disk_barrier_failures > 1 ) {
3133
+ if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3134
+ BTRFS_BLOCK_GROUP_RAID5 |
3135
+ BTRFS_BLOCK_GROUP_RAID10 )) {
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
3144
up_read (& sinfo -> groups_sem );
@@ -3402,6 +3442,8 @@ int close_ctree(struct btrfs_root *root)
3402
3442
btrfs_stop_workers (& fs_info -> workers );
3403
3443
btrfs_stop_workers (& fs_info -> endio_workers );
3404
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
3447
btrfs_stop_workers (& fs_info -> endio_meta_write_workers );
3406
3448
btrfs_stop_workers (& fs_info -> endio_write_workers );
3407
3449
btrfs_stop_workers (& fs_info -> endio_freespace_worker );
@@ -3424,6 +3466,8 @@ int close_ctree(struct btrfs_root *root)
3424
3466
bdi_destroy (& fs_info -> bdi );
3425
3467
cleanup_srcu_struct (& fs_info -> subvol_srcu );
3426
3468
3469
+ btrfs_free_stripe_hash_table (fs_info );
3470
+
3427
3471
return 0 ;
3428
3472
}
3429
3473
0 commit comments