Slab allocators: Cleanup zeroing allocations
[linux-2.6.git] / mm / util.c
1 #include <linux/slab.h>
2 #include <linux/string.h>
3 #include <linux/module.h>
4 #include <linux/err.h>
5 #include <asm/uaccess.h>
6
7 /**
8  * kstrdup - allocate space for and copy an existing string
9  *
10  * @s: the string to duplicate
11  * @gfp: the GFP mask used in the kmalloc() call when allocating memory
12  */
13 char *kstrdup(const char *s, gfp_t gfp)
14 {
15         size_t len;
16         char *buf;
17
18         if (!s)
19                 return NULL;
20
21         len = strlen(s) + 1;
22         buf = kmalloc_track_caller(len, gfp);
23         if (buf)
24                 memcpy(buf, s, len);
25         return buf;
26 }
27 EXPORT_SYMBOL(kstrdup);
28
29 /**
30  * kmemdup - duplicate region of memory
31  *
32  * @src: memory region to duplicate
33  * @len: memory region length
34  * @gfp: GFP mask to use
35  */
36 void *kmemdup(const void *src, size_t len, gfp_t gfp)
37 {
38         void *p;
39
40         p = kmalloc_track_caller(len, gfp);
41         if (p)
42                 memcpy(p, src, len);
43         return p;
44 }
45 EXPORT_SYMBOL(kmemdup);
46
47 /**
48  * krealloc - reallocate memory. The contents will remain unchanged.
49  * @p: object to reallocate memory for.
50  * @new_size: how many bytes of memory are required.
51  * @flags: the type of memory to allocate.
52  *
53  * The contents of the object pointed to are preserved up to the
54  * lesser of the new and old sizes.  If @p is %NULL, krealloc()
55  * behaves exactly like kmalloc().  If @size is 0 and @p is not a
56  * %NULL pointer, the object pointed to is freed.
57  */
58 void *krealloc(const void *p, size_t new_size, gfp_t flags)
59 {
60         void *ret;
61         size_t ks;
62
63         if (unlikely(!new_size)) {
64                 kfree(p);
65                 return ZERO_SIZE_PTR;
66         }
67
68         ks = ksize(p);
69         if (ks >= new_size)
70                 return (void *)p;
71
72         ret = kmalloc_track_caller(new_size, flags);
73         if (ret) {
74                 memcpy(ret, p, min(new_size, ks));
75                 kfree(p);
76         }
77         return ret;
78 }
79 EXPORT_SYMBOL(krealloc);
80
81 /*
82  * strndup_user - duplicate an existing string from user space
83  *
84  * @s: The string to duplicate
85  * @n: Maximum number of bytes to copy, including the trailing NUL.
86  */
87 char *strndup_user(const char __user *s, long n)
88 {
89         char *p;
90         long length;
91
92         length = strnlen_user(s, n);
93
94         if (!length)
95                 return ERR_PTR(-EFAULT);
96
97         if (length > n)
98                 return ERR_PTR(-EINVAL);
99
100         p = kmalloc(length, GFP_KERNEL);
101
102         if (!p)
103                 return ERR_PTR(-ENOMEM);
104
105         if (copy_from_user(p, s, length)) {
106                 kfree(p);
107                 return ERR_PTR(-EFAULT);
108         }
109
110         p[length - 1] = '\0';
111
112         return p;
113 }
114 EXPORT_SYMBOL(strndup_user);