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>
@@ -639,8 +640,15 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
639
640
btree_readahead_hook (root , eb , eb -> start , ret );
640
641
}
641
642
642
- if (ret )
643
+ if (ret ) {
644
+ /*
645
+ * our io error hook is going to dec the io pages
646
+ * again, we have to make sure it has something
647
+ * to decrement
648
+ */
649
+ atomic_inc (& eb -> io_pages );
643
650
clear_extent_buffer_uptodate (eb );
651
+ }
644
652
free_extent_buffer (eb );
645
653
out :
646
654
return ret ;
@@ -654,6 +662,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
654
662
eb = (struct extent_buffer * )page -> private ;
655
663
set_bit (EXTENT_BUFFER_IOERR , & eb -> bflags );
656
664
eb -> read_mirror = failed_mirror ;
665
+ atomic_dec (& eb -> io_pages );
657
666
if (test_and_clear_bit (EXTENT_BUFFER_READAHEAD , & eb -> bflags ))
658
667
btree_readahead_hook (root , eb , eb -> start , - EIO );
659
668
return - EIO ; /* we fixed nothing */
@@ -670,17 +679,23 @@ static void end_workqueue_bio(struct bio *bio, int err)
670
679
end_io_wq -> work .flags = 0 ;
671
680
672
681
if (bio -> bi_rw & REQ_WRITE ) {
673
- if (end_io_wq -> metadata == 1 )
682
+ if (end_io_wq -> metadata == BTRFS_WQ_ENDIO_METADATA )
674
683
btrfs_queue_worker (& fs_info -> endio_meta_write_workers ,
675
684
& end_io_wq -> work );
676
- else if (end_io_wq -> metadata == 2 )
685
+ else if (end_io_wq -> metadata == BTRFS_WQ_ENDIO_FREE_SPACE )
677
686
btrfs_queue_worker (& fs_info -> endio_freespace_worker ,
678
687
& end_io_wq -> work );
688
+ else if (end_io_wq -> metadata == BTRFS_WQ_ENDIO_RAID56 )
689
+ btrfs_queue_worker (& fs_info -> endio_raid56_workers ,
690
+ & end_io_wq -> work );
679
691
else
680
692
btrfs_queue_worker (& fs_info -> endio_write_workers ,
681
693
& end_io_wq -> work );
682
694
} else {
683
- if (end_io_wq -> metadata )
695
+ if (end_io_wq -> metadata == BTRFS_WQ_ENDIO_RAID56 )
696
+ btrfs_queue_worker (& fs_info -> endio_raid56_workers ,
697
+ & end_io_wq -> work );
698
+ else if (end_io_wq -> metadata )
684
699
btrfs_queue_worker (& fs_info -> endio_meta_workers ,
685
700
& end_io_wq -> work );
686
701
else
@@ -695,6 +710,7 @@ static void end_workqueue_bio(struct bio *bio, int err)
695
710
* 0 - if data
696
711
* 1 - if normal metadta
697
712
* 2 - if writing to the free space cache area
713
+ * 3 - raid parity work
698
714
*/
699
715
int btrfs_bio_wq_end_io (struct btrfs_fs_info * info , struct bio * bio ,
700
716
int metadata )
@@ -2165,6 +2181,12 @@ int open_ctree(struct super_block *sb,
2165
2181
init_waitqueue_head (& fs_info -> transaction_blocked_wait );
2166
2182
init_waitqueue_head (& fs_info -> async_submit_wait );
2167
2183
2184
+ ret = btrfs_alloc_stripe_hash_table (fs_info );
2185
+ if (ret ) {
2186
+ err = - ENOMEM ;
2187
+ goto fail_alloc ;
2188
+ }
2189
+
2168
2190
__setup_root (4096 , 4096 , 4096 , 4096 , tree_root ,
2169
2191
fs_info , BTRFS_ROOT_TREE_OBJECTID );
2170
2192
@@ -2332,6 +2354,12 @@ int open_ctree(struct super_block *sb,
2332
2354
btrfs_init_workers (& fs_info -> endio_meta_write_workers ,
2333
2355
"endio-meta-write" , fs_info -> thread_pool_size ,
2334
2356
& fs_info -> generic_worker );
2357
+ btrfs_init_workers (& fs_info -> endio_raid56_workers ,
2358
+ "endio-raid56" , fs_info -> thread_pool_size ,
2359
+ & fs_info -> generic_worker );
2360
+ btrfs_init_workers (& fs_info -> rmw_workers ,
2361
+ "rmw" , fs_info -> thread_pool_size ,
2362
+ & fs_info -> generic_worker );
2335
2363
btrfs_init_workers (& fs_info -> endio_write_workers , "endio-write" ,
2336
2364
fs_info -> thread_pool_size ,
2337
2365
& fs_info -> generic_worker );
@@ -2350,6 +2378,8 @@ int open_ctree(struct super_block *sb,
2350
2378
*/
2351
2379
fs_info -> endio_workers .idle_thresh = 4 ;
2352
2380
fs_info -> endio_meta_workers .idle_thresh = 4 ;
2381
+ fs_info -> endio_raid56_workers .idle_thresh = 4 ;
2382
+ fs_info -> rmw_workers .idle_thresh = 2 ;
2353
2383
2354
2384
fs_info -> endio_write_workers .idle_thresh = 2 ;
2355
2385
fs_info -> endio_meta_write_workers .idle_thresh = 2 ;
@@ -2366,6 +2396,8 @@ int open_ctree(struct super_block *sb,
2366
2396
ret |= btrfs_start_workers (& fs_info -> fixup_workers );
2367
2397
ret |= btrfs_start_workers (& fs_info -> endio_workers );
2368
2398
ret |= btrfs_start_workers (& fs_info -> endio_meta_workers );
2399
+ ret |= btrfs_start_workers (& fs_info -> rmw_workers );
2400
+ ret |= btrfs_start_workers (& fs_info -> endio_raid56_workers );
2369
2401
ret |= btrfs_start_workers (& fs_info -> endio_meta_write_workers );
2370
2402
ret |= btrfs_start_workers (& fs_info -> endio_write_workers );
2371
2403
ret |= btrfs_start_workers (& fs_info -> endio_freespace_worker );
@@ -2710,6 +2742,8 @@ int open_ctree(struct super_block *sb,
2710
2742
btrfs_stop_workers (& fs_info -> workers );
2711
2743
btrfs_stop_workers (& fs_info -> endio_workers );
2712
2744
btrfs_stop_workers (& fs_info -> endio_meta_workers );
2745
+ btrfs_stop_workers (& fs_info -> endio_raid56_workers );
2746
+ btrfs_stop_workers (& fs_info -> rmw_workers );
2713
2747
btrfs_stop_workers (& fs_info -> endio_meta_write_workers );
2714
2748
btrfs_stop_workers (& fs_info -> endio_write_workers );
2715
2749
btrfs_stop_workers (& fs_info -> endio_freespace_worker );
@@ -2728,6 +2762,7 @@ int open_ctree(struct super_block *sb,
2728
2762
fail_srcu :
2729
2763
cleanup_srcu_struct (& fs_info -> subvol_srcu );
2730
2764
fail :
2765
+ btrfs_free_stripe_hash_table (fs_info );
2731
2766
btrfs_close_devices (fs_info -> fs_devices );
2732
2767
return err ;
2733
2768
@@ -3076,11 +3111,16 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
3076
3111
((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK )
3077
3112
== 0 )))
3078
3113
num_tolerated_disk_barrier_failures = 0 ;
3079
- else if (num_tolerated_disk_barrier_failures > 1
3080
- &&
3081
- (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3082
- BTRFS_BLOCK_GROUP_RAID10 )))
3083
- num_tolerated_disk_barrier_failures = 1 ;
3114
+ else if (num_tolerated_disk_barrier_failures > 1 ) {
3115
+ if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
3116
+ BTRFS_BLOCK_GROUP_RAID5 |
3117
+ BTRFS_BLOCK_GROUP_RAID10 )) {
3118
+ num_tolerated_disk_barrier_failures = 1 ;
3119
+ } else if (flags &
3120
+ BTRFS_BLOCK_GROUP_RAID5 ) {
3121
+ num_tolerated_disk_barrier_failures = 2 ;
3122
+ }
3123
+ }
3084
3124
}
3085
3125
}
3086
3126
up_read (& sinfo -> groups_sem );
@@ -3384,6 +3424,8 @@ int close_ctree(struct btrfs_root *root)
3384
3424
btrfs_stop_workers (& fs_info -> workers );
3385
3425
btrfs_stop_workers (& fs_info -> endio_workers );
3386
3426
btrfs_stop_workers (& fs_info -> endio_meta_workers );
3427
+ btrfs_stop_workers (& fs_info -> endio_raid56_workers );
3428
+ btrfs_stop_workers (& fs_info -> rmw_workers );
3387
3429
btrfs_stop_workers (& fs_info -> endio_meta_write_workers );
3388
3430
btrfs_stop_workers (& fs_info -> endio_write_workers );
3389
3431
btrfs_stop_workers (& fs_info -> endio_freespace_worker );
@@ -3404,6 +3446,8 @@ int close_ctree(struct btrfs_root *root)
3404
3446
bdi_destroy (& fs_info -> bdi );
3405
3447
cleanup_srcu_struct (& fs_info -> subvol_srcu );
3406
3448
3449
+ btrfs_free_stripe_hash_table (fs_info );
3450
+
3407
3451
return 0 ;
3408
3452
}
3409
3453
0 commit comments