diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/util.c | 44 |
1 files changed, 34 insertions, 10 deletions
@@ -70,25 +70,22 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) | |||
70 | EXPORT_SYMBOL(kmemdup); | 70 | EXPORT_SYMBOL(kmemdup); |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * krealloc - reallocate memory. The contents will remain unchanged. | 73 | * __krealloc - like krealloc() but don't free @p. |
74 | * @p: object to reallocate memory for. | 74 | * @p: object to reallocate memory for. |
75 | * @new_size: how many bytes of memory are required. | 75 | * @new_size: how many bytes of memory are required. |
76 | * @flags: the type of memory to allocate. | 76 | * @flags: the type of memory to allocate. |
77 | * | 77 | * |
78 | * The contents of the object pointed to are preserved up to the | 78 | * This function is like krealloc() except it never frees the originally |
79 | * lesser of the new and old sizes. If @p is %NULL, krealloc() | 79 | * allocated buffer. Use this if you don't want to free the buffer immediately |
80 | * behaves exactly like kmalloc(). If @size is 0 and @p is not a | 80 | * like, for example, with RCU. |
81 | * %NULL pointer, the object pointed to is freed. | ||
82 | */ | 81 | */ |
83 | void *krealloc(const void *p, size_t new_size, gfp_t flags) | 82 | void *__krealloc(const void *p, size_t new_size, gfp_t flags) |
84 | { | 83 | { |
85 | void *ret; | 84 | void *ret; |
86 | size_t ks = 0; | 85 | size_t ks = 0; |
87 | 86 | ||
88 | if (unlikely(!new_size)) { | 87 | if (unlikely(!new_size)) |
89 | kfree(p); | ||
90 | return ZERO_SIZE_PTR; | 88 | return ZERO_SIZE_PTR; |
91 | } | ||
92 | 89 | ||
93 | if (p) | 90 | if (p) |
94 | ks = ksize(p); | 91 | ks = ksize(p); |
@@ -97,10 +94,37 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags) | |||
97 | return (void *)p; | 94 | return (void *)p; |
98 | 95 | ||
99 | ret = kmalloc_track_caller(new_size, flags); | 96 | ret = kmalloc_track_caller(new_size, flags); |
100 | if (ret && p) { | 97 | if (ret && p) |
101 | memcpy(ret, p, ks); | 98 | memcpy(ret, p, ks); |
99 | |||
100 | return ret; | ||
101 | } | ||
102 | EXPORT_SYMBOL(__krealloc); | ||
103 | |||
104 | /** | ||
105 | * krealloc - reallocate memory. The contents will remain unchanged. | ||
106 | * @p: object to reallocate memory for. | ||
107 | * @new_size: how many bytes of memory are required. | ||
108 | * @flags: the type of memory to allocate. | ||
109 | * | ||
110 | * The contents of the object pointed to are preserved up to the | ||
111 | * lesser of the new and old sizes. If @p is %NULL, krealloc() | ||
112 | * behaves exactly like kmalloc(). If @size is 0 and @p is not a | ||
113 | * %NULL pointer, the object pointed to is freed. | ||
114 | */ | ||
115 | void *krealloc(const void *p, size_t new_size, gfp_t flags) | ||
116 | { | ||
117 | void *ret; | ||
118 | |||
119 | if (unlikely(!new_size)) { | ||
102 | kfree(p); | 120 | kfree(p); |
121 | return ZERO_SIZE_PTR; | ||
103 | } | 122 | } |
123 | |||
124 | ret = __krealloc(p, new_size, flags); | ||
125 | if (ret && p != ret) | ||
126 | kfree(p); | ||
127 | |||
104 | return ret; | 128 | return ret; |
105 | } | 129 | } |
106 | EXPORT_SYMBOL(krealloc); | 130 | EXPORT_SYMBOL(krealloc); |