| .. | .. |
|---|
| 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) |
|---|