aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-06-24 09:41:59 -0700
committerBrian Behlendorf <[email protected]>2010-06-24 09:41:59 -0700
commite6de04b73cfaa1b17eee531d472cbbd37c247502 (patch)
tree88f515ee9b834209c9cc914868959cec64828742
parent438683c0a9c9a045106f27aca85dc1855d926497 (diff)
Add kmem_vasprintf function
We might as well have both asprintf() variants. This allows us to safely pass a va_list through several levels of the stack using va_copy() instead of va_start().
-rw-r--r--include/sys/kmem.h1
-rw-r--r--module/spl/spl-kmem.c24
2 files changed, 21 insertions, 4 deletions
diff --git a/include/sys/kmem.h b/include/sys/kmem.h
index a5ee4e0df..9688b116d 100644
--- a/include/sys/kmem.h
+++ b/include/sys/kmem.h
@@ -248,6 +248,7 @@ enum {
#define KMC_DEFAULT_SEEKS 1
extern int kmem_debugging(void);
+extern char *kmem_vasprintf(const char *fmt, va_list ap);
extern char *kmem_asprintf(const char *fmt, ...);
#define strfree(str) kfree(str)
#define strdup(str) kstrdup(str, GFP_KERNEL)
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index 4620eb9bf..a348021d8 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -239,16 +239,32 @@ EXPORT_SYMBOL(kvasprintf);
#endif /* HAVE_KVASPRINTF */
char *
+kmem_vasprintf(const char *fmt, va_list ap)
+{
+ va_list aq;
+ char *ptr;
+
+ va_copy(aq, ap);
+ do {
+ ptr = kvasprintf(GFP_KERNEL, fmt, aq);
+ } while (ptr == NULL);
+ va_end(aq);
+
+ return ptr;
+}
+EXPORT_SYMBOL(kmem_vasprintf);
+
+char *
kmem_asprintf(const char *fmt, ...)
{
- va_list args;
+ va_list ap;
char *ptr;
- va_start(args, fmt);
+ va_start(ap, fmt);
do {
- ptr = kvasprintf(GFP_KERNEL, fmt, args);
+ ptr = kvasprintf(GFP_KERNEL, fmt, ap);
} while (ptr == NULL);
- va_end(args);
+ va_end(ap);
return ptr;
}