From: NeilBrown Date: Tue, 3 Jul 2012 02:13:29 +0000 (+1000) Subject: md/raid5: fix refcount problem when blocked_rdev is set. X-Git-Tag: v3.5-rc7~8^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5f066c632fcfd2a33f2eb7077c15c630e9f5ea5b;p=profile%2Fivi%2Fkernel-x86-ivi.git md/raid5: fix refcount problem when blocked_rdev is set. commit 43220aa0f22cd3ce5b30246d50ccd696d119edea md/raid5: fix a hang on device failure. fixed a hang, but introduced a refcounting in-balance so that if the presence of bad-blocks ever caused an rdev to be 'blocked' we would increment the refcount on the rdev and never decrement it. So added the needed rdev_dec_pending when md_wait_for_blocked_rdev is not called. Reported-by: majianpeng Signed-off-by: NeilBrown --- diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index befadb4..62b6b3a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3588,8 +3588,18 @@ static void handle_stripe(struct stripe_head *sh) finish: /* wait for this device to become unblocked */ - if (conf->mddev->external && unlikely(s.blocked_rdev)) - md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); + if (unlikely(s.blocked_rdev)) { + if (conf->mddev->external) + md_wait_for_blocked_rdev(s.blocked_rdev, + conf->mddev); + else + /* Internal metadata will immediately + * be written by raid5d, so we don't + * need to wait here. + */ + rdev_dec_pending(s.blocked_rdev, + conf->mddev); + } if (s.handle_bad_blocks) for (i = disks; i--; ) {