|
@@ -68,25 +68,22 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
|
|
|
EXPORT_SYMBOL(kmemdup);
|
|
|
|
|
|
/**
|
|
|
- * krealloc - reallocate memory. The contents will remain unchanged.
|
|
|
+ * __krealloc - like krealloc() but don't free @p.
|
|
|
* @p: object to reallocate memory for.
|
|
|
* @new_size: how many bytes of memory are required.
|
|
|
* @flags: the type of memory to allocate.
|
|
|
*
|
|
|
- * The contents of the object pointed to are preserved up to the
|
|
|
- * lesser of the new and old sizes. If @p is %NULL, krealloc()
|
|
|
- * behaves exactly like kmalloc(). If @size is 0 and @p is not a
|
|
|
- * %NULL pointer, the object pointed to is freed.
|
|
|
+ * This function is like krealloc() except it never frees the originally
|
|
|
+ * allocated buffer. Use this if you don't want to free the buffer immediately
|
|
|
+ * like, for example, with RCU.
|
|
|
*/
|
|
|
-void *krealloc(const void *p, size_t new_size, gfp_t flags)
|
|
|
+void *__krealloc(const void *p, size_t new_size, gfp_t flags)
|
|
|
{
|
|
|
void *ret;
|
|
|
size_t ks = 0;
|
|
|
|
|
|
- if (unlikely(!new_size)) {
|
|
|
- kfree(p);
|
|
|
+ if (unlikely(!new_size))
|
|
|
return ZERO_SIZE_PTR;
|
|
|
- }
|
|
|
|
|
|
if (p)
|
|
|
ks = ksize(p);
|
|
@@ -95,10 +92,37 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags)
|
|
|
return (void *)p;
|
|
|
|
|
|
ret = kmalloc_track_caller(new_size, flags);
|
|
|
- if (ret && p) {
|
|
|
+ if (ret && p)
|
|
|
memcpy(ret, p, ks);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__krealloc);
|
|
|
+
|
|
|
+/**
|
|
|
+ * krealloc - reallocate memory. The contents will remain unchanged.
|
|
|
+ * @p: object to reallocate memory for.
|
|
|
+ * @new_size: how many bytes of memory are required.
|
|
|
+ * @flags: the type of memory to allocate.
|
|
|
+ *
|
|
|
+ * The contents of the object pointed to are preserved up to the
|
|
|
+ * lesser of the new and old sizes. If @p is %NULL, krealloc()
|
|
|
+ * behaves exactly like kmalloc(). If @size is 0 and @p is not a
|
|
|
+ * %NULL pointer, the object pointed to is freed.
|
|
|
+ */
|
|
|
+void *krealloc(const void *p, size_t new_size, gfp_t flags)
|
|
|
+{
|
|
|
+ void *ret;
|
|
|
+
|
|
|
+ if (unlikely(!new_size)) {
|
|
|
kfree(p);
|
|
|
+ return ZERO_SIZE_PTR;
|
|
|
}
|
|
|
+
|
|
|
+ ret = __krealloc(p, new_size, flags);
|
|
|
+ if (ret && p != ret)
|
|
|
+ kfree(p);
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL(krealloc);
|