import __bitmap_parselist from Linux kernel
Import __bitmap_parselist from the Linux kernel, in order to parse CPU ranges as used in eg. the kernel isolcpus= commandline argument. This code appears to have been in the Linux kernel since the initial git import in 2005, so I do not have attribution of which changeset(s) introduced it into the kernel. Signed-off-by: Rik van Riel <riel@redhat.com>
This commit is contained in:
parent
f498717bd8
commit
976e741c59
2 changed files with 92 additions and 2 deletions
84
bitmap.c
84
bitmap.c
|
@ -377,3 +377,87 @@ int __bitmap_parse(const char *buf, unsigned int buflen,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __bitmap_parselist - convert list format ASCII string to bitmap
|
||||
* @buf: read nul-terminated user string from this buffer
|
||||
* @buflen: buffer size in bytes. If string is smaller than this
|
||||
* then it must be terminated with a \0.
|
||||
* @is_user: location of buffer, 0 indicates kernel space
|
||||
* @maskp: write resulting mask here
|
||||
* @nmaskbits: number of bits in mask to be written
|
||||
*
|
||||
* Input format is a comma-separated list of decimal numbers and
|
||||
* ranges. Consecutively set bits are shown as two hyphen-separated
|
||||
* decimal numbers, the smallest and largest bit numbers set in
|
||||
* the range.
|
||||
*
|
||||
* Returns 0 on success, -errno on invalid input strings.
|
||||
* Error values:
|
||||
* %-EINVAL: second number in range smaller than first
|
||||
* %-EINVAL: invalid character in string
|
||||
* %-ERANGE: bit number specified too large for mask
|
||||
*/
|
||||
int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||
int is_user __attribute((unused)), unsigned long *maskp,
|
||||
int nmaskbits)
|
||||
{
|
||||
int a, b, c, old_c, totaldigits;
|
||||
int exp_digit, in_range;
|
||||
|
||||
totaldigits = c = 0;
|
||||
bitmap_zero(maskp, nmaskbits);
|
||||
do {
|
||||
exp_digit = 1;
|
||||
in_range = 0;
|
||||
a = b = 0;
|
||||
|
||||
/* Get the next cpu# or a range of cpu#'s */
|
||||
while (buflen) {
|
||||
old_c = c;
|
||||
c = *buf++;
|
||||
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;
|
||||
|
||||
if (c == '-') {
|
||||
if (exp_digit || in_range)
|
||||
return -EINVAL;
|
||||
b = 0;
|
||||
in_range = 1;
|
||||
exp_digit = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isdigit(c))
|
||||
return -EINVAL;
|
||||
|
||||
b = b * 10 + (c - '0');
|
||||
if (!in_range)
|
||||
a = b;
|
||||
exp_digit = 0;
|
||||
totaldigits++;
|
||||
}
|
||||
if (!(a <= b))
|
||||
return -EINVAL;
|
||||
if (b >= nmaskbits)
|
||||
return -ERANGE;
|
||||
while (a <= b) {
|
||||
set_bit(a, maskp);
|
||||
a++;
|
||||
}
|
||||
} while (buflen && c == ',');
|
||||
return 0;
|
||||
}
|
||||
|
|
10
bitmap.h
10
bitmap.h
|
@ -185,8 +185,8 @@ extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
|
|||
unsigned long *dst, int nbits);
|
||||
extern int bitmap_scnlistprintf(char *buf, unsigned int len,
|
||||
const unsigned long *src, int nbits);
|
||||
extern int bitmap_parselist(const char *buf, unsigned long *maskp,
|
||||
int nmaskbits);
|
||||
extern int __bitmap_parselist(const char *buf, unsigned int buflen, int is_user,
|
||||
unsigned long *dst, int nbits);
|
||||
extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
|
||||
const unsigned long *old, const unsigned long *new, int bits);
|
||||
extern int bitmap_bitremap(int oldbit,
|
||||
|
@ -351,6 +351,12 @@ static inline int bitmap_parse(const char *buf, unsigned int buflen,
|
|||
return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits);
|
||||
}
|
||||
|
||||
static inline int bitmap_parselist(const char *buf, unsigned int buflen,
|
||||
unsigned long *maskp, int nmaskbits)
|
||||
{
|
||||
return __bitmap_parselist(buf, buflen, 0, maskp, nmaskbits);
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __LINUX_BITMAP_H */
|
||||
|
|
Loading…
Reference in a new issue