Use kref.
[cascardo/kernel/samples/hello2/.git] / hello.c
diff --git a/hello.c b/hello.c
index 8a5a20b..bcf8de0 100644 (file)
--- a/hello.c
+++ b/hello.c
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/kref.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>");
 MODULE_DESCRIPTION("Hello, world");
 
-static int size = 1;
-module_param_named(size, size, int, S_IRUGO | S_IWUSR);
-
 struct hello {
        int times;
+       struct kref ref;
        char greeting[0];
 };
 
-static struct hello *hello;
+static struct hello *global_hello;
 
 static char default_greeting[] = "Hello, world!\n";
 
+static void hello_release(struct kref *ref)
+{
+       struct hello *hello = container_of(ref, struct hello, ref);
+       printk(KERN_DEBUG "releasing hello\n");
+       kfree(hello);
+}
+
 static int hello_init(void)
 {
+       static struct hello *hello;
        hello = kmalloc(sizeof(*hello) + sizeof(default_greeting), GFP_KERNEL);
        if (!hello)
                return -ENOMEM;
+       kref_init(&hello->ref);
+       kref_get(&hello->ref);
+       global_hello = hello;
        memcpy(hello->greeting, default_greeting, sizeof(default_greeting));
        printk("%s\n", hello->greeting);
        printk("%p %p %p\n", hello, hello->greeting,
                container_of(&hello->greeting, struct hello, greeting));
        printk("size %d\n", ARRAY_SIZE(default_greeting));
+       kref_put(&hello->ref, hello_release);
        return 0;
 }
 
 static __exit void hello_exit(void)
 {
-       kfree(hello);
+       kref_put(&global_hello->ref, hello_release);
 }
 
 module_init(hello_init);