lib/bitmap.c: correct a code style and do some, optimization
Subsystems (2)
PATCH RESEND 1/3 lib/bitmap.c: correct a code style and do some, optimization
We can avoid in-loop incrementation of ndigits. Save current totaldigits to ndigits before loop, and check ndigits against totaldigits after the loop.
--- lib/bitmap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
lib/bitmap.c +4 -3
@@ -367,7 +367,8 @@ int __bitmap_parse(const char *buf, unsigned int buflen, nchunks = nbits = totaldigits = c =0 ; do { - chunk = ndigits = 0; + chunk = 0; + ndigits = totaldigits; /* Get the next chunk of the bitmap */ while (buflen) {
@@ -406,9 +407,9 @@ int __bitmap_parse(const char *buf, unsigned int buflen,return -EOVERFLOW ; chunk = (chunk <<4 ) |hex_to_bin (c); - ndigits++; totaldigits++; + totaldigits++; } -if (ndigits ==0 ) +if (ndigits == totaldigits)return -EINVAL ;if (nchunks ==0 && chunk ==0 )continue ;
Signature · 1 line
1.9.1
PATCH RESEND 2/3 lib/bitmap.c: fix a special string handling bug in __bitmap_parselist
If string end with '-', for exapmle, bitmap_parselist("1,0-",&mask, nmaskbits), It is not in a valid pattern, so add a check after loop.
Return -EINVAL on such condition.
--- lib/bitmap.c | 4 ++++ 1 file changed, 4 insertions(+)
lib/bitmap.c +4 -0
@@ -546,6 +546,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,return -EINVAL ; b =0 ; in_range =1 ; + at_start =1 ;continue ; }
@@ -558,6 +559,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, at_start =0 ; totaldigits++; } +/* if no digit is after '-', it's wrong*/ +if (at_start && in_range) +return -EINVAL ;if (!(a <= b))return -EINVAL ;if (b >= nmaskbits)
Signature · 1 line
1.9.1
PATCH RESEND 3/3 lib/bitmap.c: bitmap_parselist can accept string with whitespaces on head or tail
In __bitmap_parselist we can accept whitespaces on head or tail during every parsing procedure.
If input has valid ranges, there is no reason to reject the user.
For example, bitmap_parselist(" 1-3, 5, ", &mask, nmaskbits). After separating the string, we get " 1-3", " 5", and " ". It's possible and reasonable to accept such string as long as the parsing result is correct.
--- lib/bitmap.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
lib/bitmap.c +18 -14
@@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, int nmaskbits) {unsigned a, b; -int c, old_c, totaldigits; +int c, old_c, totaldigits, ndigits;const char __user __force *ubuf = (const char __user __force *)buf;int at_start, in_range;
@@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, at_start =1 ; in_range =0 ; a = b =0 ; + ndigits = totaldigits;/* Get the next cpu# or a range of cpu#'s */ while (buflen) {
@@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,if (isspace (c))continue ; -/* -* If the last character was a space and the current -* character isn't '\0', we've got embedded whitespace. -* This is a no-no, so throw an error. -*/ -if (totaldigits && c &&isspace (old_c)) -return -EINVAL ; -/* A '\0' or a ',' signal the end of a cpu# or range */ if (c =='\0' || c ==',' )break ; +/* +* whitespaces between digits are not allowed, +* but it's ok if whitespaces are on head or tail. +* when old_c is whilespace, +* if totaldigits == ndigits, whitespace is on head. +* if whitespace is on tail, it should not run here. +* as c was ',' or '\0', +* the last code line has broken the current loop. +*/ +if ((totaldigits != ndigits) &&isspace (old_c)) +return -EINVAL ;if (c =='-' ) {if (at_start || in_range)
@@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, at_start =0 ; totaldigits++; } +if (ndigits == totaldigits) +continue ;/* if no digit is after '-', it's wrong*/ if (at_start && in_range)return -EINVAL ;
@@ -566,11 +572,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,return -EINVAL ;if (b >= nmaskbits)return -ERANGE ; -if (!at_start) { -while (a <= b) { -set_bit (a, maskp); - a++; - } +while (a <= b) { +set_bit (a, maskp); + a++; } }while (buflen && c ==',' );return 0 ;
Signature · 1 line
1.9.1