Skip to content

Commit

Permalink
kobject: Refactor kobject_set_name_vargs()
Browse files Browse the repository at this point in the history
Setting name as per the format is not only useful for kobjects.
It can also be used to set name for other things for e.g. setting
the name of the struct attribute when multiple same kind of attributes
need to be created with some identifier in name, instead of managing
memory for names at such places case by case, it would be good if
something like current kobject_set_name_vargs() can be utilized.

Refactor kobject_set_name_vargs(), Create a new generic function
set_name_vargs() which can be used for kobjects as well as at
other places.

This patch doesn't introduce any functionality change.

Signed-off-by: Jagdish Gediya <jvgediya@linux.ibm.com>
  • Loading branch information
Jagdish Gediya authored and intel-lab-lkp committed May 6, 2022
1 parent bc443c3 commit 4aac95b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 29 deletions.
1 change: 1 addition & 0 deletions include/linux/string.h
Expand Up @@ -9,6 +9,7 @@
#include <linux/stdarg.h>
#include <uapi/linux/string.h>

int set_name_vargs(const char **name, const char *fmt, va_list vargs);
extern char *strndup_user(const char __user *, long);
extern void *memdup_user(const void __user *, size_t);
extern void *vmemdup_user(const void __user *, size_t);
Expand Down
30 changes: 1 addition & 29 deletions lib/kobject.c
Expand Up @@ -249,35 +249,7 @@ static int kobject_add_internal(struct kobject *kobj)
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
const char *s;

if (kobj->name && !fmt)
return 0;

s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
if (!s)
return -ENOMEM;

/*
* ewww... some of these buggers have '/' in the name ... If
* that's the case, we need to make sure we have an actual
* allocated copy to modify, since kvasprintf_const may have
* returned something from .rodata.
*/
if (strchr(s, '/')) {
char *t;

t = kstrdup(s, GFP_KERNEL);
kfree_const(s);
if (!t)
return -ENOMEM;
strreplace(t, '/', '!');
s = t;
}
kfree_const(kobj->name);
kobj->name = s;

return 0;
return set_name_vargs(&kobj->name, fmt, vargs);
}

/**
Expand Down
40 changes: 40 additions & 0 deletions mm/util.c
Expand Up @@ -112,6 +112,46 @@ char *kstrndup(const char *s, size_t max, gfp_t gfp)
}
EXPORT_SYMBOL(kstrndup);

/**
* set_name_vargs() - Set the name as per format
* @name: pointer to point to the name as per format
* @fmt: format string used to build the name
* @vargs: vargs to format the string.
*/
int set_name_vargs(const char **name, const char *fmt, va_list vargs)
{
const char *s;

if (*name && !fmt)
return 0;

s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
if (!s)
return -ENOMEM;

/*
* ewww... some of these buggers have '/' in the name ... If
* that's the case, we need to make sure we have an actual
* allocated copy to modify, since kvasprintf_const may have
* returned something from .rodata.
*/
if (strchr(s, '/')) {
char *t;

t = kstrdup(s, GFP_KERNEL);
kfree_const(s);
if (!t)
return -ENOMEM;
strreplace(t, '/', '!');
s = t;
}
kfree_const(*name);
*name = s;

return 0;
}
EXPORT_SYMBOL(set_name_vargs);

/**
* kmemdup - duplicate region of memory
*
Expand Down

0 comments on commit 4aac95b

Please sign in to comment.