[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [LINUX] Import kasprintf patch from upstream.
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxxxxx> # Node ID c242b6d6a64a3697b0ee140aec1d24538543c5d5 # Parent aaaa249e6f3b7b955605746909eb1a09b8b61061 [LINUX] Import kasprintf patch from upstream. kasprintf has been merged upstream with a slightly different protoype to the one in Xen. Import this patch and fixup the Xen tree to fit. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 7 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 25 - linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h | 3 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c | 4 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 7 patches/linux-2.6.16.32/kasprintf.patch | 32 + patches/linux-2.6.16.32/series | 2 patches/linux-2.6.16.32/vsnprintf.patch | 177 ++++++++++ unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h | 5 unmodified_drivers/linux-2.6/platform-pci/platform-compat.c | 23 + 10 files changed, 247 insertions(+), 38 deletions(-) diff -r aaaa249e6f3b -r c242b6d6a64a linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Mon Nov 27 13:50:02 2006 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Mon Nov 27 13:50:02 2006 +0000 @@ -38,9 +38,6 @@ #ifdef HAVE_XEN_PLATFORM_COMPAT_H #include <xen/platform-compat.h> #endif - -/* xenbus_probe.c */ -extern char *kasprintf(const char *fmt, ...); #define DPRINTK(fmt, args...) \ pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args) @@ -88,7 +85,7 @@ int xenbus_watch_path2(struct xenbus_dev const char **, unsigned int)) { int err; - char *state = kasprintf("%s/%s", path, path2); + char *state = kasprintf(GFP_KERNEL, "%s/%s", path, path2); if (!state) { xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch"); return -ENOMEM; @@ -156,7 +153,7 @@ EXPORT_SYMBOL_GPL(xenbus_frontend_closed */ static char *error_path(struct xenbus_device *dev) { - return kasprintf("error/%s", dev->nodename); + return kasprintf(GFP_KERNEL, "error/%s", dev->nodename); } diff -r aaaa249e6f3b -r c242b6d6a64a linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Nov 27 13:50:02 2006 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Nov 27 13:50:02 2006 +0000 @@ -444,27 +444,6 @@ static void xenbus_dev_release(struct de kfree(to_xenbus_device(dev)); } -/* Simplified asprintf. */ -char *kasprintf(const char *fmt, ...) -{ - va_list ap; - unsigned int len; - char *p, dummy[1]; - - va_start(ap, fmt); - /* FIXME: vsnprintf has a bug, NULL should work */ - len = vsnprintf(dummy, 0, fmt, ap); - va_end(ap); - - p = kmalloc(len + 1, GFP_KERNEL); - if (!p) - return NULL; - va_start(ap, fmt); - vsprintf(p, fmt, ap); - va_end(ap); - return p; -} - static ssize_t xendev_show_nodename(struct device *dev, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) struct device_attribute *attr, @@ -547,7 +526,7 @@ static int xenbus_probe_frontend(const c char *nodename; int err; - nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name); + nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_frontend.root, type, name); if (!nodename) return -ENOMEM; @@ -644,7 +623,7 @@ void dev_changed(const char *node, struc rootlen = strsep_len(node, '/', bus->levels); if (rootlen < 0) return; - root = kasprintf("%.*s", rootlen, node); + root = kasprintf(GFP_KERNEL, "%.*s", rootlen, node); if (!root) return; diff -r aaaa249e6f3b -r c242b6d6a64a linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h Mon Nov 27 13:50:02 2006 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h Mon Nov 27 13:50:02 2006 +0000 @@ -70,8 +70,5 @@ extern int xenbus_probe_devices(struct x extern void dev_changed(const char *node, struct xen_bus_type *bus); -/* Simplified asprintf. Probably belongs in lib */ -extern char *kasprintf(const char *fmt, ...); - #endif diff -r aaaa249e6f3b -r c242b6d6a64a linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c Mon Nov 27 13:50:02 2006 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c Mon Nov 27 13:50:02 2006 +0000 @@ -188,7 +188,7 @@ static int xenbus_probe_backend_unit(con char *nodename; int err; - nodename = kasprintf("%s/%s", dir, name); + nodename = kasprintf(GFP_KERNEL, "%s/%s", dir, name); if (!nodename) return -ENOMEM; @@ -209,7 +209,7 @@ static int xenbus_probe_backend(const ch DPRINTK(""); - nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid); + nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_backend.root, type, domid); if (!nodename) return -ENOMEM; diff -r aaaa249e6f3b -r c242b6d6a64a linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Nov 27 13:50:02 2006 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Nov 27 13:50:02 2006 +0000 @@ -51,9 +51,6 @@ #include <xen/platform-compat.h> #endif -/* xenbus_probe.c */ -extern char *kasprintf(const char *fmt, ...); - struct xs_stored_msg { struct list_head list; @@ -295,9 +292,9 @@ static char *join(const char *dir, const char *buffer; if (strlen(name) == 0) - buffer = kasprintf("%s", dir); + buffer = kasprintf(GFP_KERNEL, "%s", dir); else - buffer = kasprintf("%s/%s", dir, name); + buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name); return (!buffer) ? ERR_PTR(-ENOMEM) : buffer; } diff -r aaaa249e6f3b -r c242b6d6a64a patches/linux-2.6.16.32/series --- a/patches/linux-2.6.16.32/series Mon Nov 27 13:50:02 2006 +0000 +++ b/patches/linux-2.6.16.32/series Mon Nov 27 13:50:02 2006 +0000 @@ -23,3 +23,5 @@ x86-put-note-sections-into-a-pt_note-seg x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch x86-elfnote-as-preprocessor-macro.patch +vsnprintf.patch +kasprintf.patch diff -r aaaa249e6f3b -r c242b6d6a64a unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h --- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Mon Nov 27 13:50:02 2006 +0000 +++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Mon Nov 27 13:50:02 2006 +0000 @@ -64,4 +64,9 @@ void *kzalloc(size_t size, int flags); #define end_that_request_last(req, uptodate) end_that_request_last(req) #endif +#if defined(_LINUX_KERNEL_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +extern char *kasprintf(gfp_t gfp, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); #endif + +#endif diff -r aaaa249e6f3b -r c242b6d6a64a unmodified_drivers/linux-2.6/platform-pci/platform-compat.c --- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Mon Nov 27 13:50:02 2006 +0000 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Mon Nov 27 13:50:02 2006 +0000 @@ -114,3 +114,26 @@ void *kzalloc(size_t size, int flags) } EXPORT_SYMBOL(kzalloc); #endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +/* Simplified asprintf. */ +char *kasprintf(gfp_t gfp, const char *fmt, ...) +{ + va_list ap; + unsigned int len; + char *p, dummy[1]; + + va_start(ap, fmt); + len = vsnprintf(dummy, 0, fmt, ap); + va_end(ap); + + p = kmalloc(len + 1, gfp); + if (!p) + return NULL; + va_start(ap, fmt); + vsprintf(p, fmt, ap); + va_end(ap); + return p; +} +EXPORT_SYMBOL(kasprintf); +#endif diff -r aaaa249e6f3b -r c242b6d6a64a patches/linux-2.6.16.32/kasprintf.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.32/kasprintf.patch Mon Nov 27 13:50:02 2006 +0000 @@ -0,0 +1,59 @@ +commit e905914f96e11862b130dd229f73045dad9a34e8 +Author: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx> +Date: Sun Jun 25 05:49:17 2006 -0700 + + [PATCH] Implement kasprintf + + Implement kasprintf, a kernel version of asprintf. This allocates the + memory required for the formatted string, including the trailing '\0'. + Returns NULL on allocation failure. + + Signed-off-by: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx> + Signed-off-by: Chris Wright <chrisw@xxxxxxxxxxxx> + Signed-off-by: Andrew Morton <akpm@xxxxxxxx> + Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx> + +diff --git a/include/linux/kernel.h b/include/linux/kernel.h +index 8c21aaa..3c5e4c2 100644 +--- a/include/linux/kernel.h ++++ b/include/linux/kernel.h +@@ -117,6 +117,8 @@ extern int scnprintf(char * buf, size_t + __attribute__ ((format (printf, 3, 4))); + extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))); ++extern char *kasprintf(gfp_t gfp, const char *fmt, ...) ++ __attribute__ ((format (printf, 2, 3))); + + extern int sscanf(const char *, const char *, ...) + __attribute__ ((format (scanf, 2, 3))); +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index f595947..797428a 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -849,3 +849,26 @@ int sscanf(const char * buf, const char + } + + EXPORT_SYMBOL(sscanf); ++ ++ ++/* Simplified asprintf. */ ++char *kasprintf(gfp_t gfp, const char *fmt, ...) ++{ ++ va_list ap; ++ unsigned int len; ++ char *p; ++ ++ va_start(ap, fmt); ++ len = vsnprintf(NULL, 0, fmt, ap); ++ va_end(ap); ++ ++ p = kmalloc(len+1, gfp); ++ if (!p) ++ return NULL; ++ va_start(ap, fmt); ++ vsnprintf(p, len+1, fmt, ap); ++ va_end(ap); ++ return p; ++} ++ ++EXPORT_SYMBOL(kasprintf); diff -r aaaa249e6f3b -r c242b6d6a64a patches/linux-2.6.16.32/vsnprintf.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.16.32/vsnprintf.patch Mon Nov 27 13:50:02 2006 +0000 @@ -0,0 +1,211 @@ +commit f796937a062c7aeb44cd0e75e1586c8543634a7d +Author: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx> +Date: Sun Jun 25 05:49:17 2006 -0700 + + [PATCH] Fix bounds check in vsnprintf, to allow for a 0 size and NULL buffer + + This change allows callers to use a 0-byte buffer and a NULL buffer pointer + with vsnprintf, so it can be used to determine how large the resulting + formatted string will be. + + Previously the code effectively treated a size of 0 as a size of 4G (on + 32-bit systems), with other checks preventing it from actually trying to + emit the string - but the terminal \0 would still be written, which would + crash if the buffer is NULL. + + This change changes the boundary check so that 'end' points to the putative + location of the terminal '\0', which is only written if size > 0. + + vsnprintf still allows the buffer size to be set very large, to allow + unbounded buffer sizes (to implement sprintf, etc). + + [akpm@xxxxxxxx: fix long-vs-longlong confusion] + Signed-off-by: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx> + Signed-off-by: Chris Wright <chrisw@xxxxxxxxxxxx> + Signed-off-by: Andrew Morton <akpm@xxxxxxxx> + Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx> + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index b07db5c..f595947 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -187,49 +187,49 @@ static char * number(char * buf, char * + size -= precision; + if (!(type&(ZEROPAD+LEFT))) { + while(size-->0) { +- if (buf <= end) ++ if (buf < end) + *buf = ' '; + ++buf; + } + } + if (sign) { +- if (buf <= end) ++ if (buf < end) + *buf = sign; + ++buf; + } + if (type & SPECIAL) { + if (base==8) { +- if (buf <= end) ++ if (buf < end) + *buf = '0'; + ++buf; + } else if (base==16) { +- if (buf <= end) ++ if (buf < end) + *buf = '0'; + ++buf; +- if (buf <= end) ++ if (buf < end) + *buf = digits[33]; + ++buf; + } + } + if (!(type & LEFT)) { + while (size-- > 0) { +- if (buf <= end) ++ if (buf < end) + *buf = c; + ++buf; + } + } + while (i < precision--) { +- if (buf <= end) ++ if (buf < end) + *buf = '0'; + ++buf; + } + while (i-- > 0) { +- if (buf <= end) ++ if (buf < end) + *buf = tmp[i]; + ++buf; + } + while (size-- > 0) { +- if (buf <= end) ++ if (buf < end) + *buf = ' '; + ++buf; + } +@@ -272,7 +272,8 @@ int vsnprintf(char *buf, size_t size, co + /* 'z' changed to 'Z' --davidm 1/25/99 */ + /* 't' added for ptrdiff_t */ + +- /* Reject out-of-range values early */ ++ /* Reject out-of-range values early. Large positive sizes are ++ used for unknown buffer sizes. */ + if (unlikely((int) size < 0)) { + /* There can be only one.. */ + static int warn = 1; +@@ -282,16 +283,17 @@ int vsnprintf(char *buf, size_t size, co + } + + str = buf; +- end = buf + size - 1; ++ end = buf + size; + +- if (end < buf - 1) { +- end = ((void *) -1); +- size = end - buf + 1; ++ /* Make sure end is always >= buf */ ++ if (end < buf) { ++ end = ((void *)-1); ++ size = end - buf; + } + + for (; *fmt ; ++fmt) { + if (*fmt != '%') { +- if (str <= end) ++ if (str < end) + *str = *fmt; + ++str; + continue; +@@ -357,17 +359,17 @@ int vsnprintf(char *buf, size_t size, co + case 'c': + if (!(flags & LEFT)) { + while (--field_width > 0) { +- if (str <= end) ++ if (str < end) + *str = ' '; + ++str; + } + } + c = (unsigned char) va_arg(args, int); +- if (str <= end) ++ if (str < end) + *str = c; + ++str; + while (--field_width > 0) { +- if (str <= end) ++ if (str < end) + *str = ' '; + ++str; + } +@@ -382,18 +384,18 @@ int vsnprintf(char *buf, size_t size, co + + if (!(flags & LEFT)) { + while (len < field_width--) { +- if (str <= end) ++ if (str < end) + *str = ' '; + ++str; + } + } + for (i = 0; i < len; ++i) { +- if (str <= end) ++ if (str < end) + *str = *s; + ++str; ++s; + } + while (len < field_width--) { +- if (str <= end) ++ if (str < end) + *str = ' '; + ++str; + } +@@ -426,7 +428,7 @@ int vsnprintf(char *buf, size_t size, co + continue; + + case '%': +- if (str <= end) ++ if (str < end) + *str = '%'; + ++str; + continue; +@@ -449,11 +451,11 @@ int vsnprintf(char *buf, size_t size, co + break; + + default: +- if (str <= end) ++ if (str < end) + *str = '%'; + ++str; + if (*fmt) { +- if (str <= end) ++ if (str < end) + *str = *fmt; + ++str; + } else { +@@ -483,14 +485,13 @@ int vsnprintf(char *buf, size_t size, co + str = number(str, end, num, base, + field_width, precision, flags); + } +- if (str <= end) +- *str = '\0'; +- else if (size > 0) +- /* don't write out a null byte if the buf size is zero */ +- *end = '\0'; +- /* the trailing null byte doesn't count towards the total +- * ++str; +- */ ++ if (size > 0) { ++ if (str < end) ++ *str = '\0'; ++ else ++ *end = '\0'; ++ } ++ /* the trailing null byte doesn't count towards the total */ + return str-buf; + } + _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |