Use kref.
[cascardo/kernel/samples/hello2/.git] / hello.c
diff --git a/hello.c b/hello.c
index f5d9670..bcf8de0 100644 (file)
--- a/hello.c
+++ b/hello.c
@@ -22,6 +22,7 @@
 #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>");
@@ -29,29 +30,42 @@ MODULE_DESCRIPTION("Hello, world");
 
 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);