[PATCH] create a kstrdup library function
authorPaulo Marques <pmarques@grupopie.com>
Thu, 23 Jun 2005 07:09:02 +0000 (00:09 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 23 Jun 2005 16:45:18 +0000 (09:45 -0700)
This patch creates a new kstrdup library function and changes the "local"
implementations in several places to use this function.

Most of the changes come from the sound and net subsystems.  The sound part
had already been acknowledged by Takashi Iwai and the net part by David S.
Miller.

I left UML alone for now because I would need more time to read the code
carefully before making changes there.

Signed-off-by: Paulo Marques <pmarques@grupopie.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
21 files changed:
drivers/md/dm-ioctl.c
drivers/parport/probe.c
include/linux/netdevice.h
include/linux/string.h
include/sound/core.h
mm/slab.c
net/core/neighbour.c
net/core/sysctl_net_core.c
net/ipv4/devinet.c
net/ipv6/addrconf.c
net/sunrpc/svcauth_unix.c
sound/core/info.c
sound/core/info_oss.c
sound/core/memory.c
sound/core/oss/mixer_oss.c
sound/core/oss/pcm_oss.c
sound/core/sound.c
sound/core/timer.c
sound/isa/gus/gus_mem.c
sound/pci/hda/patch_realtek.c
sound/synth/emux/emux.c

index ee3c869d9701933d366dfdf18fc023eb5cef2da8..200a0688f717c76759c1165cde20652ad14d07f7 100644 (file)
@@ -122,14 +122,6 @@ static struct hash_cell *__get_uuid_cell(const char *str)
 /*-----------------------------------------------------------------
  * Inserting, removing and renaming a device.
  *---------------------------------------------------------------*/
-static inline char *kstrdup(const char *str)
-{
-       char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
-       if (r)
-               strcpy(r, str);
-       return r;
-}
-
 static struct hash_cell *alloc_cell(const char *name, const char *uuid,
                                    struct mapped_device *md)
 {
@@ -139,7 +131,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid,
        if (!hc)
                return NULL;
 
-       hc->name = kstrdup(name);
+       hc->name = kstrdup(name, GFP_KERNEL);
        if (!hc->name) {
                kfree(hc);
                return NULL;
@@ -149,7 +141,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid,
                hc->uuid = NULL;
 
        else {
-               hc->uuid = kstrdup(uuid);
+               hc->uuid = kstrdup(uuid, GFP_KERNEL);
                if (!hc->uuid) {
                        kfree(hc->name);
                        kfree(hc);
@@ -273,7 +265,7 @@ static int dm_hash_rename(const char *old, const char *new)
        /*
         * duplicate new.
         */
-       new_name = kstrdup(new);
+       new_name = kstrdup(new, GFP_KERNEL);
        if (!new_name)
                return -ENOMEM;
 
index c94963145e17991bbfeb233e8d7a63733da58698..6e6f42d01e64847cc626ca974e01f58f15d755f5 100644 (file)
@@ -48,14 +48,6 @@ static void pretty_print(struct parport *port, int device)
        printk("\n");
 }
 
-static char *strdup(char *str)
-{
-       int n = strlen(str)+1;
-       char *s = kmalloc(n, GFP_KERNEL);
-       if (!s) return NULL;
-       return strcpy(s, str);
-}
-
 static void parse_data(struct parport *port, int device, char *str)
 {
        char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
@@ -88,16 +80,16 @@ static void parse_data(struct parport *port, int device, char *str)
                        if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
                                if (info->mfr)
                                        kfree (info->mfr);
-                               info->mfr = strdup(sep);
+                               info->mfr = kstrdup(sep, GFP_KERNEL);
                        } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
                                if (info->model)
                                        kfree (info->model);
-                               info->model = strdup(sep);
+                               info->model = kstrdup(sep, GFP_KERNEL);
                        } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
                                int i;
                                if (info->class_name)
                                        kfree (info->class_name);
-                               info->class_name = strdup(sep);
+                               info->class_name = kstrdup(sep, GFP_KERNEL);
                                for (u = sep; *u; u++)
                                        *u = toupper(*u);
                                for (i = 0; classes[i].token; i++) {
@@ -112,7 +104,7 @@ static void parse_data(struct parport *port, int device, char *str)
                                   !strcmp(p, "COMMAND SET")) {
                                if (info->cmdset)
                                        kfree (info->cmdset);
-                               info->cmdset = strdup(sep);
+                               info->cmdset = kstrdup(sep, GFP_KERNEL);
                                /* if it speaks printer language, it's
                                   probably a printer */
                                if (strstr(sep, "PJL") || strstr(sep, "PCL"))
@@ -120,7 +112,7 @@ static void parse_data(struct parport *port, int device, char *str)
                        } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
                                if (info->description)
                                        kfree (info->description);
-                               info->description = strdup(sep);
+                               info->description = kstrdup(sep, GFP_KERNEL);
                        }
                }
        rock_on:
index d6afd440cf7b2b18d020f4ba25a49b862b98bcbe..d89816ad642fa0890dec4a35cada88bbd96b69c2 100644 (file)
@@ -925,10 +925,6 @@ extern int skb_checksum_help(struct sk_buff *skb, int inward);
 extern void            net_enable_timestamp(void);
 extern void            net_disable_timestamp(void);
 
-#ifdef CONFIG_SYSCTL
-extern char *net_sysctl_strdup(const char *s);
-#endif
-
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_DEV_H */
index b9fc59469956368dd3cfa323f0fd45e9fe7ae55b..93994c61309538a8847c84911c6d78ded396bcd7 100644 (file)
@@ -88,6 +88,8 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
 extern void * memchr(const void *,int,__kernel_size_t);
 #endif
 
+extern char *kstrdup(const char *s, int gfp);
+
 #ifdef __cplusplus
 }
 #endif
