diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index a79dd33d343d..92fd0104fa04 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2365,6 +2365,63 @@ sync_completed_show(mddev_t *mddev, char *page) | |||
2365 | static struct md_sysfs_entry | 2365 | static struct md_sysfs_entry |
2366 | md_sync_completed = __ATTR_RO(sync_completed); | 2366 | md_sync_completed = __ATTR_RO(sync_completed); |
2367 | 2367 | ||
2368 | static ssize_t | ||
2369 | suspend_lo_show(mddev_t *mddev, char *page) | ||
2370 | { | ||
2371 | return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo); | ||
2372 | } | ||
2373 | |||
2374 | static ssize_t | ||
2375 | suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) | ||
2376 | { | ||
2377 | char *e; | ||
2378 | unsigned long long new = simple_strtoull(buf, &e, 10); | ||
2379 | |||
2380 | if (mddev->pers->quiesce == NULL) | ||
2381 | return -EINVAL; | ||
2382 | if (buf == e || (*e && *e != '\n')) | ||
2383 | return -EINVAL; | ||
2384 | if (new >= mddev->suspend_hi || | ||
2385 | (new > mddev->suspend_lo && new < mddev->suspend_hi)) { | ||
2386 | mddev->suspend_lo = new; | ||
2387 | mddev->pers->quiesce(mddev, 2); | ||
2388 | return len; | ||
2389 | } else | ||
2390 | return -EINVAL; | ||
2391 | } | ||
2392 | static struct md_sysfs_entry md_suspend_lo = | ||
2393 | __ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store); | ||
2394 | |||
2395 | |||
2396 | static ssize_t | ||
2397 | suspend_hi_show(mddev_t *mddev, char *page) | ||
2398 | { | ||
2399 | return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_hi); | ||
2400 | } | ||
2401 | |||
2402 | static ssize_t | ||
2403 | suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) | ||
2404 | { | ||
2405 | char *e; | ||
2406 | unsigned long long new = simple_strtoull(buf, &e, 10); | ||
2407 | |||
2408 | if (mddev->pers->quiesce == NULL) | ||
2409 | return -EINVAL; | ||
2410 | if (buf == e || (*e && *e != '\n')) | ||
2411 | return -EINVAL; | ||
2412 | if ((new <= mddev->suspend_lo && mddev->suspend_lo >= mddev->suspend_hi) || | ||
2413 | (new > mddev->suspend_lo && new > mddev->suspend_hi)) { | ||
2414 | mddev->suspend_hi = new; | ||
2415 | mddev->pers->quiesce(mddev, 1); | ||
2416 | mddev->pers->quiesce(mddev, 0); | ||
2417 | return len; | ||
2418 | } else | ||
2419 | return -EINVAL; | ||
2420 | } | ||
2421 | static struct md_sysfs_entry md_suspend_hi = | ||
2422 | __ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); | ||
2423 | |||
2424 | |||
2368 | static struct attribute *md_default_attrs[] = { | 2425 | static struct attribute *md_default_attrs[] = { |
2369 | &md_level.attr, | 2426 | &md_level.attr, |
2370 | &md_raid_disks.attr, | 2427 | &md_raid_disks.attr, |
@@ -2382,6 +2439,8 @@ static struct attribute *md_redundancy_attrs[] = { | |||
2382 | &md_sync_max.attr, | 2439 | &md_sync_max.attr, |
2383 | &md_sync_speed.attr, | 2440 | &md_sync_speed.attr, |
2384 | &md_sync_completed.attr, | 2441 | &md_sync_completed.attr, |
2442 | &md_suspend_lo.attr, | ||
2443 | &md_suspend_hi.attr, | ||
2385 | NULL, | 2444 | NULL, |
2386 | }; | 2445 | }; |
2387 | static struct attribute_group md_redundancy_group = { | 2446 | static struct attribute_group md_redundancy_group = { |