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.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 30a93d64921e..ad576ad2ca76 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -44,6 +44,7 @@
44#include <linux/suspend.h> 44#include <linux/suspend.h>
45#include <linux/poll.h> 45#include <linux/poll.h>
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <linux/ctype.h>
47 48
48#include <linux/init.h> 49#include <linux/init.h>
49 50
@@ -1978,6 +1979,54 @@ static void analyze_sbs(mddev_t * mddev)
1978} 1979}
1979 1980
1980static ssize_t 1981static ssize_t
1982safe_delay_show(mddev_t *mddev, char *page)
1983{
1984 int msec = (mddev->safemode_delay*1000)/HZ;
1985 return sprintf(page, "%d.%03d\n", msec/1000, msec%1000);
1986}
1987static ssize_t
1988safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
1989{
1990 int scale=1;
1991 int dot=0;
1992 int i;
1993 unsigned long msec;
1994 char buf[30];
1995 char *e;
1996 /* remove a period, and count digits after it */
1997 if (len >= sizeof(buf))
1998 return -EINVAL;
1999 strlcpy(buf, cbuf, len);
2000 buf[len] = 0;
2001 for (i=0; i<len; i++) {
2002 if (dot) {
2003 if (isdigit(buf[i])) {
2004 buf[i-1] = buf[i];
2005 scale *= 10;
2006 }
2007 buf[i] = 0;
2008 } else if (buf[i] == '.') {
2009 dot=1;
2010 buf[i] = 0;
2011 }
2012 }
2013 msec = simple_strtoul(buf, &e, 10);
2014 if (e == buf || (*e && *e != '\n'))
2015 return -EINVAL;
2016 msec = (msec * 1000) / scale;
2017 if (msec == 0)
2018 mddev->safemode_delay = 0;
2019 else {
2020 mddev->safemode_delay = (msec*HZ)/1000;
2021 if (mddev->safemode_delay == 0)
2022 mddev->safemode_delay = 1;
2023 }
2024 return len;
2025}
2026static struct md_sysfs_entry md_safe_delay =
2027__ATTR(safe_mode_delay, 0644,safe_delay_show, safe_delay_store);
2028
2029static ssize_t
1981level_show(mddev_t *mddev, char *page) 2030level_show(mddev_t *mddev, char *page)
1982{ 2031{
1983 struct mdk_personality *p = mddev->pers; 2032 struct mdk_personality *p = mddev->pers;
@@ -2433,6 +2482,7 @@ static struct attribute *md_default_attrs[] = {
2433 &md_size.attr, 2482 &md_size.attr,
2434 &md_metadata.attr, 2483 &md_metadata.attr,
2435 &md_new_device.attr, 2484 &md_new_device.attr,
2485 &md_safe_delay.attr,
2436 NULL, 2486 NULL,
2437}; 2487};
2438 2488
@@ -2708,7 +2758,7 @@ static int do_md_run(mddev_t * mddev)
2708 mddev->safemode = 0; 2758 mddev->safemode = 0;
2709 mddev->safemode_timer.function = md_safemode_timeout; 2759 mddev->safemode_timer.function = md_safemode_timeout;
2710 mddev->safemode_timer.data = (unsigned long) mddev; 2760 mddev->safemode_timer.data = (unsigned long) mddev;
2711 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ 2761 mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */
2712 mddev->in_sync = 1; 2762 mddev->in_sync = 1;
2713 2763
2714 ITERATE_RDEV(mddev,rdev,tmp) 2764 ITERATE_RDEV(mddev,rdev,tmp)
@@ -4594,7 +4644,7 @@ void md_write_end(mddev_t *mddev)
4594 if (atomic_dec_and_test(&mddev->writes_pending)) { 4644 if (atomic_dec_and_test(&mddev->writes_pending)) {
4595 if (mddev->safemode == 2) 4645 if (mddev->safemode == 2)
4596 md_wakeup_thread(mddev->thread); 4646 md_wakeup_thread(mddev->thread);
4597 else 4647 else if (mddev->safemode_delay)
4598 mod_timer(&mddev->safemode_timer, jiffies + mddev->safemode_delay); 4648 mod_timer(&mddev->safemode_timer, jiffies + mddev->safemode_delay);
4599 } 4649 }
4600} 4650}