Loading drivers/md/md.c +42 −22 Original line number Diff line number Diff line Loading @@ -2763,6 +2763,47 @@ static void analyze_sbs(mddev_t * mddev) } } /* Read a fixed-point number. * Numbers in sysfs attributes should be in "standard" units where * possible, so time should be in seconds. * However we internally use a a much smaller unit such as * milliseconds or jiffies. * This function takes a decimal number with a possible fractional * component, and produces an integer which is the result of * multiplying that number by 10^'scale'. * all without any floating-point arithmetic. */ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale) { unsigned long result = 0; long decimals = -1; while (isdigit(*cp) || (*cp == '.' && decimals < 0)) { if (*cp == '.') decimals = 0; else if (decimals < scale) { unsigned int value; value = *cp - '0'; result = result * 10 + value; if (decimals >= 0) decimals++; } cp++; } if (*cp == '\n') cp++; if (*cp) return -EINVAL; if (decimals < 0) decimals = 0; while (decimals < scale) { result *= 10; decimals ++; } *res = result; return 0; } static void md_safemode_timeout(unsigned long data); static ssize_t Loading @@ -2774,31 +2815,10 @@ safe_delay_show(mddev_t *mddev, char *page) static ssize_t safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) { int scale=1; int dot=0; int i; unsigned long msec; char buf[30]; /* remove a period, and count digits after it */ if (len >= sizeof(buf)) return -EINVAL; strlcpy(buf, cbuf, sizeof(buf)); for (i=0; i<len; i++) { if (dot) { if (isdigit(buf[i])) { buf[i-1] = buf[i]; scale *= 10; } buf[i] = 0; } else if (buf[i] == '.') { dot=1; buf[i] = 0; } } if (strict_strtoul(buf, 10, &msec) < 0) if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) return -EINVAL; msec = (msec * 1000) / scale; if (msec == 0) mddev->safemode_delay = 0; else { Loading drivers/md/md.h +2 −1 Original line number Diff line number Diff line Loading @@ -463,6 +463,7 @@ extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); extern int md_check_no_bitmap(mddev_t *mddev); extern int md_integrity_register(mddev_t *mddev); void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); #endif /* _MD_MD_H */ Loading
drivers/md/md.c +42 −22 Original line number Diff line number Diff line Loading @@ -2763,6 +2763,47 @@ static void analyze_sbs(mddev_t * mddev) } } /* Read a fixed-point number. * Numbers in sysfs attributes should be in "standard" units where * possible, so time should be in seconds. * However we internally use a a much smaller unit such as * milliseconds or jiffies. * This function takes a decimal number with a possible fractional * component, and produces an integer which is the result of * multiplying that number by 10^'scale'. * all without any floating-point arithmetic. */ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale) { unsigned long result = 0; long decimals = -1; while (isdigit(*cp) || (*cp == '.' && decimals < 0)) { if (*cp == '.') decimals = 0; else if (decimals < scale) { unsigned int value; value = *cp - '0'; result = result * 10 + value; if (decimals >= 0) decimals++; } cp++; } if (*cp == '\n') cp++; if (*cp) return -EINVAL; if (decimals < 0) decimals = 0; while (decimals < scale) { result *= 10; decimals ++; } *res = result; return 0; } static void md_safemode_timeout(unsigned long data); static ssize_t Loading @@ -2774,31 +2815,10 @@ safe_delay_show(mddev_t *mddev, char *page) static ssize_t safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) { int scale=1; int dot=0; int i; unsigned long msec; char buf[30]; /* remove a period, and count digits after it */ if (len >= sizeof(buf)) return -EINVAL; strlcpy(buf, cbuf, sizeof(buf)); for (i=0; i<len; i++) { if (dot) { if (isdigit(buf[i])) { buf[i-1] = buf[i]; scale *= 10; } buf[i] = 0; } else if (buf[i] == '.') { dot=1; buf[i] = 0; } } if (strict_strtoul(buf, 10, &msec) < 0) if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) return -EINVAL; msec = (msec * 1000) / scale; if (msec == 0) mddev->safemode_delay = 0; else { Loading
drivers/md/md.h +2 −1 Original line number Diff line number Diff line Loading @@ -463,6 +463,7 @@ extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); extern int md_check_no_bitmap(mddev_t *mddev); extern int md_integrity_register(mddev_t *mddev); void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); #endif /* _MD_MD_H */