|
@@ -3150,6 +3150,78 @@ static ssize_t ubb_store(struct md_rdev *rdev, const char *page, size_t len)
|
|
|
static struct rdev_sysfs_entry rdev_unack_bad_blocks =
|
|
|
__ATTR(unacknowledged_bad_blocks, S_IRUGO|S_IWUSR, ubb_show, ubb_store);
|
|
|
|
|
|
+static ssize_t
|
|
|
+ppl_sector_show(struct md_rdev *rdev, char *page)
|
|
|
+{
|
|
|
+ return sprintf(page, "%llu\n", (unsigned long long)rdev->ppl.sector);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t
|
|
|
+ppl_sector_store(struct md_rdev *rdev, const char *buf, size_t len)
|
|
|
+{
|
|
|
+ unsigned long long sector;
|
|
|
+
|
|
|
+ if (kstrtoull(buf, 10, §or) < 0)
|
|
|
+ return -EINVAL;
|
|
|
+ if (sector != (sector_t)sector)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (rdev->mddev->pers && test_bit(MD_HAS_PPL, &rdev->mddev->flags) &&
|
|
|
+ rdev->raid_disk >= 0)
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ if (rdev->mddev->persistent) {
|
|
|
+ if (rdev->mddev->major_version == 0)
|
|
|
+ return -EINVAL;
|
|
|
+ if ((sector > rdev->sb_start &&
|
|
|
+ sector - rdev->sb_start > S16_MAX) ||
|
|
|
+ (sector < rdev->sb_start &&
|
|
|
+ rdev->sb_start - sector > -S16_MIN))
|
|
|
+ return -EINVAL;
|
|
|
+ rdev->ppl.offset = sector - rdev->sb_start;
|
|
|
+ } else if (!rdev->mddev->external) {
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ rdev->ppl.sector = sector;
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+static struct rdev_sysfs_entry rdev_ppl_sector =
|
|
|
+__ATTR(ppl_sector, S_IRUGO|S_IWUSR, ppl_sector_show, ppl_sector_store);
|
|
|
+
|
|
|
+static ssize_t
|
|
|
+ppl_size_show(struct md_rdev *rdev, char *page)
|
|
|
+{
|
|
|
+ return sprintf(page, "%u\n", rdev->ppl.size);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t
|
|
|
+ppl_size_store(struct md_rdev *rdev, const char *buf, size_t len)
|
|
|
+{
|
|
|
+ unsigned int size;
|
|
|
+
|
|
|
+ if (kstrtouint(buf, 10, &size) < 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (rdev->mddev->pers && test_bit(MD_HAS_PPL, &rdev->mddev->flags) &&
|
|
|
+ rdev->raid_disk >= 0)
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
+ if (rdev->mddev->persistent) {
|
|
|
+ if (rdev->mddev->major_version == 0)
|
|
|
+ return -EINVAL;
|
|
|
+ if (size > U16_MAX)
|
|
|
+ return -EINVAL;
|
|
|
+ } else if (!rdev->mddev->external) {
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ rdev->ppl.size = size;
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
+static struct rdev_sysfs_entry rdev_ppl_size =
|
|
|
+__ATTR(ppl_size, S_IRUGO|S_IWUSR, ppl_size_show, ppl_size_store);
|
|
|
+
|
|
|
static struct attribute *rdev_default_attrs[] = {
|
|
|
&rdev_state.attr,
|
|
|
&rdev_errors.attr,
|
|
@@ -3160,6 +3232,8 @@ static struct attribute *rdev_default_attrs[] = {
|
|
|
&rdev_recovery_start.attr,
|
|
|
&rdev_bad_blocks.attr,
|
|
|
&rdev_unack_bad_blocks.attr,
|
|
|
+ &rdev_ppl_sector.attr,
|
|
|
+ &rdev_ppl_size.attr,
|
|
|
NULL,
|
|
|
};
|
|
|
static ssize_t
|
|
@@ -4896,6 +4970,46 @@ static struct md_sysfs_entry md_array_size =
|
|
|
__ATTR(array_size, S_IRUGO|S_IWUSR, array_size_show,
|
|
|
array_size_store);
|
|
|
|
|
|
+static ssize_t
|
|
|
+consistency_policy_show(struct mddev *mddev, char *page)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) {
|
|
|
+ ret = sprintf(page, "journal\n");
|
|
|
+ } else if (test_bit(MD_HAS_PPL, &mddev->flags)) {
|
|
|
+ ret = sprintf(page, "ppl\n");
|
|
|
+ } else if (mddev->bitmap) {
|
|
|
+ ret = sprintf(page, "bitmap\n");
|
|
|
+ } else if (mddev->pers) {
|
|
|
+ if (mddev->pers->sync_request)
|
|
|
+ ret = sprintf(page, "resync\n");
|
|
|
+ else
|
|
|
+ ret = sprintf(page, "none\n");
|
|
|
+ } else {
|
|
|
+ ret = sprintf(page, "unknown\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t
|
|
|
+consistency_policy_store(struct mddev *mddev, const char *buf, size_t len)
|
|
|
+{
|
|
|
+ if (mddev->pers) {
|
|
|
+ return -EBUSY;
|
|
|
+ } else if (mddev->external && strncmp(buf, "ppl", 3) == 0) {
|
|
|
+ set_bit(MD_HAS_PPL, &mddev->flags);
|
|
|
+ return len;
|
|
|
+ } else {
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static struct md_sysfs_entry md_consistency_policy =
|
|
|
+__ATTR(consistency_policy, S_IRUGO | S_IWUSR, consistency_policy_show,
|
|
|
+ consistency_policy_store);
|
|
|
+
|
|
|
static struct attribute *md_default_attrs[] = {
|
|
|
&md_level.attr,
|
|
|
&md_layout.attr,
|
|
@@ -4911,6 +5025,7 @@ static struct attribute *md_default_attrs[] = {
|
|
|
&md_reshape_direction.attr,
|
|
|
&md_array_size.attr,
|
|
|
&max_corr_read_errors.attr,
|
|
|
+ &md_consistency_policy.attr,
|
|
|
NULL,
|
|
|
};
|
|
|
|