diff options
-rw-r--r-- | drivers/md/raid5.c | 19 | ||||
-rw-r--r-- | drivers/md/raid5.h | 1 |
2 files changed, 19 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3fa3f20dc5f5..dbae459fb02d 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1675,6 +1675,8 @@ static void raid5_end_write_request(struct bio *bi, int error) | |||
1675 | raid5_conf_t *conf = sh->raid_conf; | 1675 | raid5_conf_t *conf = sh->raid_conf; |
1676 | int disks = sh->disks, i; | 1676 | int disks = sh->disks, i; |
1677 | int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); | 1677 | int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); |
1678 | sector_t first_bad; | ||
1679 | int bad_sectors; | ||
1678 | 1680 | ||
1679 | for (i=0 ; i<disks; i++) | 1681 | for (i=0 ; i<disks; i++) |
1680 | if (bi == &sh->dev[i].req) | 1682 | if (bi == &sh->dev[i].req) |
@@ -1691,7 +1693,9 @@ static void raid5_end_write_request(struct bio *bi, int error) | |||
1691 | if (!uptodate) { | 1693 | if (!uptodate) { |
1692 | set_bit(WriteErrorSeen, &conf->disks[i].rdev->flags); | 1694 | set_bit(WriteErrorSeen, &conf->disks[i].rdev->flags); |
1693 | set_bit(R5_WriteError, &sh->dev[i].flags); | 1695 | set_bit(R5_WriteError, &sh->dev[i].flags); |
1694 | } | 1696 | } else if (is_badblock(conf->disks[i].rdev, sh->sector, STRIPE_SECTORS, |
1697 | &first_bad, &bad_sectors)) | ||
1698 | set_bit(R5_MadeGood, &sh->dev[i].flags); | ||
1695 | 1699 | ||
1696 | rdev_dec_pending(conf->disks[i].rdev, conf->mddev); | 1700 | rdev_dec_pending(conf->disks[i].rdev, conf->mddev); |
1697 | 1701 | ||
@@ -3078,6 +3082,13 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3078 | } else | 3082 | } else |
3079 | clear_bit(R5_WriteError, &dev->flags); | 3083 | clear_bit(R5_WriteError, &dev->flags); |
3080 | } | 3084 | } |
3085 | if (test_bit(R5_MadeGood, &dev->flags)) { | ||
3086 | if (!test_bit(Faulty, &rdev->flags)) { | ||
3087 | s->handle_bad_blocks = 1; | ||
3088 | atomic_inc(&rdev->nr_pending); | ||
3089 | } else | ||
3090 | clear_bit(R5_MadeGood, &dev->flags); | ||
3091 | } | ||
3081 | if (!test_bit(R5_Insync, &dev->flags)) { | 3092 | if (!test_bit(R5_Insync, &dev->flags)) { |
3082 | /* The ReadError flag will just be confusing now */ | 3093 | /* The ReadError flag will just be confusing now */ |
3083 | clear_bit(R5_ReadError, &dev->flags); | 3094 | clear_bit(R5_ReadError, &dev->flags); |
@@ -3340,6 +3351,12 @@ finish: | |||
3340 | md_error(conf->mddev, rdev); | 3351 | md_error(conf->mddev, rdev); |
3341 | rdev_dec_pending(rdev, conf->mddev); | 3352 | rdev_dec_pending(rdev, conf->mddev); |
3342 | } | 3353 | } |
3354 | if (test_and_clear_bit(R5_MadeGood, &dev->flags)) { | ||
3355 | rdev = conf->disks[i].rdev; | ||
3356 | rdev_clear_badblocks(rdev, sh->sector, | ||
3357 | STRIPE_SECTORS); | ||
3358 | rdev_dec_pending(rdev, conf->mddev); | ||
3359 | } | ||
3343 | } | 3360 | } |
3344 | 3361 | ||
3345 | if (s.ops_request) | 3362 | if (s.ops_request) |
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 8620cb67ae39..11b9566184b2 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h | |||
@@ -274,6 +274,7 @@ struct stripe_head_state { | |||
274 | #define R5_Wantdrain 13 /* dev->towrite needs to be drained */ | 274 | #define R5_Wantdrain 13 /* dev->towrite needs to be drained */ |
275 | #define R5_WantFUA 14 /* Write should be FUA */ | 275 | #define R5_WantFUA 14 /* Write should be FUA */ |
276 | #define R5_WriteError 15 /* got a write error - need to record it */ | 276 | #define R5_WriteError 15 /* got a write error - need to record it */ |
277 | #define R5_MadeGood 16 /* A bad block has been fixed by writing to it*/ | ||
277 | /* | 278 | /* |
278 | * Write method | 279 | * Write method |
279 | */ | 280 | */ |