# 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
|