diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 45 | ||||
-rw-r--r-- | drivers/md/raid1.c | 4 | ||||
-rw-r--r-- | drivers/md/raid10.c | 3 | ||||
-rw-r--r-- | drivers/md/raid5.c | 3 | ||||
-rw-r--r-- | drivers/md/raid6main.c | 3 |
5 files changed, 21 insertions, 37 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 789b114f860a..7075bebb7f37 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -224,8 +224,8 @@ static mddev_t * mddev_find(dev_t unit) | |||
224 | INIT_LIST_HEAD(&new->all_mddevs); | 224 | INIT_LIST_HEAD(&new->all_mddevs); |
225 | init_timer(&new->safemode_timer); | 225 | init_timer(&new->safemode_timer); |
226 | atomic_set(&new->active, 1); | 226 | atomic_set(&new->active, 1); |
227 | bio_list_init(&new->write_list); | ||
228 | spin_lock_init(&new->write_lock); | 227 | spin_lock_init(&new->write_lock); |
228 | init_waitqueue_head(&new->sb_wait); | ||
229 | 229 | ||
230 | new->queue = blk_alloc_queue(GFP_KERNEL); | 230 | new->queue = blk_alloc_queue(GFP_KERNEL); |
231 | if (!new->queue) { | 231 | if (!new->queue) { |
@@ -1307,6 +1307,7 @@ repeat: | |||
1307 | if (!mddev->persistent) { | 1307 | if (!mddev->persistent) { |
1308 | mddev->sb_dirty = 0; | 1308 | mddev->sb_dirty = 0; |
1309 | spin_unlock(&mddev->write_lock); | 1309 | spin_unlock(&mddev->write_lock); |
1310 | wake_up(&mddev->sb_wait); | ||
1310 | return; | 1311 | return; |
1311 | } | 1312 | } |
1312 | spin_unlock(&mddev->write_lock); | 1313 | spin_unlock(&mddev->write_lock); |
@@ -1348,6 +1349,7 @@ repeat: | |||
1348 | } | 1349 | } |
1349 | mddev->sb_dirty = 0; | 1350 | mddev->sb_dirty = 0; |
1350 | spin_unlock(&mddev->write_lock); | 1351 | spin_unlock(&mddev->write_lock); |
1352 | wake_up(&mddev->sb_wait); | ||
1351 | 1353 | ||
1352 | } | 1354 | } |
1353 | 1355 | ||
@@ -3368,29 +3370,26 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) | |||
3368 | 3370 | ||
3369 | /* md_write_start(mddev, bi) | 3371 | /* md_write_start(mddev, bi) |
3370 | * If we need to update some array metadata (e.g. 'active' flag | 3372 | * If we need to update some array metadata (e.g. 'active' flag |
3371 | * in superblock) before writing, queue bi for later writing | 3373 | * in superblock) before writing, schedule a superblock update |
3372 | * and return 0, else return 1 and it will be written now | 3374 | * and wait for it to complete. |
3373 | */ | 3375 | */ |
3374 | int md_write_start(mddev_t *mddev, struct bio *bi) | 3376 | void md_write_start(mddev_t *mddev, struct bio *bi) |
3375 | { | 3377 | { |
3378 | DEFINE_WAIT(w); | ||
3376 | if (bio_data_dir(bi) != WRITE) | 3379 | if (bio_data_dir(bi) != WRITE) |
3377 | return 1; | 3380 | return; |
3378 | 3381 | ||
3379 | atomic_inc(&mddev->writes_pending); | 3382 | atomic_inc(&mddev->writes_pending); |
3380 | spin_lock(&mddev->write_lock); | ||
3381 | if (mddev->in_sync == 0 && mddev->sb_dirty == 0) { | ||
3382 | spin_unlock(&mddev->write_lock); | ||
3383 | return 1; | ||
3384 | } | ||
3385 | bio_list_add(&mddev->write_list, bi); | ||
3386 | |||
3387 | if (mddev->in_sync) { | 3383 | if (mddev->in_sync) { |
3388 | mddev->in_sync = 0; | 3384 | spin_lock(&mddev->write_lock); |
3389 | mddev->sb_dirty = 1; | 3385 | if (mddev->in_sync) { |
3386 | mddev->in_sync = 0; | ||
3387 | mddev->sb_dirty = 1; | ||
3388 | md_wakeup_thread(mddev->thread); | ||
3389 | } | ||
3390 | spin_unlock(&mddev->write_lock); | ||
3390 | } | 3391 | } |
3391 | spin_unlock(&mddev->write_lock); | 3392 | wait_event(mddev->sb_wait, mddev->sb_dirty==0); |
3392 | md_wakeup_thread(mddev->thread); | ||
3393 | return 0; | ||
3394 | } | 3393 | } |
3395 | 3394 | ||
3396 | void md_write_end(mddev_t *mddev) | 3395 | void md_write_end(mddev_t *mddev) |
@@ -3685,7 +3684,6 @@ void md_check_recovery(mddev_t *mddev) | |||
3685 | mddev->sb_dirty || | 3684 | mddev->sb_dirty || |
3686 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || | 3685 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || |
3687 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || | 3686 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || |
3688 | mddev->write_list.head || | ||
3689 | (mddev->safemode == 1) || | 3687 | (mddev->safemode == 1) || |
3690 | (mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending) | 3688 | (mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending) |
3691 | && !mddev->in_sync && mddev->recovery_cp == MaxSector) | 3689 | && !mddev->in_sync && mddev->recovery_cp == MaxSector) |
@@ -3694,7 +3692,6 @@ void md_check_recovery(mddev_t *mddev) | |||
3694 | 3692 | ||
3695 | if (mddev_trylock(mddev)==0) { | 3693 | if (mddev_trylock(mddev)==0) { |
3696 | int spares =0; | 3694 | int spares =0; |
3697 | struct bio *blist; | ||
3698 | 3695 | ||
3699 | spin_lock(&mddev->write_lock); | 3696 | spin_lock(&mddev->write_lock); |
3700 | if (mddev->safemode && !atomic_read(&mddev->writes_pending) && | 3697 | if (mddev->safemode && !atomic_read(&mddev->writes_pending) && |
@@ -3704,21 +3701,11 @@ void md_check_recovery(mddev_t *mddev) | |||
3704 | } | 3701 | } |
3705 | if (mddev->safemode == 1) | 3702 | if (mddev->safemode == 1) |
3706 | mddev->safemode = 0; | 3703 | mddev->safemode = 0; |
3707 | blist = bio_list_get(&mddev->write_list); | ||
3708 | spin_unlock(&mddev->write_lock); | 3704 | spin_unlock(&mddev->write_lock); |
3709 | 3705 | ||
3710 | if (mddev->sb_dirty) | 3706 | if (mddev->sb_dirty) |
3711 | md_update_sb(mddev); | 3707 | md_update_sb(mddev); |
3712 | 3708 | ||
3713 | while (blist) { | ||
3714 | struct bio *b = blist; | ||
3715 | blist = blist->bi_next; | ||
3716 | b->bi_next = NULL; | ||
3717 | generic_make_request(b); | ||
3718 | /* we already counted this, so need to un-count */ | ||
3719 | md_write_end(mddev); | ||
3720 | } | ||
3721 | |||
3722 | 3709 | ||
3723 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && | 3710 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
3724 | !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { | 3711 | !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3f5234fe3593..98b09773e79e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -561,8 +561,8 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
561 | * thread has put up a bar for new requests. | 561 | * thread has put up a bar for new requests. |
562 | * Continue immediately if no resync is active currently. | 562 | * Continue immediately if no resync is active currently. |
563 | */ | 563 | */ |
564 | if (md_write_start(mddev, bio)==0) | 564 | md_write_start(mddev, bio); /* wait on superblock update early */ |
565 | return 0; | 565 | |
566 | spin_lock_irq(&conf->resync_lock); | 566 | spin_lock_irq(&conf->resync_lock); |
567 | wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, ); | 567 | wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, ); |
568 | conf->nr_pending++; | 568 | conf->nr_pending++; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8476515bfdc7..fd7324a86d13 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -700,8 +700,7 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
700 | return 0; | 700 | return 0; |
701 | } | 701 | } |
702 | 702 | ||
703 | if (md_write_start(mddev, bio) == 0) | 703 | md_write_start(mddev, bio); |
704 | return 0; | ||
705 | 704 | ||
706 | /* | 705 | /* |
707 | * Register the new request and wait if the reconstruction | 706 | * Register the new request and wait if the reconstruction |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 1ce3f5aaa984..93a9726cc2d6 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1411,8 +1411,7 @@ static int make_request (request_queue_t *q, struct bio * bi) | |||
1411 | sector_t logical_sector, last_sector; | 1411 | sector_t logical_sector, last_sector; |
1412 | struct stripe_head *sh; | 1412 | struct stripe_head *sh; |
1413 | 1413 | ||
1414 | if (md_write_start(mddev, bi)==0) | 1414 | md_write_start(mddev, bi); |
1415 | return 0; | ||
1416 | 1415 | ||
1417 | if (bio_data_dir(bi)==WRITE) { | 1416 | if (bio_data_dir(bi)==WRITE) { |
1418 | disk_stat_inc(mddev->gendisk, writes); | 1417 | disk_stat_inc(mddev->gendisk, writes); |
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index d9c385496dc5..f62ea1a73d0d 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -1570,8 +1570,7 @@ static int make_request (request_queue_t *q, struct bio * bi) | |||
1570 | sector_t logical_sector, last_sector; | 1570 | sector_t logical_sector, last_sector; |
1571 | struct stripe_head *sh; | 1571 | struct stripe_head *sh; |
1572 | 1572 | ||
1573 | if (md_write_start(mddev, bi)==0) | 1573 | md_write_start(mddev, bi); |
1574 | return 0; | ||
1575 | 1574 | ||
1576 | if (bio_data_dir(bi)==WRITE) { | 1575 | if (bio_data_dir(bi)==WRITE) { |
1577 | disk_stat_inc(mddev->gendisk, writes); | 1576 | disk_stat_inc(mddev->gendisk, writes); |