From: Shaohua Li Date: Tue, 3 Jul 2012 05:57:19 +0000 (+1000) Subject: raid5: delayed stripe fix X-Git-Tag: v2.6.39-400.9.0~303^2~40 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=35e47bbad85ba92bd54f2eaea2c10eee9cdafe67;p=users%2Fjedix%2Flinux-maple.git raid5: delayed stripe fix commit fab363b5ff502d1b39ddcfec04271f5858d9f26e upstream. There isn't locking setting STRIPE_DELAYED and STRIPE_PREREAD_ACTIVE bits, but the two bits have relationship. A delayed stripe can be moved to hold list only when preread active stripe count is below IO_THRESHOLD. If a stripe has both the bits set, such stripe will be in delayed list and preread count not 0, which will make such stripe never leave delayed list. Signed-off-by: Shaohua Li Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman Signed-off-by: Guangyu Sun --- diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 1f6c68df6f38..d0c8a1e1633a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -199,12 +199,14 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) BUG_ON(!list_empty(&sh->lru)); BUG_ON(atomic_read(&conf->active_stripes)==0); if (test_bit(STRIPE_HANDLE, &sh->state)) { - if (test_bit(STRIPE_DELAYED, &sh->state)) + if (test_bit(STRIPE_DELAYED, &sh->state) && + !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && sh->bm_seq - conf->seq_write > 0) list_add_tail(&sh->lru, &conf->bitmap_list); else { + clear_bit(STRIPE_DELAYED, &sh->state); clear_bit(STRIPE_BIT_DELAY, &sh->state); list_add_tail(&sh->lru, &conf->handle_list); }