index 9117c23e3a01b9b885eb97f18c06efd79f677347..f8c4ef0aa35233aa71ffda5ce13f199145918e4b 100644 (file)
@@ -292,6 +292,7 @@ void *snd_hidden_kcalloc(size_t n, size_t size, int flags);
 void snd_hidden_kfree(const void *obj);
 void *snd_hidden_vmalloc(unsigned long size);
 void snd_hidden_vfree(void *obj);
+char *snd_hidden_kstrdup(const char *s, int flags);
 #define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
 #define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
 #define kfree(obj) snd_hidden_kfree(obj)
@@ -301,6 +302,7 @@ void snd_hidden_vfree(void *obj);
 #define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
 #define kfree_nocheck(obj) snd_wrapper_kfree(obj)
 #define vfree_nocheck(obj) snd_wrapper_vfree(obj)
+#define kstrdup(s, flags)  snd_hidden_kstrdup(s, flags)
 #else
 #define snd_memory_init() /*NOP*/
 #define snd_memory_done() /*NOP*/
@@ -311,7 +313,6 @@ void snd_hidden_vfree(void *obj);
 #define kfree_nocheck(obj) kfree(obj)
 #define vfree_nocheck(obj) vfree(obj)
 #endif
-char *snd_kmalloc_strdup(const char *string, int flags);
 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
 
index 93cbbbb39f42a783244e6bfaebfbd68f1f017e4c..122d031baab2f957bc73abdac853d4195ba78619 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -92,6 +92,7 @@
 #include       <linux/sysctl.h>
 #include       <linux/module.h>
 #include       <linux/rcupdate.h>
+#include       <linux/string.h>
 
 #include       <asm/uaccess.h>
 #include       <asm/cacheflush.h>
@@ -3082,3 +3083,26 @@ unsigned int ksize(const void *objp)
 
        return size;
 }
