diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 93fde48c0f42..c37e256b1176 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -94,6 +94,8 @@ | |||
94 | #define __inline__ | 94 | #define __inline__ |
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | #define printk_rl(args...) ((void) (printk_ratelimit() && printk(args))) | ||
98 | |||
97 | #if !RAID6_USE_EMPTY_ZERO_PAGE | 99 | #if !RAID6_USE_EMPTY_ZERO_PAGE |
98 | /* In .bss so it's zeroed */ | 100 | /* In .bss so it's zeroed */ |
99 | const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); | 101 | const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); |
@@ -1143,10 +1145,12 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1143 | set_bit(R5_UPTODATE, &sh->dev[i].flags); | 1145 | set_bit(R5_UPTODATE, &sh->dev[i].flags); |
1144 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | 1146 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { |
1145 | rdev = conf->disks[i].rdev; | 1147 | rdev = conf->disks[i].rdev; |
1146 | printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n", | 1148 | printk_rl(KERN_INFO "raid5:%s: read error corrected" |
1147 | mdname(conf->mddev), STRIPE_SECTORS, | 1149 | " (%lu sectors at %llu on %s)\n", |
1148 | (unsigned long long)(sh->sector + rdev->data_offset), | 1150 | mdname(conf->mddev), STRIPE_SECTORS, |
1149 | bdevname(rdev->bdev, b)); | 1151 | (unsigned long long)(sh->sector |
1152 | + rdev->data_offset), | ||
1153 | bdevname(rdev->bdev, b)); | ||
1150 | clear_bit(R5_ReadError, &sh->dev[i].flags); | 1154 | clear_bit(R5_ReadError, &sh->dev[i].flags); |
1151 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | 1155 | clear_bit(R5_ReWrite, &sh->dev[i].flags); |
1152 | } | 1156 | } |
@@ -1160,16 +1164,22 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1160 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); | 1164 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); |
1161 | atomic_inc(&rdev->read_errors); | 1165 | atomic_inc(&rdev->read_errors); |
1162 | if (conf->mddev->degraded) | 1166 | if (conf->mddev->degraded) |
1163 | printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n", | 1167 | printk_rl(KERN_WARNING |
1164 | mdname(conf->mddev), | 1168 | "raid5:%s: read error not correctable " |
1165 | (unsigned long long)(sh->sector + rdev->data_offset), | 1169 | "(sector %llu on %s).\n", |
1166 | bdn); | 1170 | mdname(conf->mddev), |
1171 | (unsigned long long)(sh->sector | ||
1172 | + rdev->data_offset), | ||
1173 | bdn); | ||
1167 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) | 1174 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) |
1168 | /* Oh, no!!! */ | 1175 | /* Oh, no!!! */ |
1169 | printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n", | 1176 | printk_rl(KERN_WARNING |
1170 | mdname(conf->mddev), | 1177 | "raid5:%s: read error NOT corrected!! " |
1171 | (unsigned long long)(sh->sector + rdev->data_offset), | 1178 | "(sector %llu on %s).\n", |
1172 | bdn); | 1179 | mdname(conf->mddev), |
1180 | (unsigned long long)(sh->sector | ||
1181 | + rdev->data_offset), | ||
1182 | bdn); | ||
1173 | else if (atomic_read(&rdev->read_errors) | 1183 | else if (atomic_read(&rdev->read_errors) |
1174 | > conf->max_nr_stripes) | 1184 | > conf->max_nr_stripes) |
1175 | printk(KERN_WARNING | 1185 | printk(KERN_WARNING |
@@ -1258,7 +1268,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1258 | /* | 1268 | /* |
1259 | * if recovery was running, make sure it aborts. | 1269 | * if recovery was running, make sure it aborts. |
1260 | */ | 1270 | */ |
1261 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1271 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1262 | } | 1272 | } |
1263 | set_bit(Faulty, &rdev->flags); | 1273 | set_bit(Faulty, &rdev->flags); |
1264 | printk (KERN_ALERT | 1274 | printk (KERN_ALERT |
@@ -1992,6 +2002,7 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
1992 | * have quiesced. | 2002 | * have quiesced. |
1993 | */ | 2003 | */ |
1994 | if ((s->uptodate == disks - 1) && | 2004 | if ((s->uptodate == disks - 1) && |
2005 | (s->failed && disk_idx == s->failed_num) && | ||
1995 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { | 2006 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { |
1996 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); | 2007 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); |
1997 | set_bit(R5_Wantcompute, &dev->flags); | 2008 | set_bit(R5_Wantcompute, &dev->flags); |
@@ -2077,7 +2088,9 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh, | |||
2077 | /* we would like to get this block, possibly | 2088 | /* we would like to get this block, possibly |
2078 | * by computing it, but we might not be able to | 2089 | * by computing it, but we might not be able to |
2079 | */ | 2090 | */ |
2080 | if (s->uptodate == disks-1) { | 2091 | if ((s->uptodate == disks - 1) && |
2092 | (s->failed && (i == r6s->failed_num[0] || | ||
2093 | i == r6s->failed_num[1]))) { | ||
2081 | pr_debug("Computing stripe %llu block %d\n", | 2094 | pr_debug("Computing stripe %llu block %d\n", |
2082 | (unsigned long long)sh->sector, i); | 2095 | (unsigned long long)sh->sector, i); |
2083 | compute_block_1(sh, i, 0); | 2096 | compute_block_1(sh, i, 0); |
@@ -2635,6 +2648,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2635 | struct r5dev *dev; | 2648 | struct r5dev *dev; |
2636 | unsigned long pending = 0; | 2649 | unsigned long pending = 0; |
2637 | mdk_rdev_t *blocked_rdev = NULL; | 2650 | mdk_rdev_t *blocked_rdev = NULL; |
2651 | int prexor; | ||
2638 | 2652 | ||
2639 | memset(&s, 0, sizeof(s)); | 2653 | memset(&s, 0, sizeof(s)); |
2640 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " | 2654 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " |
@@ -2764,9 +2778,11 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2764 | /* leave prexor set until postxor is done, allows us to distinguish | 2778 | /* leave prexor set until postxor is done, allows us to distinguish |
2765 | * a rmw from a rcw during biodrain | 2779 | * a rmw from a rcw during biodrain |
2766 | */ | 2780 | */ |
2781 | prexor = 0; | ||
2767 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && | 2782 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && |
2768 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { | 2783 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { |
2769 | 2784 | ||
2785 | prexor = 1; | ||
2770 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); | 2786 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); |
2771 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); | 2787 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); |
2772 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); | 2788 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); |
@@ -2800,6 +2816,8 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2800 | if (!test_and_set_bit( | 2816 | if (!test_and_set_bit( |
2801 | STRIPE_OP_IO, &sh->ops.pending)) | 2817 | STRIPE_OP_IO, &sh->ops.pending)) |
2802 | sh->ops.count++; | 2818 | sh->ops.count++; |
2819 | if (prexor) | ||
2820 | continue; | ||
2803 | if (!test_bit(R5_Insync, &dev->flags) || | 2821 | if (!test_bit(R5_Insync, &dev->flags) || |
2804 | (i == sh->pd_idx && s.failed == 0)) | 2822 | (i == sh->pd_idx && s.failed == 0)) |
2805 | set_bit(STRIPE_INSYNC, &sh->state); | 2823 | set_bit(STRIPE_INSYNC, &sh->state); |
@@ -4564,6 +4582,14 @@ static int raid5_remove_disk(mddev_t *mddev, int number) | |||
4564 | err = -EBUSY; | 4582 | err = -EBUSY; |
4565 | goto abort; | 4583 | goto abort; |
4566 | } | 4584 | } |
4585 | /* Only remove non-faulty devices if recovery | ||
4586 | * isn't possible. | ||
4587 | */ | ||
4588 | if (!test_bit(Faulty, &rdev->flags) && | ||
4589 | mddev->degraded <= conf->max_degraded) { | ||
4590 | err = -EBUSY; | ||
4591 | goto abort; | ||
4592 | } | ||
4567 | p->rdev = NULL; | 4593 | p->rdev = NULL; |
4568 | synchronize_rcu(); | 4594 | synchronize_rcu(); |
4569 | if (atomic_read(&rdev->nr_pending)) { | 4595 | if (atomic_read(&rdev->nr_pending)) { |