aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c27
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/md/raid10.c11
-rw-r--r--drivers/md/raid5.c3
-rw-r--r--drivers/md/raid6main.c3
5 files changed, 42 insertions, 4 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 594d8c312e6a..32a4e2311e43 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1000,6 +1000,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
1000 } 1000 }
1001 rdev->preferred_minor = 0xffff; 1001 rdev->preferred_minor = 0xffff;
1002 rdev->data_offset = le64_to_cpu(sb->data_offset); 1002 rdev->data_offset = le64_to_cpu(sb->data_offset);
1003 atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read));
1003 1004
1004 rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; 1005 rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
1005 bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1; 1006 bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
@@ -1139,6 +1140,8 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1139 else 1140 else
1140 sb->resync_offset = cpu_to_le64(0); 1141 sb->resync_offset = cpu_to_le64(0);
1141 1142
1143 sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
1144
1142 if (mddev->bitmap && mddev->bitmap_file == NULL) { 1145 if (mddev->bitmap && mddev->bitmap_file == NULL) {
1143 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); 1146 sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
1144 sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); 1147 sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
@@ -1592,9 +1595,30 @@ super_show(mdk_rdev_t *rdev, char *page)
1592} 1595}
1593static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super); 1596static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
1594 1597
1598static ssize_t
1599errors_show(mdk_rdev_t *rdev, char *page)
1600{
1601 return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors));
1602}
1603
1604static ssize_t
1605errors_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1606{
1607 char *e;
1608 unsigned long n = simple_strtoul(buf, &e, 10);
1609 if (*buf && (*e == 0 || *e == '\n')) {
1610 atomic_set(&rdev->corrected_errors, n);
1611 return len;
1612 }
1613 return -EINVAL;
1614}
1615static struct rdev_sysfs_entry rdev_errors =
1616__ATTR(errors, 0644, errors_show, errors_store);
1617
1595static struct attribute *rdev_default_attrs[] = { 1618static struct attribute *rdev_default_attrs[] = {
1596 &rdev_state.attr, 1619 &rdev_state.attr,
1597 &rdev_super.attr, 1620 &rdev_super.attr,
1621 &rdev_errors.attr,
1598 NULL, 1622 NULL,
1599}; 1623};
1600static ssize_t 1624static ssize_t
@@ -1674,6 +1698,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
1674 rdev->data_offset = 0; 1698 rdev->data_offset = 0;
1675 atomic_set(&rdev->nr_pending, 0); 1699 atomic_set(&rdev->nr_pending, 0);
1676 atomic_set(&rdev->read_errors, 0); 1700 atomic_set(&rdev->read_errors, 0);
1701 atomic_set(&rdev->corrected_errors, 0);
1677 1702
1678 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 1703 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
1679 if (!size) { 1704 if (!size) {
@@ -4729,7 +4754,7 @@ static int set_ro(const char *val, struct kernel_param *kp)
4729 int num = simple_strtoul(val, &e, 10); 4754 int num = simple_strtoul(val, &e, 10);
4730 if (*val && (*e == '\0' || *e == '\n')) { 4755 if (*val && (*e == '\0' || *e == '\n')) {
4731 start_readonly = num; 4756 start_readonly = num;
4732 return 0;; 4757 return 0;
4733 } 4758 }
4734 return -EINVAL; 4759 return -EINVAL;
4735} 4760}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 181c9616d5f1..a06ff91f27e2 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1265,6 +1265,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
1265 if (r1_bio->bios[d]->bi_end_io != end_sync_read) 1265 if (r1_bio->bios[d]->bi_end_io != end_sync_read)
1266 continue; 1266 continue;
1267 rdev = conf->mirrors[d].rdev; 1267 rdev = conf->mirrors[d].rdev;
1268 atomic_add(s, &rdev->corrected_errors);
1268 if (sync_page_io(rdev->bdev, 1269 if (sync_page_io(rdev->bdev,
1269 sect + rdev->data_offset, 1270 sect + rdev->data_offset,
1270 s<<9, 1271 s<<9,
@@ -1463,6 +1464,7 @@ static void raid1d(mddev_t *mddev)
1463 d = conf->raid_disks; 1464 d = conf->raid_disks;
1464 d--; 1465 d--;
1465 rdev = conf->mirrors[d].rdev; 1466 rdev = conf->mirrors[d].rdev;
1467 atomic_add(s, &rdev->corrected_errors);
1466 if (rdev && 1468 if (rdev &&
1467 test_bit(In_sync, &rdev->flags)) { 1469 test_bit(In_sync, &rdev->flags)) {
1468 if (sync_page_io(rdev->bdev, 1470 if (sync_page_io(rdev->bdev,
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 201dc7168a5f..9e658e519a27 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1122,9 +1122,13 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error)
1122 1122
1123 if (test_bit(BIO_UPTODATE, &bio->bi_flags)) 1123 if (test_bit(BIO_UPTODATE, &bio->bi_flags))
1124 set_bit(R10BIO_Uptodate, &r10_bio->state); 1124 set_bit(R10BIO_Uptodate, &r10_bio->state);
1125 else if (!test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery)) 1125 else {
1126 md_error(r10_bio->mddev, 1126 atomic_add(r10_bio->sectors,
1127 conf->mirrors[d].rdev); 1127 &conf->mirrors[d].rdev->corrected_errors);
1128 if (!test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery))
1129 md_error(r10_bio->mddev,
1130 conf->mirrors[d].rdev);
1131 }
1128 1132
1129 /* for reconstruct, we always reschedule after a read. 1133 /* for reconstruct, we always reschedule after a read.
1130 * for resync, only after all reads 1134 * for resync, only after all reads
@@ -1430,6 +1434,7 @@ static void raid10d(mddev_t *mddev)
1430 sl--; 1434 sl--;
1431 d = r10_bio->devs[sl].devnum; 1435 d = r10_bio->devs[sl].devnum;
1432 rdev = conf->mirrors[d].rdev; 1436 rdev = conf->mirrors[d].rdev;
1437 atomic_add(s, &rdev->corrected_errors);
1433 if (rdev && 1438 if (rdev &&
1434 test_bit(In_sync, &rdev->flags)) { 1439 test_bit(In_sync, &rdev->flags)) {
1435 if (sync_page_io(rdev->bdev, 1440 if (sync_page_io(rdev->bdev,
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 9cc844f455bf..54f4a9847e38 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1400,6 +1400,9 @@ static void handle_stripe(struct stripe_head *sh)
1400 bi->bi_io_vec[0].bv_offset = 0; 1400 bi->bi_io_vec[0].bv_offset = 0;
1401 bi->bi_size = STRIPE_SIZE; 1401 bi->bi_size = STRIPE_SIZE;
1402 bi->bi_next = NULL; 1402 bi->bi_next = NULL;
1403 if (rw == WRITE &&
1404 test_bit(R5_ReWrite, &sh->dev[i].flags))
1405 atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
1403 generic_make_request(bi); 1406 generic_make_request(bi);
1404 } else { 1407 } else {
1405 if (rw == 1) 1408 if (rw == 1)
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 84dd875bb2f6..8c823d686a60 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -1562,6 +1562,9 @@ static void handle_stripe(struct stripe_head *sh, struct page *tmp_page)
1562 bi->bi_io_vec[0].bv_offset = 0; 1562 bi->bi_io_vec[0].bv_offset = 0;
1563 bi->bi_size = STRIPE_SIZE; 1563 bi->bi_size = STRIPE_SIZE;
1564 bi->bi_next = NULL; 1564 bi->bi_next = NULL;
1565 if (rw == WRITE &&
1566 test_bit(R5_ReWrite, &sh->dev[i].flags))
1567 atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
1565 generic_make_request(bi); 1568 generic_make_request(bi);
1566 } else { 1569 } else {
1567 if (rw == 1) 1570 if (rw == 1)