Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'md/4.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md

Pull MD fixes from Shaohua Li:
"A few fixes for MD. Mainly fix a problem introduced in 4.13, which we
retry bio for some code paths but not all in some situations"

* tag 'md/4.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md:
md/raid5: cap worker count
dm-raid: fix a race condition in request handling
md: fix a race condition for flush request handling
md: separate request handling

+50 -32
+1 -1
drivers/md/dm-raid.c
··· 3238 3238 if (unlikely(bio_end_sector(bio) > mddev->array_sectors)) 3239 3239 return DM_MAPIO_REQUEUE; 3240 3240 3241 - mddev->pers->make_request(mddev, bio); 3241 + md_handle_request(mddev, bio); 3242 3242 3243 3243 return DM_MAPIO_SUBMITTED; 3244 3244 }
+43 -29
drivers/md/md.c
··· 266 266 * call has finished, the bio has been linked into some internal structure 267 267 * and so is visible to ->quiesce(), so we don't need the refcount any more. 268 268 */ 269 + void md_handle_request(struct mddev *mddev, struct bio *bio) 270 + { 271 + check_suspended: 272 + rcu_read_lock(); 273 + if (mddev->suspended) { 274 + DEFINE_WAIT(__wait); 275 + for (;;) { 276 + prepare_to_wait(&mddev->sb_wait, &__wait, 277 + TASK_UNINTERRUPTIBLE); 278 + if (!mddev->suspended) 279 + break; 280 + rcu_read_unlock(); 281 + schedule(); 282 + rcu_read_lock(); 283 + } 284 + finish_wait(&mddev->sb_wait, &__wait); 285 + } 286 + atomic_inc(&mddev->active_io); 287 + rcu_read_unlock(); 288 + 289 + if (!mddev->pers->make_request(mddev, bio)) { 290 + atomic_dec(&mddev->active_io); 291 + wake_up(&mddev->sb_wait); 292 + goto check_suspended; 293 + } 294 + 295 + if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) 296 + wake_up(&mddev->sb_wait); 297 + } 298 + EXPORT_SYMBOL(md_handle_request); 299 + 269 300 static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) 270 301 { 271 302 const int rw = bio_data_dir(bio); ··· 316 285 bio_endio(bio); 317 286 return BLK_QC_T_NONE; 318 287 } 319 - check_suspended: 320 - rcu_read_lock(); 321 - if (mddev->suspended) { 322 - DEFINE_WAIT(__wait); 323 - for (;;) { 324 - prepare_to_wait(&mddev->sb_wait, &__wait, 325 - TASK_UNINTERRUPTIBLE); 326 - if (!mddev->suspended) 327 - break; 328 - rcu_read_unlock(); 329 - schedule(); 330 - rcu_read_lock(); 331 - } 332 - finish_wait(&mddev->sb_wait, &__wait); 333 - } 334 - atomic_inc(&mddev->active_io); 335 - rcu_read_unlock(); 336 288 337 289 /* 338 290 * save the sectors now since our bio can ··· 324 310 sectors = bio_sectors(bio); 325 311 /* bio could be mergeable after passing to underlayer */ 326 312 bio->bi_opf &= ~REQ_NOMERGE; 327 - if (!mddev->pers->make_request(mddev, bio)) { 328 - atomic_dec(&mddev->active_io); 329 - wake_up(&mddev->sb_wait); 330 - goto check_suspended; 331 - } 313 + 314 + md_handle_request(mddev, bio); 332 315 333 316 cpu = part_stat_lock(); 334 317 part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); 335 318 part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors); 336 319 part_stat_unlock(); 337 - 338 - if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) 339 - wake_up(&mddev->sb_wait); 340 320 341 321 return BLK_QC_T_NONE; 342 322 } ··· 447 439 struct mddev *mddev = container_of(ws, struct mddev, flush_work); 448 440 struct bio *bio = mddev->flush_bio; 449 441 442 + /* 443 + * must reset flush_bio before calling into md_handle_request to avoid a 444 + * deadlock, because other bios passed md_handle_request suspend check 445 + * could wait for this and below md_handle_request could wait for those 446 + * bios because of suspend check 447 + */ 448 + mddev->flush_bio = NULL; 449 + wake_up(&mddev->sb_wait); 450 + 450 451 if (bio->bi_iter.bi_size == 0) 451 452 /* an empty barrier - all done */ 452 453 bio_endio(bio); 453 454 else { 454 455 bio->bi_opf &= ~REQ_PREFLUSH; 455 - mddev->pers->make_request(mddev, bio); 456 + md_handle_request(mddev, bio); 456 457 } 457 - 458 - mddev->flush_bio = NULL; 459 - wake_up(&mddev->sb_wait); 460 458 } 461 459 462 460 void md_flush_request(struct mddev *mddev, struct bio *bio)
+1
drivers/md/md.h
··· 692 692 extern int md_rdev_init(struct md_rdev *rdev); 693 693 extern void md_rdev_clear(struct md_rdev *rdev); 694 694 695 + extern void md_handle_request(struct mddev *mddev, struct bio *bio); 695 696 extern void mddev_suspend(struct mddev *mddev); 696 697 extern void mddev_resume(struct mddev *mddev); 697 698 extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
+5 -2
drivers/md/raid5.c
··· 6575 6575 raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len) 6576 6576 { 6577 6577 struct r5conf *conf; 6578 - unsigned long new; 6578 + unsigned int new; 6579 6579 int err; 6580 6580 struct r5worker_group *new_groups, *old_groups; 6581 6581 int group_cnt, worker_cnt_per_group; 6582 6582 6583 6583 if (len >= PAGE_SIZE) 6584 6584 return -EINVAL; 6585 - if (kstrtoul(page, 10, &new)) 6585 + if (kstrtouint(page, 10, &new)) 6586 + return -EINVAL; 6587 + /* 8192 should be big enough */ 6588 + if (new > 8192) 6586 6589 return -EINVAL; 6587 6590 6588 6591 err = mddev_lock(mddev);