+
+
+/*
+ * kstrdup - allocate space for and copy an existing string
+ *
+ * @s: the string to duplicate
+ * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+ */
+char *kstrdup(const char *s, int gfp)
+{
+       size_t len;
+       char *buf;
+
+       if (!s)
+               return NULL;
+
+       len = strlen(s) + 1;
+       buf = kmalloc(len, gfp);
+       if (buf)
+               memcpy(buf, s, len);
+       return buf;
+}
+EXPORT_SYMBOL(kstrdup);
index f6bdcad47da6451a9603db531d626077fa946e6d..851eb927ed971da078035beca4caa77c1a406c78 100644 (file)
@@ -32,6 +32,7 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
+#include <linux/string.h>
 
 #define NEIGH_DEBUG 1
 
@@ -2592,7 +2593,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
                t->neigh_vars[17].extra1 = dev;
        }
 
-       dev_name = net_sysctl_strdup(dev_name_source);
+       dev_name = kstrdup(dev_name_source, GFP_KERNEL);
        if (!dev_name) {
                err = -ENOBUFS;
                goto free;
index c8be646cb1911e30c9c607f5f64d5a8b1f859b23..880a88815211e88f8310034879492d3beb16d0a4 100644 (file)
@@ -35,19 +35,6 @@ extern int sysctl_somaxconn;
 extern char sysctl_divert_version[];
 #endif /* CONFIG_NET_DIVERT */
 
-/*
- * This strdup() is used for creating copies of network 
- * device names to be handed over to sysctl.
- */
-char *net_sysctl_strdup(const char *s)
-{
-       char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
-       if (rv)
-               strcpy(rv, s);
-       return rv;
-}
-
 ctl_table core_table[] = {
 #ifdef CONFIG_NET
        {
@@ -177,6 +164,4 @@ ctl_table core_table[] = {
        { .ctl_name = 0 }
 };
 
-EXPORT_SYMBOL(net_sysctl_strdup);
-
 #endif
index 650dcb12d9a15318ef49c889fffc7a0867b0fb5e..d8a10e3dd77d2090d3729ef39a41633bbe8fbda9 100644 (file)
@@ -1471,7 +1471,7 @@ static void devinet_sysctl_register(struct in_device *in_dev,
         * by sysctl and we wouldn't want anyone to change it under our feet
         * (see SIOCSIFNAME).
         */     
-       dev_name = net_sysctl_strdup(dev_name);
+       dev_name = kstrdup(dev_name, GFP_KERNEL);
        if (!dev_name)
            goto free;
 
index 14f5c53235fe664f71d18fca9fe0c84cf3edc2e0..a54d4ef3fd35f2c7400762aa4dd87abd2f221e31 100644 (file)
@@ -57,6 +57,7 @@
 #endif
 #include <linux/delay.h>
 #include <linux/notifier.h>
+#include <linux/string.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
@@ -3437,7 +3438,7 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
         * by sysctl and we wouldn't want anyone to change it under our feet
         * (see SIOCSIFNAME).
         */     
-       dev_name = net_sysctl_strdup(dev_name);
+       dev_name = kstrdup(dev_name, GFP_KERNEL);
        if (!dev_name)
            goto free;
 
index 2b99b4028d31d442f9fb71b5e6bf19e815bb87cf..d6baf6fdf8a97d43f8569d9fef0bc762ebc616b9 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/err.h>
 #include <linux/seq_file.h>
 #include <linux/hash.h>
+#include <linux/string.h>
 
 #define RPCDBG_FACILITY        RPCDBG_AUTH
 
  */
 
 
-static char *strdup(char *s)
-{
-       char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
-       if (rv)
-               strcpy(rv, s);
-       return rv;
-}
-
 struct unix_domain {
        struct auth_domain      h;
        int     addr_changes;
@@ -55,7 +48,7 @@ struct auth_domain *unix_domain_find(char *name)
        if (new == NULL)
                return NULL;
        cache_init(&new->h.h);
-       new->h.name = strdup(name);
+       new->h.name = kstrdup(name, GFP_KERNEL);
        new->h.flavour = RPC_AUTH_UNIX;
        new->addr_changes = 0;
        new->h.h.expiry_time = NEVER;
index 31faffe01cb0fde0a4c73834cb69ad2c464954dc..5e122bbe7c927846afd4820fa5fc72d7366095f8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/vmalloc.h>
 #include <linux/time.h>
 #include <linux/smp_lock.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
@@ -754,7 +755,7 @@ static snd_info_entry_t *snd_info_create_entry(const char *name)
        entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);
        if (entry == NULL)
                return NULL;
-       entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);
+       entry->name = kstrdup(name, GFP_KERNEL);
        if (entry->name == NULL) {
                kfree(entry);
                return NULL;
index f9e4ce4434543598ee4f1b898375b3999fa008b8..12107968d4026fd8102ee0305d9260655511a7db 100644 (file)
@@ -22,6 +22,7 @@
 #include <sound/driver.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
@@ -51,7 +52,7 @@ int snd_oss_info_register(int dev, int num, char *string)
                        x = NULL;
                }
        } else {
-               x = snd_kmalloc_strdup(string, GFP_KERNEL);
+               x = kstrdup(string, GFP_KERNEL);
                if (x == NULL) {
                        up(&strings);
                        return -ENOMEM;
index 20860fec936440c4918d63839cf3b3c8981cfb85..c1fb28e8433076c37de10c07adb2675b23c0f7a3 100644 (file)
@@ -184,6 +184,20 @@ void snd_hidden_vfree(void *obj)
        snd_wrapper_vfree(obj);
 }
 
+char *snd_hidden_kstrdup(const char *s, int flags)
+{
+       int len;
+       char *buf;
+
+       if (!s) return NULL;
+
+       len = strlen(s) + 1;
+       buf = _snd_kmalloc(len, flags);
+       if (buf)
+               memcpy(buf, s, len);
+       return buf;
+}
+
 static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
 {
        snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
@@ -214,35 +228,8 @@ int __exit snd_memory_info_done(void)
        return 0;
 }
 
-#else
-
-#define _snd_kmalloc kmalloc
-
 #endif /* CONFIG_SND_DEBUG_MEMORY */
 
-/**
- * snd_kmalloc_strdup - copy the string
- * @string: the original string
- * @flags: allocation conditions, GFP_XXX
- *
- * Allocates a memory chunk via kmalloc() and copies the string to it.
- *
- * Returns the pointer, or NULL if no enoguh memory.
- */
-char *snd_kmalloc_strdup(const char *string, int flags)
-{
-       size_t len;
-       char *ptr;
-
-       if (!string)
-               return NULL;
-       len = strlen(string) + 1;
-       ptr = _snd_kmalloc(len, flags);
-       if (ptr)
-               memcpy(ptr, string, len);
-       return ptr;
-}
-
 /**
  * copy_to_user_fromio - copy data from mmio-space to user-space
  * @dst: the destination pointer on user-space
index 98ed9a9f0da65f503c9e5a08602d51c764500929..98fc0766f8853731757105c534556e27712e1e8f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/control.h>
@@ -1137,7 +1138,7 @@ static void snd_mixer_oss_proc_write(snd_info_entry_t *entry,
                        goto __unlock;
                }
                tbl->oss_id = ch;
-               tbl->name = snd_kmalloc_strdup(str, GFP_KERNEL);
+               tbl->name = kstrdup(str, GFP_KERNEL);
                if (! tbl->name) {
                        kfree(tbl);
                        goto __unlock;
index cab30977e7c0887603abacd05218894857176463..de7444c586f977e363833320cf7aa27d594c219d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/pcm.h>
@@ -2360,7 +2361,7 @@ static void snd_pcm_oss_proc_write(snd_info_entry_t *entry,
                                        for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next);
                                        setup1->next = setup;
                                }
-                               template.task_name = snd_kmalloc_strdup(task_name, GFP_KERNEL);
+                               template.task_name = kstrdup(task_name, GFP_KERNEL);
                        } else {
                                buffer->error = -ENOMEM;
                        }
index 0815fadeb3ec7915e6b0c31add6cece70073c9dd..7612884f530b17abfe554a867e55309b45a2a815 100644 (file)
@@ -399,8 +399,8 @@ EXPORT_SYMBOL(snd_hidden_kcalloc);
 EXPORT_SYMBOL(snd_hidden_kfree);
 EXPORT_SYMBOL(snd_hidden_vmalloc);
 EXPORT_SYMBOL(snd_hidden_vfree);
+EXPORT_SYMBOL(snd_hidden_kstrdup);
 #endif
-EXPORT_SYMBOL(snd_kmalloc_strdup);
 EXPORT_SYMBOL(copy_to_user_fromio);
 EXPORT_SYMBOL(copy_from_user_toio);
   /* init.c */
index b498e5482d77d8d40ce20eb1ed08c3e856e49708..cfaccd415b3b918cedc9cbdc6a9d4c89dd0a0861 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 #include <sound/control.h>
@@ -100,7 +101,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti
        timeri = kcalloc(1, sizeof(*timeri), GFP_KERNEL);
        if (timeri == NULL)
                return NULL;
-       timeri->owner = snd_kmalloc_strdup(owner, GFP_KERNEL);
+       timeri->owner = kstrdup(owner, GFP_KERNEL);
        if (! timeri->owner) {
                kfree(timeri);
                return NULL;
index 609838e8ef6727162c8b8b941c0c346e38667cd4..5eb766dd564bf60918f12aa25b814dfc2ea84154 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <sound/driver.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/info.h>
@@ -213,7 +214,7 @@ snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
        if (share_id != NULL)
                memcpy(&block.share_id, share_id, sizeof(block.share_id));
        block.owner = owner;
-       block.name = snd_kmalloc_strdup(name, GFP_KERNEL);
+       block.name = kstrdup(name, GFP_KERNEL);
        nblock = snd_gf1_mem_xalloc(alloc, &block);
        snd_gf1_mem_lock(alloc, 1);
        return nblock;
@@ -253,13 +254,13 @@ int snd_gf1_mem_init(snd_gus_card_t * gus)
        if (gus->gf1.enh_mode) {
                block.ptr = 0;
                block.size = 1024;
-               block.name = snd_kmalloc_strdup("InterWave LFOs", GFP_KERNEL);
+               block.name = kstrdup("InterWave LFOs", GFP_KERNEL);
                if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
                        return -ENOMEM;
        }
        block.ptr = gus->gf1.default_voice_address;
        block.size = 4;
-       block.name = snd_kmalloc_strdup("Voice default (NULL's)", GFP_KERNEL);
+       block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL);
        if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
                return -ENOMEM;
 #ifdef CONFIG_SND_DEBUG
index 9edd558d6bd34359ce03714598d0de14c384f117..bab89843d850be582cadf6ddc181a4f5d1f33f68 100644 (file)
@@ -1781,7 +1781,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
 
        knew = &spec->kctl_alloc[spec->num_kctl_used];
        *knew = alc880_control_templates[type];
-       knew->name = snd_kmalloc_strdup(name, GFP_KERNEL);
+       knew->name = kstrdup(name, GFP_KERNEL);
        if (! knew->name)
                return -ENOMEM;
        knew->private_value = val;
index 16f3b461627ab80fa1194649af6744dba1c1fd20..60d0b2c6669848a79f4c83653918b84e40cf277e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/emux_synth.h>
 #include <linux/init.h>
@@ -76,7 +77,7 @@ int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name)
        snd_assert(name != NULL, return -EINVAL);
 
        emu->card = card;
-       emu->name = snd_kmalloc_strdup(name, GFP_KERNEL);
+       emu->name = kstrdup(name, GFP_KERNEL);
        emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL);
        if (emu->voices == NULL)
                return -ENOMEM;