aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c27
1 files changed, 26 insertions, 1 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}