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; |