lib/string_helpers: Introduce parse_int_array()

Existing parse_inte_array_user() works with __user buffers only.
Separate array parsing from __user bits so the functionality can be
utilized with kernel buffers too.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
This commit is contained in:
Cezary Rojewski 2023-08-02 12:14:19 +02:00
parent 49446d05da
commit 5a4a7d2576
2 changed files with 22 additions and 18 deletions

View File

@ -21,6 +21,7 @@ enum string_size_units {
void string_get_size(u64 size, u64 blk_size, enum string_size_units units, void string_get_size(u64 size, u64 blk_size, enum string_size_units units,
char *buf, int len); char *buf, int len);
int parse_int_array(const char *buf, size_t count, int **array);
int parse_int_array_user(const char __user *from, size_t count, int **array); int parse_int_array_user(const char __user *from, size_t count, int **array);
#define UNESCAPE_SPACE BIT(0) #define UNESCAPE_SPACE BIT(0)

View File

@ -131,6 +131,25 @@ void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
} }
EXPORT_SYMBOL(string_get_size); EXPORT_SYMBOL(string_get_size);
int parse_int_array(const char *buf, size_t count, int **array)
{
int *ints, nints;
get_options(buf, 0, &nints);
if (!nints)
return -ENOENT;
ints = kcalloc(nints + 1, sizeof(*ints), GFP_KERNEL);
if (!ints)
return -ENOMEM;
get_options(buf, nints + 1, ints);
*array = ints;
return 0;
}
EXPORT_SYMBOL(parse_int_array);
/** /**
* parse_int_array_user - Split string into a sequence of integers * parse_int_array_user - Split string into a sequence of integers
* @from: The user space buffer to read from * @from: The user space buffer to read from
@ -146,30 +165,14 @@ EXPORT_SYMBOL(string_get_size);
*/ */
int parse_int_array_user(const char __user *from, size_t count, int **array) int parse_int_array_user(const char __user *from, size_t count, int **array)
{ {
int *ints, nints;
char *buf; char *buf;
int ret = 0; int ret;
buf = memdup_user_nul(from, count); buf = memdup_user_nul(from, count);
if (IS_ERR(buf)) if (IS_ERR(buf))
return PTR_ERR(buf); return PTR_ERR(buf);
get_options(buf, 0, &nints); ret = parse_int_array(buf, count, array);
if (!nints) {
ret = -ENOENT;
goto free_buf;
}
ints = kcalloc(nints + 1, sizeof(*ints), GFP_KERNEL);
if (!ints) {
ret = -ENOMEM;
goto free_buf;
}
get_options(buf, nints + 1, ints);
*array = ints;
free_buf:
kfree(buf); kfree(buf);
return ret; return ret;
} }