diff options
author | NeilBrown <neilb@suse.de> | 2006-01-06 03:20:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:34:09 -0500 |
commit | 4dbcdc751cb25ffca3a8374cbc5ab6de961cc545 (patch) | |
tree | 61d1eb6e35c0eec66e5a8610c1f57b1e6eec135c /drivers/md/md.c | |
parent | d9d166c2a9d5d01af34396793950aa695883eed4 (diff) |
[PATCH] md: count corrected read errors per drive
Store this total in superblock (As appropriate), and make it available to
userspace via sysfs.
Signed-off-by: Neil Brown <neilb@suse.de>
Acked-by: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 27 |
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 | } |
1593 | static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super); | 1596 | static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super); |
1594 | 1597 | ||
1598 | static ssize_t | ||
1599 | errors_show(mdk_rdev_t *rdev, char *page) | ||
1600 | { | ||
1601 | return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors)); | ||
1602 | } | ||
1603 | |||
1604 | static ssize_t | ||
1605 | errors_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 | } | ||
1615 | static struct rdev_sysfs_entry rdev_errors = | ||
1616 | __ATTR(errors, 0644, errors_show, errors_store); | ||
1617 | |||
1595 | static struct attribute *rdev_default_attrs[] = { | 1618 | static 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 | }; |
1600 | static ssize_t | 1624 | static 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 | } |