linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] raid5: Avoid doing more read on dev of a stripe at the same time
@ 2012-09-15  2:20 Jianpeng Ma
  2012-09-20  2:51 ` NeilBrown
  0 siblings, 1 reply; 10+ messages in thread
From: Jianpeng Ma @ 2012-09-15  2:20 UTC (permalink / raw)
  To: Neil Brown; +Cc: linux-raid

In func 'ops_run_bio' if you read the dev which the last reading
of this dev didn't return,it will destrory the  req/rreq'source of rdev.
It may call hung-task.
For example, for badsector or other reasons, read-operation only used
stripe instead of chunk_aligned_read.
First:stripe 0;second: stripe 8;third:stripe 16.At the block-layer,three
bios merged.
Because media error of sector from 0 to 7, the request retried.
At this time, raid5d readed stripe0 again.But it will set 'bio->next =
NULL'.So the stripe 8 and 16 didn't return.

Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
---
 drivers/md/raid5.c |   13 ++++++++++---
 drivers/md/raid5.h |    1 +
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index adda94d..e52ba1b 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -547,9 +547,14 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
 				rw = WRITE_FUA;
 			else
 				rw = WRITE;
-		} else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
-			rw = READ;
-		else if (test_and_clear_bit(R5_WantReplace,
+		} else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags)) {
+			/*The last read did not return,so skip this read*/
+			if (test_and_set_bit(R5_Reading, &sh->dev[i].flags)) {
+				clear_bit(R5_LOCKED, &sh->dev[i].flags);
+				continue;
+			} else
+				rw = READ;
+		} else if (test_and_clear_bit(R5_WantReplace,
 					    &sh->dev[i].flags)) {
 			rw = WRITE;
 			replace_only = 1;
@@ -700,6 +705,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
 			pr_debug("skip op %ld on disc %d for sector %llu\n",
 				bi->bi_rw, i, (unsigned long long)sh->sector);
 			clear_bit(R5_LOCKED, &sh->dev[i].flags);
+			clear_bit(R5_Reading, &sh->dev[i].flags);
 			set_bit(STRIPE_HANDLE, &sh->state);
 		}
 	}
@@ -1818,6 +1824,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
 	}
 	rdev_dec_pending(rdev, conf->mddev);
 	clear_bit(R5_LOCKED, &sh->dev[i].flags);
+	clear_bit(R5_Reading, &sh->dev[i].flags);
 	set_bit(STRIPE_HANDLE, &sh->state);
 	release_stripe(sh);
 }
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index a9fc249..a596df8 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -298,6 +298,7 @@ enum r5dev_flags {
 	R5_WantReplace, /* We need to update the replacement, we have read
 			 * data in, and now is a good time to write it out.
 			 */
+	R5_Reading,	/* this dev on reading on lld*/
 };
 
 /*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-09-26  9:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-15  2:20 [PATCH] raid5: Avoid doing more read on dev of a stripe at the same time Jianpeng Ma
2012-09-20  2:51 ` NeilBrown
2012-09-20  3:04   ` Jianpeng Ma
2012-09-20  3:24     ` NeilBrown
2012-09-20  6:04       ` Jianpeng Ma
2012-09-21  2:24       ` Jianpeng Ma
2012-09-25  7:29         ` NeilBrown
2012-09-26  2:43           ` NeilBrown
2012-09-26  4:09             ` Jianpeng Ma
2012-09-26  9:14             ` Jianpeng Ma

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).