raid5: fix possible oops in add_stripe_bio when enable pr_debug
PATCH 1/1 raid5: fix possible oops in add_stripe_bio when enable pr_debug
In func add_stripe_bio:
Quoted 8 lines
Quoted 8 lines
.....
bip = &sh->dev[dd_idx].toread;......
spin_unlock_irq(&sh->stripe_lock);pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)(*bip)->bi_sector, (unsigned long long)sh->sector, dd_idx);
After spin_unlock_irq, this thread scheded and toread may become null. So it will be oops.
--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/raid5.c +2 -1
@@ -2356,6 +2356,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, instruct bio **bip;struct r5conf *conf = sh->raid_conf;int firstwrite=0 ; +sector_t sector = bi->bi_sector; pr_debug("adding bi b#%llu to stripe s#%llu\n", (unsigned long long)bi->bi_sector,
@@ -2406,7 +2407,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, inspin_unlock_irq (&sh->stripe_lock);pr_debug ("added bi b#%llu to stripe s#%llu, disk %d.\n" , - (unsigned long long )(*bip)->bi_sector, + (unsigned long long )sector, (unsigned long long )sh->sector, dd_idx);if (conf->mddev->bitmap && firstwrite) {
Signature · 1 line
1.7.9.5
Quoted 30 lines · On Thu, 20 Sep 2012 14:34:00 +0800 "Jianpeng Ma" <[email protected]> wrote:
In func
add_stripe_bio:Quoted 8 lines
Quoted 8 lines
.....
bip = &sh->dev[dd_idx].toread;......
spin_unlock_irq(&sh->stripe_lock);pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)(*bip)->bi_sector, (unsigned long long)sh->sector, dd_idx);After
spin_unlock_irq, this thread scheded and toread may become null. So it will be oops.Signed-off-by Jianpeng Ma <[email protected]>--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/md/raid5.c +1
-0@@ -2356,6 +2356,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, instruct bio **bip;struct r5conf *conf = sh->raid_conf;int firstwrite=0 ; +sector_t sector = bi->bi_sector; pr_debug("adding bi b#%llu to stripe s#%llu\n", (unsigned long long)bi->bi_sector,
drivers/md/raid5.c static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in · line 2413
Quoted 8 lines
drivers/md/raid5.c +1
-1@@ -2406,7 +2407,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, inspin_unlock_irq (&sh->stripe_lock);pr_debug ("added bi b#%llu to stripe s#%llu, disk %d.\n" , - (unsigned long long )(*bip)->bi_sector, + (unsigned long long )sector, (unsigned long long )sh->sector, dd_idx);if (conf->mddev->bitmap && firstwrite) {
how about we just move the spin_unlock_irq after the pr_debug??
NeilBrown
On 2012-09-20 14:47 NeilBrown <[email protected]> Wrote:
Quoted 39 lines · On Thu, 20 Sep 2012 14:34:00 +0800 "Jianpeng Ma" <[email protected]> wrote:
Quoted 38 lines
In func
add_stripe_bio:Quoted 8 lines
Quoted 8 lines
.....
bip = &sh->dev[dd_idx].toread;......
spin_unlock_irq(&sh->stripe_lock);pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)(*bip)->bi_sector, (unsigned long long)sh->sector, dd_idx);After
spin_unlock_irq, this thread scheded and toread may become null. So it will be oops.Signed-off-by Jianpeng Ma <[email protected]>--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/md/raid5.c +2
-1@@ -2356,6 +2356,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, instruct bio **bip;struct r5conf *conf = sh->raid_conf;int firstwrite=0 ; +sector_t sector = bi->bi_sector; pr_debug("adding bi b#%llu to stripe s#%llu\n", (unsigned long long)bi->bi_sector,@@ -2406,7 +2407,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, inspin_unlock_irq (&sh->stripe_lock);pr_debug ("added bi b#%llu to stripe s#%llu, disk %d.\n" , - (unsigned long long )(*bip)->bi_sector, + (unsigned long long )sector, (unsigned long long )sh->sector, dd_idx);
Quoted 5 lines
drivers/md/raid5.c static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in · line 2413
Quoted 1 line
drivers/md/raid5.c +0
-0if (conf->mddev->bitmap && firstwrite) {how about we just move the
spin_unlock_irqafter thepr_debug??
ah! Why are you think ? my method only add a parameter. BTW, in func handle_failed_stripe:
Quoted 7 lines
Quoted 7 lines
if (!test_bit(R5_Wantfill, &sh->dev[i].flags) &&
(!test_bit(R5_Insync, &sh->dev[i].flags) || test_bit(R5_ReadError, &sh->dev[i].flags))) { bi = sh->dev[i].toread; sh->dev[i].toread = NULL; if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) wake_up(&conf->wait_for_overlap);
Why use stripe_lock to protect toread?
Thanks!
Quoted 40 lines · On Thu, 20 Sep 2012 15:17:54 +0800 "Jianpeng Ma" <[email protected]> wrote:
On 2012-09-20 14:47 NeilBrown <[email protected]> Wrote:
Quoted 39 lines · On Thu, 20 Sep 2012 14:34:00 +0800 "Jianpeng Ma" <[email protected]> wrote:
Quoted 38 lines
In func
add_stripe_bio:Quoted 8 lines
Quoted 8 lines
.....
bip = &sh->dev[dd_idx].toread;......
spin_unlock_irq(&sh->stripe_lock);pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)(*bip)->bi_sector, (unsigned long long)sh->sector, dd_idx);After
spin_unlock_irq, this thread scheded and toread may become null. So it will be oops.Signed-off-by Jianpeng Ma <[email protected]>--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/md/raid5.c +2
-1@@ -2356,6 +2356,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, instruct bio **bip;struct r5conf *conf = sh->raid_conf;int firstwrite=0 ; +sector_t sector = bi->bi_sector; pr_debug("adding bi b#%llu to stripe s#%llu\n", (unsigned long long)bi->bi_sector,@@ -2406,7 +2407,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, inspin_unlock_irq (&sh->stripe_lock);pr_debug ("added bi b#%llu to stripe s#%llu, disk %d.\n" , - (unsigned long long )(*bip)->bi_sector, + (unsigned long long )sector, (unsigned long long )sh->sector, dd_idx);
Quoted 6 lines
Quoted 5 lines
drivers/md/raid5.c static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in · line 2413
Quoted 1 line
drivers/md/raid5.c +0
-0if (conf->mddev->bitmap && firstwrite) {how about we just move the
spin_unlock_irqafter thepr_debug??ah! Why are you think ? my method only add a parameter.
Yes.
Quoted 9 lines
BTW, in func
handle_failed_stripe:Quoted 7 lines
Quoted 7 lines
if (!test_bit(R5_Wantfill, &sh->dev[i].flags) &&
(!test_bit(R5_Insync, &sh->dev[i].flags) || test_bit(R5_ReadError, &sh->dev[i].flags))) { bi = sh->dev[i].toread; sh->dev[i].toread = NULL; if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) wake_up(&conf->wait_for_overlap);Why use
stripe_lockto protect toread?
I assume you mean that we should be holding the lock to protect toread, but we aren't.
I've queued a patch to fix that.
Thanks.
NeilBrown
Quoted 2 lines
Thanks!
On 2012-09-25 14:45 NeilBrown <[email protected]> Wrote:
Quoted 59 lines · On Thu, 20 Sep 2012 15:17:54 +0800 "Jianpeng Ma" <[email protected]> wrote:
Quoted 41 lines
On 2012-09-20 14:47 NeilBrown <[email protected]> Wrote:
Quoted 39 lines · On Thu, 20 Sep 2012 14:34:00 +0800 "Jianpeng Ma" <[email protected]> wrote:
Quoted 38 lines
In func
add_stripe_bio:Quoted 8 lines
Quoted 8 lines
.....
bip = &sh->dev[dd_idx].toread;......
spin_unlock_irq(&sh->stripe_lock);pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)(*bip)->bi_sector, (unsigned long long)sh->sector, dd_idx);After
spin_unlock_irq, this thread scheded and toread may become null. So it will be oops.Signed-off-by Jianpeng Ma <[email protected]>--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/md/raid5.c +2
-1@@ -2356,6 +2356,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, instruct bio **bip;struct r5conf *conf = sh->raid_conf;int firstwrite=0 ; +sector_t sector = bi->bi_sector; pr_debug("adding bi b#%llu to stripe s#%llu\n", (unsigned long long)bi->bi_sector,@@ -2406,7 +2407,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, inspin_unlock_irq (&sh->stripe_lock);pr_debug ("added bi b#%llu to stripe s#%llu, disk %d.\n" , - (unsigned long long )(*bip)->bi_sector, + (unsigned long long )sector, (unsigned long long )sh->sector, dd_idx);Quoted 6 lines
Quoted 5 lines
drivers/md/raid5.c static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in · line 2413
Quoted 1 line
drivers/md/raid5.c +0
-0if (conf->mddev->bitmap && firstwrite) {how about we just move the
spin_unlock_irqafter thepr_debug??ah! Why are you think ? my method only add a parameter.
Yes.
Quoted 8 lines
BTW, in func
handle_failed_stripe:Quoted 7 lines
Quoted 7 lines
if (!test_bit(R5_Wantfill, &sh->dev[i].flags) &&
(!test_bit(R5_Insync, &sh->dev[i].flags) || test_bit(R5_ReadError, &sh->dev[i].flags))) { bi = sh->dev[i].toread; sh->dev[i].toread = NULL; if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) wake_up(&conf->wait_for_overlap);
Quoted 6 lines
Quoted 1 line
Why use
stripe_lockto protect toread?I assume you mean that we should be holding the lock to protect toread, but we aren't.
I've queued a patch to fix that.
Hi,
Last Saturday, i sent a patch-set which contained a patch which fix this bug.
You can check your mail!
Thanks!
Quoted 9 lines
Thanks.
NeilBrownQuoted 2 lines
Thanks!