nfsd: track last inode only in use_wgather case
[safe/jmp/linux-2.6] / kernel / params.c
index a1e3025..de273ec 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 
+/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
+#define KPARAM_KMALLOCED       0x80000000
+
 #if 0
 #define DEBUGP printk
 #else
@@ -217,7 +220,19 @@ int param_set_charp(const char *val, struct kernel_param *kp)
                return -ENOSPC;
        }
 
-       *(char **)kp->arg = (char *)val;
+       if (kp->perm & KPARAM_KMALLOCED)
+               kfree(*(char **)kp->arg);
+
+       /* This is a hack.  We can't need to strdup in early boot, and we
+        * don't need to; this mangled commandline is preserved. */
+       if (slab_is_available()) {
+               kp->perm |= KPARAM_KMALLOCED;
+               *(char **)kp->arg = kstrdup(val, GFP_KERNEL);
+               if (!kp->arg)
+                       return -ENOMEM;
+       } else
+               *(const char **)kp->arg = val;
+
        return 0;
 }
 
@@ -571,6 +586,15 @@ void module_param_sysfs_remove(struct module *mod)
 }
 #endif
 
+void destroy_params(const struct kernel_param *params, unsigned num)
+{
+       unsigned int i;
+
+       for (i = 0; i < num; i++)
+               if (params[i].perm & KPARAM_KMALLOCED)
+                       kfree(*(char **)params[i].arg);
+}
+
 static void __init kernel_add_sysfs_param(const char *name,
                                          struct kernel_param *kparam,
                                          unsigned int name_skip)