.. | .. |
---|
751 | 751 | disk = r10_bio->devs[slot].devnum; |
---|
752 | 752 | rdev = rcu_dereference(conf->mirrors[disk].replacement); |
---|
753 | 753 | if (rdev == NULL || test_bit(Faulty, &rdev->flags) || |
---|
754 | | - r10_bio->devs[slot].addr + sectors > rdev->recovery_offset) |
---|
| 754 | + r10_bio->devs[slot].addr + sectors > |
---|
| 755 | + rdev->recovery_offset) { |
---|
| 756 | + /* |
---|
| 757 | + * Read replacement first to prevent reading both rdev |
---|
| 758 | + * and replacement as NULL during replacement replace |
---|
| 759 | + * rdev. |
---|
| 760 | + */ |
---|
| 761 | + smp_mb(); |
---|
755 | 762 | rdev = rcu_dereference(conf->mirrors[disk].rdev); |
---|
| 763 | + } |
---|
756 | 764 | if (rdev == NULL || |
---|
757 | 765 | test_bit(Faulty, &rdev->flags)) |
---|
758 | 766 | continue; |
---|
.. | .. |
---|
894 | 902 | else |
---|
895 | 903 | submit_bio_noacct(bio); |
---|
896 | 904 | bio = next; |
---|
| 905 | + cond_resched(); |
---|
897 | 906 | } |
---|
898 | 907 | blk_finish_plug(&plug); |
---|
899 | 908 | } else |
---|
.. | .. |
---|
1087 | 1096 | else |
---|
1088 | 1097 | submit_bio_noacct(bio); |
---|
1089 | 1098 | bio = next; |
---|
| 1099 | + cond_resched(); |
---|
1090 | 1100 | } |
---|
1091 | 1101 | kfree(plug); |
---|
1092 | 1102 | } |
---|
.. | .. |
---|
1346 | 1356 | |
---|
1347 | 1357 | for (i = 0; i < conf->copies; i++) { |
---|
1348 | 1358 | int d = r10_bio->devs[i].devnum; |
---|
1349 | | - struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev); |
---|
1350 | | - struct md_rdev *rrdev = rcu_dereference( |
---|
1351 | | - conf->mirrors[d].replacement); |
---|
| 1359 | + struct md_rdev *rdev, *rrdev; |
---|
| 1360 | + |
---|
| 1361 | + rrdev = rcu_dereference(conf->mirrors[d].replacement); |
---|
| 1362 | + /* |
---|
| 1363 | + * Read replacement first to prevent reading both rdev and |
---|
| 1364 | + * replacement as NULL during replacement replace rdev. |
---|
| 1365 | + */ |
---|
| 1366 | + smp_mb(); |
---|
| 1367 | + rdev = rcu_dereference(conf->mirrors[d].rdev); |
---|
1352 | 1368 | if (rdev == rrdev) |
---|
1353 | 1369 | rrdev = NULL; |
---|
1354 | 1370 | if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { |
---|
.. | .. |
---|
2212 | 2228 | { |
---|
2213 | 2229 | struct r10conf *conf = mddev->private; |
---|
2214 | 2230 | int d; |
---|
2215 | | - struct bio *wbio, *wbio2; |
---|
| 2231 | + struct bio *wbio = r10_bio->devs[1].bio; |
---|
| 2232 | + struct bio *wbio2 = r10_bio->devs[1].repl_bio; |
---|
| 2233 | + |
---|
| 2234 | + /* Need to test wbio2->bi_end_io before we call |
---|
| 2235 | + * submit_bio_noacct as if the former is NULL, |
---|
| 2236 | + * the latter is free to free wbio2. |
---|
| 2237 | + */ |
---|
| 2238 | + if (wbio2 && !wbio2->bi_end_io) |
---|
| 2239 | + wbio2 = NULL; |
---|
2216 | 2240 | |
---|
2217 | 2241 | if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) { |
---|
2218 | 2242 | fix_recovery_read_error(r10_bio); |
---|
2219 | | - end_sync_request(r10_bio); |
---|
| 2243 | + if (wbio->bi_end_io) |
---|
| 2244 | + end_sync_request(r10_bio); |
---|
| 2245 | + if (wbio2) |
---|
| 2246 | + end_sync_request(r10_bio); |
---|
2220 | 2247 | return; |
---|
2221 | 2248 | } |
---|
2222 | 2249 | |
---|
.. | .. |
---|
2225 | 2252 | * and submit the write request |
---|
2226 | 2253 | */ |
---|
2227 | 2254 | d = r10_bio->devs[1].devnum; |
---|
2228 | | - wbio = r10_bio->devs[1].bio; |
---|
2229 | | - wbio2 = r10_bio->devs[1].repl_bio; |
---|
2230 | | - /* Need to test wbio2->bi_end_io before we call |
---|
2231 | | - * submit_bio_noacct as if the former is NULL, |
---|
2232 | | - * the latter is free to free wbio2. |
---|
2233 | | - */ |
---|
2234 | | - if (wbio2 && !wbio2->bi_end_io) |
---|
2235 | | - wbio2 = NULL; |
---|
2236 | 2255 | if (wbio->bi_end_io) { |
---|
2237 | 2256 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); |
---|
2238 | 2257 | md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio)); |
---|
.. | .. |
---|
2900 | 2919 | sector_t chunk_mask = conf->geo.chunk_mask; |
---|
2901 | 2920 | int page_idx = 0; |
---|
2902 | 2921 | |
---|
2903 | | - if (!mempool_initialized(&conf->r10buf_pool)) |
---|
2904 | | - if (init_resync(conf)) |
---|
2905 | | - return 0; |
---|
2906 | | - |
---|
2907 | 2922 | /* |
---|
2908 | 2923 | * Allow skipping a full rebuild for incremental assembly |
---|
2909 | 2924 | * of a clean array, like RAID1 does. |
---|
.. | .. |
---|
2918 | 2933 | *skipped = 1; |
---|
2919 | 2934 | return mddev->dev_sectors - sector_nr; |
---|
2920 | 2935 | } |
---|
| 2936 | + |
---|
| 2937 | + if (!mempool_initialized(&conf->r10buf_pool)) |
---|
| 2938 | + if (init_resync(conf)) |
---|
| 2939 | + return 0; |
---|
2921 | 2940 | |
---|
2922 | 2941 | skipped: |
---|
2923 | 2942 | max_sector = mddev->dev_sectors; |
---|
.. | .. |
---|
3034 | 3053 | int must_sync; |
---|
3035 | 3054 | int any_working; |
---|
3036 | 3055 | int need_recover = 0; |
---|
3037 | | - int need_replace = 0; |
---|
3038 | 3056 | struct raid10_info *mirror = &conf->mirrors[i]; |
---|
3039 | 3057 | struct md_rdev *mrdev, *mreplace; |
---|
3040 | 3058 | |
---|
.. | .. |
---|
3046 | 3064 | !test_bit(Faulty, &mrdev->flags) && |
---|
3047 | 3065 | !test_bit(In_sync, &mrdev->flags)) |
---|
3048 | 3066 | need_recover = 1; |
---|
3049 | | - if (mreplace != NULL && |
---|
3050 | | - !test_bit(Faulty, &mreplace->flags)) |
---|
3051 | | - need_replace = 1; |
---|
| 3067 | + if (mreplace && test_bit(Faulty, &mreplace->flags)) |
---|
| 3068 | + mreplace = NULL; |
---|
3052 | 3069 | |
---|
3053 | | - if (!need_recover && !need_replace) { |
---|
| 3070 | + if (!need_recover && !mreplace) { |
---|
3054 | 3071 | rcu_read_unlock(); |
---|
3055 | 3072 | continue; |
---|
3056 | 3073 | } |
---|
.. | .. |
---|
3066 | 3083 | rcu_read_unlock(); |
---|
3067 | 3084 | continue; |
---|
3068 | 3085 | } |
---|
3069 | | - if (mreplace && test_bit(Faulty, &mreplace->flags)) |
---|
3070 | | - mreplace = NULL; |
---|
3071 | 3086 | /* Unless we are doing a full sync, or a replacement |
---|
3072 | 3087 | * we only need to recover the block if it is set in |
---|
3073 | 3088 | * the bitmap |
---|
.. | .. |
---|
3190 | 3205 | bio = r10_bio->devs[1].repl_bio; |
---|
3191 | 3206 | if (bio) |
---|
3192 | 3207 | bio->bi_end_io = NULL; |
---|
3193 | | - /* Note: if need_replace, then bio |
---|
| 3208 | + /* Note: if replace is not NULL, then bio |
---|
3194 | 3209 | * cannot be NULL as r10buf_pool_alloc will |
---|
3195 | 3210 | * have allocated it. |
---|
3196 | 3211 | */ |
---|
3197 | | - if (!need_replace) |
---|
| 3212 | + if (!mreplace) |
---|
3198 | 3213 | break; |
---|
3199 | 3214 | bio->bi_next = biolist; |
---|
3200 | 3215 | biolist = bio; |
---|
.. | .. |
---|
3615 | 3630 | return nc*fc; |
---|
3616 | 3631 | } |
---|
3617 | 3632 | |
---|
| 3633 | +static void raid10_free_conf(struct r10conf *conf) |
---|
| 3634 | +{ |
---|
| 3635 | + if (!conf) |
---|
| 3636 | + return; |
---|
| 3637 | + |
---|
| 3638 | + mempool_exit(&conf->r10bio_pool); |
---|
| 3639 | + kfree(conf->mirrors); |
---|
| 3640 | + kfree(conf->mirrors_old); |
---|
| 3641 | + kfree(conf->mirrors_new); |
---|
| 3642 | + safe_put_page(conf->tmppage); |
---|
| 3643 | + bioset_exit(&conf->bio_split); |
---|
| 3644 | + kfree(conf); |
---|
| 3645 | +} |
---|
| 3646 | + |
---|
3618 | 3647 | static struct r10conf *setup_conf(struct mddev *mddev) |
---|
3619 | 3648 | { |
---|
3620 | 3649 | struct r10conf *conf = NULL; |
---|
.. | .. |
---|
3697 | 3726 | return conf; |
---|
3698 | 3727 | |
---|
3699 | 3728 | out: |
---|
3700 | | - if (conf) { |
---|
3701 | | - mempool_exit(&conf->r10bio_pool); |
---|
3702 | | - kfree(conf->mirrors); |
---|
3703 | | - safe_put_page(conf->tmppage); |
---|
3704 | | - bioset_exit(&conf->bio_split); |
---|
3705 | | - kfree(conf); |
---|
3706 | | - } |
---|
| 3729 | + raid10_free_conf(conf); |
---|
3707 | 3730 | return ERR_PTR(err); |
---|
3708 | 3731 | } |
---|
3709 | 3732 | |
---|
.. | .. |
---|
3741 | 3764 | if (!conf) |
---|
3742 | 3765 | goto out; |
---|
3743 | 3766 | |
---|
| 3767 | + mddev->thread = conf->thread; |
---|
| 3768 | + conf->thread = NULL; |
---|
| 3769 | + |
---|
3744 | 3770 | if (mddev_is_clustered(conf->mddev)) { |
---|
3745 | 3771 | int fc, fo; |
---|
3746 | 3772 | |
---|
.. | .. |
---|
3752 | 3778 | goto out_free_conf; |
---|
3753 | 3779 | } |
---|
3754 | 3780 | } |
---|
3755 | | - |
---|
3756 | | - mddev->thread = conf->thread; |
---|
3757 | | - conf->thread = NULL; |
---|
3758 | 3781 | |
---|
3759 | 3782 | if (mddev->queue) { |
---|
3760 | 3783 | blk_queue_max_discard_sectors(mddev->queue, |
---|
.. | .. |
---|
3909 | 3932 | |
---|
3910 | 3933 | out_free_conf: |
---|
3911 | 3934 | md_unregister_thread(&mddev->thread); |
---|
3912 | | - mempool_exit(&conf->r10bio_pool); |
---|
3913 | | - safe_put_page(conf->tmppage); |
---|
3914 | | - kfree(conf->mirrors); |
---|
3915 | | - kfree(conf); |
---|
| 3935 | + raid10_free_conf(conf); |
---|
3916 | 3936 | mddev->private = NULL; |
---|
3917 | 3937 | out: |
---|
3918 | 3938 | return -EIO; |
---|
.. | .. |
---|
3920 | 3940 | |
---|
3921 | 3941 | static void raid10_free(struct mddev *mddev, void *priv) |
---|
3922 | 3942 | { |
---|
3923 | | - struct r10conf *conf = priv; |
---|
3924 | | - |
---|
3925 | | - mempool_exit(&conf->r10bio_pool); |
---|
3926 | | - safe_put_page(conf->tmppage); |
---|
3927 | | - kfree(conf->mirrors); |
---|
3928 | | - kfree(conf->mirrors_old); |
---|
3929 | | - kfree(conf->mirrors_new); |
---|
3930 | | - bioset_exit(&conf->bio_split); |
---|
3931 | | - kfree(conf); |
---|
| 3943 | + raid10_free_conf(priv); |
---|
3932 | 3944 | } |
---|
3933 | 3945 | |
---|
3934 | 3946 | static void raid10_quiesce(struct mddev *mddev, int quiesce) |
---|