From: Brian Behlendorf Date: Thu, 24 Jun 2010 16:41:59 +0000 (-0700) Subject: Add kmem_vasprintf function X-Git-Tag: spl-0.5.0~41 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e6de04b73cfaa1b17eee531d472cbbd37c247502;p=spl 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(). --- diff --git a/include/sys/kmem.h b/include/sys/kmem.h index a5ee4e0..9688b11 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 4620eb9..a348021 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -238,17 +238,33 @@ char *kvasprintf(gfp_t gfp, const char *fmt, va_list ap) 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; }