linux/mm/util.c
<<
>>
Prefs
   1#include <linux/mm.h>
   2#include <linux/slab.h>
   3#include <linux/string.h>
   4#include <linux/module.h>
   5#include <linux/err.h>
   6#include <linux/sched.h>
   7#include <asm/uaccess.h>
   8
   9/**
  10 * kstrdup - allocate space for and copy an existing string
  11 * @s: the string to duplicate
  12 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
  13 */
  14char *kstrdup(const char *s, gfp_t gfp)
  15{
  16        size_t len;
  17        char *buf;
  18
  19        if (!s)
  20                return NULL;
  21
  22        len = strlen(s) + 1;
  23        buf = kmalloc_track_caller(len, gfp);
  24        if (buf)
  25                memcpy(buf, s, len);
  26        return buf;
  27}
  28EXPORT_SYMBOL(kstrdup);
  29
  30/**
  31 * kstrndup - allocate space for and copy an existing string
  32 * @s: the string to duplicate
  33 * @max: read at most @max chars from @s
  34 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
  35 */
  36char *kstrndup(const char *s, size_t max, gfp_t gfp)
  37{
  38        size_t len;
  39        char *buf;
  40
  41        if (!s)
  42                return NULL;
  43
  44        len = strnlen(s, max);
  45        buf = kmalloc_track_caller(len+1, gfp);
  46        if (buf) {
  47                memcpy(buf, s, len);
  48                buf[len] = '\0';
  49        }
  50        return buf;
  51}
  52EXPORT_SYMBOL(kstrndup);
  53
  54/**
  55 * kmemdup - duplicate region of memory
  56 *
  57 * @src: memory region to duplicate
  58 * @len: memory region length
  59 * @gfp: GFP mask to use
  60 */
  61void *kmemdup(const void *src, size_t len, gfp_t gfp)
  62{
  63        void *p;
  64
  65        p = kmalloc_track_caller(len, gfp);
  66        if (p)
  67                memcpy(p, src, len);
  68        return p;
  69}
  70EXPORT_SYMBOL(kmemdup);
  71
  72/**
  73 * __krealloc - like krealloc() but don't free @p.
  74 * @p: object to reallocate memory for.
  75 * @new_size: how many bytes of memory are required.
  76 * @flags: the type of memory to allocate.
  77 *
  78 * This function is like krealloc() except it never frees the originally
  79 * allocated buffer. Use this if you don't want to free the buffer immediately
  80 * like, for example, with RCU.
  81 */
  82void *__krealloc(const void *p, size_t new_size, gfp_t flags)
  83{
  84        void *ret;
  85        size_t ks = 0;
  86
  87        if (unlikely(!new_size))
  88                return ZERO_SIZE_PTR;
  89
  90        if (p)
  91                ks = ksize(p);
  92
  93        if (ks >= new_size)
  94                return (void *)p;
  95
  96        ret = kmalloc_track_caller(new_size, flags);
  97        if (ret && p)
  98                memcpy(ret, p, ks);
  99
 100        return ret;
 101}
 102EXPORT_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 */
 115void *krealloc(const void *p, size_t new_size, gfp_t flags)
 116{
 117        void *ret;
 118
 119        if (unlikely(!new_size)) {
 120                kfree(p);
 121                return ZERO_SIZE_PTR;
 122        }
 123
 124        ret = __krealloc(p, new_size, flags);
 125        if (ret && p != ret)
 126                kfree(p);
 127
 128        return ret;
 129}
 130EXPORT_SYMBOL(krealloc);
 131
 132/*
 133 * strndup_user - duplicate an existing string from user space
 134 * @s: The string to duplicate
 135 * @n: Maximum number of bytes to copy, including the trailing NUL.
 136 */
 137char *strndup_user(const char __user *s, long n)
 138{
 139        char *p;
 140        long length;
 141
 142        length = strnlen_user(s, n);
 143
 144        if (!length)
 145                return ERR_PTR(-EFAULT);
 146
 147        if (length > n)
 148                return ERR_PTR(-EINVAL);
 149
 150        p = kmalloc(length, GFP_KERNEL);
 151
 152        if (!p)
 153                return ERR_PTR(-ENOMEM);
 154
 155        if (copy_from_user(p, s, length)) {
 156                kfree(p);
 157                return ERR_PTR(-EFAULT);
 158        }
 159
 160        p[length - 1] = '\0';
 161
 162        return p;
 163}
 164EXPORT_SYMBOL(strndup_user);
 165
 166#ifndef HAVE_ARCH_PICK_MMAP_LAYOUT
 167void arch_pick_mmap_layout(struct mm_struct *mm)
 168{
 169        mm->mmap_base = TASK_UNMAPPED_BASE;
 170        mm->get_unmapped_area = arch_get_unmapped_area;
 171        mm->unmap_area = arch_unmap_area;
 172}
 173#endif
 174
 175int __attribute__((weak)) get_user_pages_fast(unsigned long start,
 176                                int nr_pages, int write, struct page **pages)
 177{
 178        struct mm_struct *mm = current->mm;
 179        int ret;
 180
 181        down_read(&mm->mmap_sem);
 182        ret = get_user_pages(current, mm, start, nr_pages,
 183                                        write, 0, pages, NULL);
 184        up_read(&mm->mmap_sem);
 185
 186        return ret;
 187}
 188EXPORT_SYMBOL_GPL(get_user_pages_fast);
 189
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.