Message ID | 20231011093412.7994-2-kkartik@nvidia.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | soc/tegra: fuse: Add ACPI support | expand |
On Wed, Oct 11, 2023 at 2:17 PM Kartik <kkartik@nvidia.com> wrote: > > Introduce function kmemdup_array(), that will copy `n` number of > elements from a given array `src` to `dst`. > > On success, kmemdup_array() returns 0 and copy the elements from `src` > to newly allocated array `dst`, it also stores number of elements > copied from `src` array to `dst_count` parameter. On failure, this > returns a negative integer value containing the error value. Hmm... Why is it so complicated? Can it be as simple as return kmemdup(size_mul()); ? -- With Best Regards, Andy Shevchenko
On Wed, 2023-10-11 at 18:36:11 +0300, Andy Shevchenko wrote: > On Wed, Oct 11, 2023 at 2:17 PM Kartik <kkartik@nvidia.com> wrote: > > > > Introduce function kmemdup_array(), that will copy `n` number of > > elements from a given array `src` to `dst`. > > > > On success, kmemdup_array() returns 0 and copy the elements from `src` > > to newly allocated array `dst`, it also stores number of elements > > copied from `src` array to `dst_count` parameter. On failure, this > > returns a negative integer value containing the error value. > > Hmm... Why is it so complicated? > > Can it be as simple as > > return kmemdup(size_mul()); > > ? > > -- > With Best Regards, > Andy Shevchenko The idea was to validate the arguments that are passed to kmemdup_array(). But I agree doing so complicates things here. I will update this in the next patchset. Thanks & Regards, Kartik
diff --git a/include/linux/string.h b/include/linux/string.h index dbfc66400050..6245a7918b05 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -179,6 +179,8 @@ extern char *kstrndup(const char *s, size_t len, gfp_t gfp); extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp); +extern int kmemdup_array(void **dst, size_t *dst_count, const void *src, size_t element_size, + size_t count, gfp_t gfp); extern char **argv_split(gfp_t gfp, const char *str, int *argcp); extern void argv_free(char **argv); diff --git a/mm/util.c b/mm/util.c index 6eddd891198e..a7c87a119be1 100644 --- a/mm/util.c +++ b/mm/util.c @@ -135,6 +135,40 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) } EXPORT_SYMBOL(kmemdup); +/** + * kmemdup_array - duplicate a given array. + * + * @dst: reference to the pointer to store address of duplicated array. + * @dst_count: number of elements in the duplicated array. + * @src: array to duplicate. + * @element_size: size of each element of array. + * @count: number of elements to duplicate from array. + * @gfp: GFP mask to use. + * + * Return: Returns 0 on success, on failure this returns a negative error value. + */ +int kmemdup_array(void **dst, size_t *dst_count, const void *src, size_t element_size, size_t count, + gfp_t gfp) +{ + size_t size; + + *dst_count = 0; + + if (!src || !element_size || !count) + return -EINVAL; + + size = size_mul(element_size, count); + + *dst = kmemdup(src, size, gfp); + if (*dst) + return -ENOMEM; + + *dst_count = size / element_size; + + return 0; +} +EXPORT_SYMBOL(kmemdup_array); + /** * kvmemdup - duplicate region of memory *
Introduce function kmemdup_array(), that will copy `n` number of elements from a given array `src` to `dst`. On success, kmemdup_array() returns 0 and copy the elements from `src` to newly allocated array `dst`, it also stores number of elements copied from `src` array to `dst_count` parameter. On failure, this returns a negative integer value containing the error value. Signed-off-by: Kartik <kkartik@nvidia.com> --- include/linux/string.h | 2 ++ mm/util.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+)