mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-24 17:23:25 -05:00
md: add sysfs entries for PPL
Add 'consistency_policy' attribute for array. It indicates how the array maintains consistency in case of unexpected shutdown. Add 'ppl_sector' and 'ppl_size' for rdev, which describe the location and size of the PPL space on the device. They can't be changed for active members if the array is started and PPL is enabled, so in the setter functions only basic checks are performed. More checks are done in ppl_validate_rdev() when starting the log. These attributes are writable to allow enabling PPL for external metadata arrays and (later) to enable/disable PPL for a running array. Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
parent
3418d036c8
commit
664aed0444
2 changed files with 144 additions and 3 deletions
|
@ -401,7 +401,30 @@ All md devices contain:
|
|||
once the array becomes non-degraded, and this fact has been
|
||||
recorded in the metadata.
|
||||
|
||||
consistency_policy
|
||||
This indicates how the array maintains consistency in case of unexpected
|
||||
shutdown. It can be:
|
||||
|
||||
none
|
||||
Array has no redundancy information, e.g. raid0, linear.
|
||||
|
||||
resync
|
||||
Full resync is performed and all redundancy is regenerated when the
|
||||
array is started after unclean shutdown.
|
||||
|
||||
bitmap
|
||||
Resync assisted by a write-intent bitmap.
|
||||
|
||||
journal
|
||||
For raid4/5/6, journal device is used to log transactions and replay
|
||||
after unclean shutdown.
|
||||
|
||||
ppl
|
||||
For raid5 only, Partial Parity Log is used to close the write hole and
|
||||
eliminate resync.
|
||||
|
||||
The accepted values when writing to this file are ``ppl`` and ``resync``,
|
||||
used to enable and disable PPL.
|
||||
|
||||
|
||||
As component devices are added to an md array, they appear in the ``md``
|
||||
|
@ -563,6 +586,9 @@ Each directory contains:
|
|||
adds bad blocks without acknowledging them. This is largely
|
||||
for testing.
|
||||
|
||||
ppl_sector, ppl_size
|
||||
Location and size (in sectors) of the space used for Partial Parity Log
|
||||
on this device.
|
||||
|
||||
|
||||
An active md device will also contain an entry for each active device
|
||||
|
|
115
drivers/md/md.c
115
drivers/md/md.c
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue