Use the hold framework in do_failures. This patch doesn't change any logic in processing bios, it just simplifies failure handling and avoids periodically polling the failures list. Signed-off-by: Mikulas Patocka --- drivers/md/dm-raid1.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) Index: linux-2.6.31-rc3-devel/drivers/md/dm-raid1.c =================================================================== --- linux-2.6.31-rc3-devel.orig/drivers/md/dm-raid1.c 2009-07-20 20:16:18.000000000 +0200 +++ linux-2.6.31-rc3-devel/drivers/md/dm-raid1.c 2009-07-20 20:17:55.000000000 +0200 @@ -690,20 +690,12 @@ static void do_failures(struct mirror_se { struct bio *bio; - if (!failures->head) + if (likely(!failures->head)) return; - if (!ms->log_failure) { - while ((bio = bio_list_pop(failures))) { - ms->in_sync = 0; - dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); - } - return; - } - /* * If the log has failed, unattempted writes are being - * put on the failures list. We can't issue those writes + * put on the hold list. We can't issue those writes * until a log has been marked, so we must store them. * * If a 'noflush' suspend is in progress, we can requeue @@ -718,23 +710,15 @@ static void do_failures(struct mirror_se * for us to treat them the same and requeue them * as well. */ - if (dm_noflush_suspending(ms->ti)) { - while ((bio = bio_list_pop(failures))) - bio_endio(bio, DM_ENDIO_REQUEUE); - return; - } - if (atomic_read(&ms->suspend)) { - while ((bio = bio_list_pop(failures))) - bio_endio(bio, -EIO); - return; + while ((bio = bio_list_pop(failures))) { + if (!ms->log_failure) { + ms->in_sync = 0; + dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); + } else { + hold_bio(ms, bio); + } } - - spin_lock_irq(&ms->lock); - bio_list_merge(&ms->failures, failures); - spin_unlock_irq(&ms->lock); - - delayed_wake(ms); } static void trigger_event(struct work_struct *work)