diff options
Diffstat (limited to 'drivers/md/md.c')
| -rw-r--r-- | drivers/md/md.c | 117 |
1 files changed, 25 insertions, 92 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index dbf822df942a..225815197a3d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -227,12 +227,12 @@ static int md_make_request(struct request_queue *q, struct bio *bio) | |||
| 227 | return 0; | 227 | return 0; |
| 228 | } | 228 | } |
| 229 | rcu_read_lock(); | 229 | rcu_read_lock(); |
| 230 | if (mddev->suspended || mddev->barrier) { | 230 | if (mddev->suspended) { |
| 231 | DEFINE_WAIT(__wait); | 231 | DEFINE_WAIT(__wait); |
| 232 | for (;;) { | 232 | for (;;) { |
| 233 | prepare_to_wait(&mddev->sb_wait, &__wait, | 233 | prepare_to_wait(&mddev->sb_wait, &__wait, |
| 234 | TASK_UNINTERRUPTIBLE); | 234 | TASK_UNINTERRUPTIBLE); |
| 235 | if (!mddev->suspended && !mddev->barrier) | 235 | if (!mddev->suspended) |
| 236 | break; | 236 | break; |
| 237 | rcu_read_unlock(); | 237 | rcu_read_unlock(); |
| 238 | schedule(); | 238 | schedule(); |
| @@ -283,40 +283,29 @@ EXPORT_SYMBOL_GPL(mddev_resume); | |||
| 283 | 283 | ||
| 284 | int mddev_congested(mddev_t *mddev, int bits) | 284 | int mddev_congested(mddev_t *mddev, int bits) |
| 285 | { | 285 | { |
| 286 | if (mddev->barrier) | ||
| 287 | return 1; | ||
| 288 | return mddev->suspended; | 286 | return mddev->suspended; |
| 289 | } | 287 | } |
| 290 | EXPORT_SYMBOL(mddev_congested); | 288 | EXPORT_SYMBOL(mddev_congested); |
| 291 | 289 | ||
| 292 | /* | 290 | /* |
| 293 | * Generic barrier handling for md | 291 | * Generic flush handling for md |
| 294 | */ | 292 | */ |
| 295 | 293 | ||
| 296 | #define POST_REQUEST_BARRIER ((void*)1) | 294 | static void md_end_flush(struct bio *bio, int err) |
| 297 | |||
| 298 | static void md_end_barrier(struct bio *bio, int err) | ||
| 299 | { | 295 | { |
| 300 | mdk_rdev_t *rdev = bio->bi_private; | 296 | mdk_rdev_t *rdev = bio->bi_private; |
| 301 | mddev_t *mddev = rdev->mddev; | 297 | mddev_t *mddev = rdev->mddev; |
| 302 | if (err == -EOPNOTSUPP && mddev->barrier != POST_REQUEST_BARRIER) | ||
| 303 | set_bit(BIO_EOPNOTSUPP, &mddev->barrier->bi_flags); | ||
| 304 | 298 | ||
| 305 | rdev_dec_pending(rdev, mddev); | 299 | rdev_dec_pending(rdev, mddev); |
| 306 | 300 | ||
| 307 | if (atomic_dec_and_test(&mddev->flush_pending)) { | 301 | if (atomic_dec_and_test(&mddev->flush_pending)) { |
| 308 | if (mddev->barrier == POST_REQUEST_BARRIER) { | 302 | /* The pre-request flush has finished */ |
| 309 | /* This was a post-request barrier */ | 303 | schedule_work(&mddev->flush_work); |
| 310 | mddev->barrier = NULL; | ||
| 311 | wake_up(&mddev->sb_wait); | ||
| 312 | } else | ||
| 313 | /* The pre-request barrier has finished */ | ||
| 314 | schedule_work(&mddev->barrier_work); | ||
| 315 | } | 304 | } |
| 316 | bio_put(bio); | 305 | bio_put(bio); |
| 317 | } | 306 | } |
| 318 | 307 | ||
| 319 | static void submit_barriers(mddev_t *mddev) | 308 | static void submit_flushes(mddev_t *mddev) |
| 320 | { | 309 | { |
| 321 | mdk_rdev_t *rdev; | 310 | mdk_rdev_t *rdev; |
| 322 | 311 | ||
| @@ -333,60 +322,56 @@ static void submit_barriers(mddev_t *mddev) | |||
| 333 | atomic_inc(&rdev->nr_pending); | 322 | atomic_inc(&rdev->nr_pending); |
| 334 | rcu_read_unlock(); | 323 | rcu_read_unlock(); |
| 335 | bi = bio_alloc(GFP_KERNEL, 0); | 324 | bi = bio_alloc(GFP_KERNEL, 0); |
| 336 | bi->bi_end_io = md_end_barrier; | 325 | bi->bi_end_io = md_end_flush; |
| 337 | bi->bi_private = rdev; | 326 | bi->bi_private = rdev; |
| 338 | bi->bi_bdev = rdev->bdev; | 327 | bi->bi_bdev = rdev->bdev; |
| 339 | atomic_inc(&mddev->flush_pending); | 328 | atomic_inc(&mddev->flush_pending); |
| 340 | submit_bio(WRITE_BARRIER, bi); | 329 | submit_bio(WRITE_FLUSH, bi); |
| 341 | rcu_read_lock(); | 330 | rcu_read_lock(); |
| 342 | rdev_dec_pending(rdev, mddev); | 331 | rdev_dec_pending(rdev, mddev); |
| 343 | } | 332 | } |
| 344 | rcu_read_unlock(); | 333 | rcu_read_unlock(); |
| 345 | } | 334 | } |
| 346 | 335 | ||
| 347 | static void md_submit_barrier(struct work_struct *ws) | 336 | static void md_submit_flush_data(struct work_struct *ws) |
| 348 | { | 337 | { |
| 349 | mddev_t *mddev = container_of(ws, mddev_t, barrier_work); | 338 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); |
| 350 | struct bio *bio = mddev->barrier; | 339 | struct bio *bio = mddev->flush_bio; |
| 351 | 340 | ||
| 352 | atomic_set(&mddev->flush_pending, 1); | 341 | atomic_set(&mddev->flush_pending, 1); |
| 353 | 342 | ||
| 354 | if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags)) | 343 | if (bio->bi_size == 0) |
| 355 | bio_endio(bio, -EOPNOTSUPP); | ||
| 356 | else if (bio->bi_size == 0) | ||
| 357 | /* an empty barrier - all done */ | 344 | /* an empty barrier - all done */ |
| 358 | bio_endio(bio, 0); | 345 | bio_endio(bio, 0); |
| 359 | else { | 346 | else { |
| 360 | bio->bi_rw &= ~REQ_HARDBARRIER; | 347 | bio->bi_rw &= ~REQ_FLUSH; |
| 361 | if (mddev->pers->make_request(mddev, bio)) | 348 | if (mddev->pers->make_request(mddev, bio)) |
| 362 | generic_make_request(bio); | 349 | generic_make_request(bio); |
| 363 | mddev->barrier = POST_REQUEST_BARRIER; | ||
| 364 | submit_barriers(mddev); | ||
| 365 | } | 350 | } |
| 366 | if (atomic_dec_and_test(&mddev->flush_pending)) { | 351 | if (atomic_dec_and_test(&mddev->flush_pending)) { |
| 367 | mddev->barrier = NULL; | 352 | mddev->flush_bio = NULL; |
| 368 | wake_up(&mddev->sb_wait); | 353 | wake_up(&mddev->sb_wait); |
| 369 | } | 354 | } |
| 370 | } | 355 | } |
| 371 | 356 | ||
| 372 | void md_barrier_request(mddev_t *mddev, struct bio *bio) | 357 | void md_flush_request(mddev_t *mddev, struct bio *bio) |
| 373 | { | 358 | { |
| 374 | spin_lock_irq(&mddev->write_lock); | 359 | spin_lock_irq(&mddev->write_lock); |
| 375 | wait_event_lock_irq(mddev->sb_wait, | 360 | wait_event_lock_irq(mddev->sb_wait, |
| 376 | !mddev->barrier, | 361 | !mddev->flush_bio, |
| 377 | mddev->write_lock, /*nothing*/); | 362 | mddev->write_lock, /*nothing*/); |
| 378 | mddev->barrier = bio; | 363 | mddev->flush_bio = bio; |
| 379 | spin_unlock_irq(&mddev->write_lock); | 364 | spin_unlock_irq(&mddev->write_lock); |
| 380 | 365 | ||
| 381 | atomic_set(&mddev->flush_pending, 1); | 366 | atomic_set(&mddev->flush_pending, 1); |
| 382 | INIT_WORK(&mddev->barrier_work, md_submit_barrier); | 367 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); |
| 383 | 368 | ||
| 384 | submit_barriers(mddev); | 369 | submit_flushes(mddev); |
| 385 | 370 | ||
| 386 | if (atomic_dec_and_test(&mddev->flush_pending)) | 371 | if (atomic_dec_and_test(&mddev->flush_pending)) |
| 387 | schedule_work(&mddev->barrier_work); | 372 | schedule_work(&mddev->flush_work); |
| 388 | } | 373 | } |
| 389 | EXPORT_SYMBOL(md_barrier_request); | 374 | EXPORT_SYMBOL(md_flush_request); |
| 390 | 375 | ||
| 391 | /* Support for plugging. | 376 | /* Support for plugging. |
| 392 | * This mirrors the plugging support in request_queue, but does not | 377 | * This mirrors the plugging support in request_queue, but does not |
| @@ -697,31 +682,6 @@ static void super_written(struct bio *bio, int error) | |||
| 697 | bio_put(bio); | 682 | bio_put(bio); |
| 698 | } | 683 | } |
| 699 | 684 | ||
| 700 | static void super_written_barrier(struct bio *bio, int error) | ||
| 701 | { | ||
| 702 | struct bio *bio2 = bio->bi_private; | ||
| 703 | mdk_rdev_t *rdev = bio2->bi_private; | ||
| 704 | mddev_t *mddev = rdev->mddev; | ||
| 705 | |||
| 706 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags) && | ||
| 707 | error == -EOPNOTSUPP) { | ||
| 708 | unsigned long flags; | ||
| 709 | /* barriers don't appear to be supported :-( */ | ||
| 710 | set_bit(BarriersNotsupp, &rdev->flags); | ||
| 711 | mddev->barriers_work = 0; | ||
| 712 | spin_lock_irqsave(&mddev->write_lock, flags); | ||
| 713 | bio2->bi_next = mddev->biolist; | ||
| 714 | mddev->biolist = bio2; | ||
| 715 | spin_unlock_irqrestore(&mddev->write_lock, flags); | ||
| 716 | wake_up(&mddev->sb_wait); | ||
| 717 | bio_put(bio); | ||
| 718 | } else { | ||
| 719 | bio_put(bio2); | ||
| 720 | bio->bi_private = rdev; | ||
| 721 | super_written(bio, error); | ||
| 722 | } | ||
| 723 | } | ||
| 724 | |||
| 725 | void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | 685 | void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, |
| 726 | sector_t sector, int size, struct page *page) | 686 | sector_t sector, int size, struct page *page) |
| 727 | { | 687 | { |
| @@ -730,51 +690,28 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | |||
| 730 | * and decrement it on completion, waking up sb_wait | 690 | * and decrement it on completion, waking up sb_wait |
| 731 | * if zero is reached. | 691 | * if zero is reached. |
| 732 | * If an error occurred, call md_error | 692 | * If an error occurred, call md_error |
| 733 | * | ||
| 734 | * As we might need to resubmit the request if REQ_HARDBARRIER | ||
| 735 | * causes ENOTSUPP, we allocate a spare bio... | ||
| 736 | */ | 693 | */ |
| 737 | struct bio *bio = bio_alloc(GFP_NOIO, 1); | 694 | struct bio *bio = bio_alloc(GFP_NOIO, 1); |
| 738 | int rw = REQ_WRITE | REQ_SYNC | REQ_UNPLUG; | ||
| 739 | 695 | ||
| 740 | bio->bi_bdev = rdev->bdev; | 696 | bio->bi_bdev = rdev->bdev; |
| 741 | bio->bi_sector = sector; | 697 | bio->bi_sector = sector; |
| 742 | bio_add_page(bio, page, size, 0); | 698 | bio_add_page(bio, page, size, 0); |
| 743 | bio->bi_private = rdev; | 699 | bio->bi_private = rdev; |
| 744 | bio->bi_end_io = super_written; | 700 | bio->bi_end_io = super_written; |
| 745 | bio->bi_rw = rw; | ||
| 746 | 701 | ||
| 747 | atomic_inc(&mddev->pending_writes); | 702 | atomic_inc(&mddev->pending_writes); |
| 748 | if (!test_bit(BarriersNotsupp, &rdev->flags)) { | 703 | submit_bio(REQ_WRITE | REQ_SYNC | REQ_UNPLUG | REQ_FLUSH | REQ_FUA, |
| 749 | struct bio *rbio; | 704 | bio); |
| 750 | rw |= REQ_HARDBARRIER; | ||
| 751 | rbio = bio_clone(bio, GFP_NOIO); | ||
| 752 | rbio->bi_private = bio; | ||
| 753 | rbio->bi_end_io = super_written_barrier; | ||
| 754 | submit_bio(rw, rbio); | ||
| 755 | } else | ||
| 756 | submit_bio(rw, bio); | ||
| 757 | } | 705 | } |
| 758 | 706 | ||
| 759 | void md_super_wait(mddev_t *mddev) | 707 | void md_super_wait(mddev_t *mddev) |
| 760 | { | 708 | { |
| 761 | /* wait for all superblock writes that were scheduled to complete. | 709 | /* wait for all superblock writes that were scheduled to complete */ |
| 762 | * if any had to be retried (due to BARRIER problems), retry them | ||
| 763 | */ | ||
| 764 | DEFINE_WAIT(wq); | 710 | DEFINE_WAIT(wq); |
| 765 | for(;;) { | 711 | for(;;) { |
| 766 | prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE); | 712 | prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE); |
| 767 | if (atomic_read(&mddev->pending_writes)==0) | 713 | if (atomic_read(&mddev->pending_writes)==0) |
| 768 | break; | 714 | break; |
| 769 | while (mddev->biolist) { | ||
| 770 | struct bio *bio; | ||
| 771 | spin_lock_irq(&mddev->write_lock); | ||
| 772 | bio = mddev->biolist; | ||
| 773 | mddev->biolist = bio->bi_next ; | ||
| 774 | bio->bi_next = NULL; | ||
| 775 | spin_unlock_irq(&mddev->write_lock); | ||
| 776 | submit_bio(bio->bi_rw, bio); | ||
| 777 | } | ||
| 778 | schedule(); | 715 | schedule(); |
| 779 | } | 716 | } |
| 780 | finish_wait(&mddev->sb_wait, &wq); | 717 | finish_wait(&mddev->sb_wait, &wq); |
| @@ -1071,7 +1008,6 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1071 | clear_bit(Faulty, &rdev->flags); | 1008 | clear_bit(Faulty, &rdev->flags); |
| 1072 | clear_bit(In_sync, &rdev->flags); | 1009 | clear_bit(In_sync, &rdev->flags); |
| 1073 | clear_bit(WriteMostly, &rdev->flags); | 1010 | clear_bit(WriteMostly, &rdev->flags); |
| 1074 | clear_bit(BarriersNotsupp, &rdev->flags); | ||
| 1075 | 1011 | ||
| 1076 | if (mddev->raid_disks == 0) { | 1012 | if (mddev->raid_disks == 0) { |
| 1077 | mddev->major_version = 0; | 1013 | mddev->major_version = 0; |
| @@ -1486,7 +1422,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1486 | clear_bit(Faulty, &rdev->flags); | 1422 | clear_bit(Faulty, &rdev->flags); |
| 1487 | clear_bit(In_sync, &rdev->flags); | 1423 | clear_bit(In_sync, &rdev->flags); |
| 1488 | clear_bit(WriteMostly, &rdev->flags); | 1424 | clear_bit(WriteMostly, &rdev->flags); |
| 1489 | clear_bit(BarriersNotsupp, &rdev->flags); | ||
| 1490 | 1425 | ||
| 1491 | if (mddev->raid_disks == 0) { | 1426 | if (mddev->raid_disks == 0) { |
| 1492 | mddev->major_version = 1; | 1427 | mddev->major_version = 1; |
| @@ -4505,7 +4440,6 @@ int md_run(mddev_t *mddev) | |||
| 4505 | /* may be over-ridden by personality */ | 4440 | /* may be over-ridden by personality */ |
| 4506 | mddev->resync_max_sectors = mddev->dev_sectors; | 4441 | mddev->resync_max_sectors = mddev->dev_sectors; |
| 4507 | 4442 | ||
| 4508 | mddev->barriers_work = 1; | ||
| 4509 | mddev->ok_start_degraded = start_dirty_degraded; | 4443 | mddev->ok_start_degraded = start_dirty_degraded; |
| 4510 | 4444 | ||
| 4511 | if (start_readonly && mddev->ro == 0) | 4445 | if (start_readonly && mddev->ro == 0) |
| @@ -4684,7 +4618,6 @@ static void md_clean(mddev_t *mddev) | |||
| 4684 | mddev->recovery = 0; | 4618 | mddev->recovery = 0; |
| 4685 | mddev->in_sync = 0; | 4619 | mddev->in_sync = 0; |
| 4686 | mddev->degraded = 0; | 4620 | mddev->degraded = 0; |
| 4687 | mddev->barriers_work = 0; | ||
| 4688 | mddev->safemode = 0; | 4621 | mddev->safemode = 0; |
| 4689 | mddev->bitmap_info.offset = 0; | 4622 | mddev->bitmap_info.offset = 0; |
| 4690 | mddev->bitmap_info.default_offset = 0; | 4623 | mddev->bitmap_info.default_offset = 0; |
