Skip to content

Commit

Permalink
kernel:module: add radix-tree example
Browse files Browse the repository at this point in the history
  • Loading branch information
jouyouyun committed Jan 9, 2021
1 parent 46b49b9 commit c91dde4
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 0 deletions.
11 changes: 11 additions & 0 deletions kernel/modules/radix-tree/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
obj-m := radix_tree.o
ccflags-y := -std=gnu99 -Wno-declaration-after-statement -O3
cwd := $(shell pwd)

kdir := /lib/modules/$(shell uname -r)/build

all:
make -C ${kdir} M=${cwd} modules

clean:
make -C ${kdir} M=${cwd} clean
131 changes: 131 additions & 0 deletions kernel/modules/radix-tree/radix_tree.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* Copyright (C) 2021 jouyouyun <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* radix_tree.c -- kernel radix-tree example
*
* Written on 星期一, 4 一月 2021.
*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/radix-tree.h>

#define FLAG_R 1 << 0
#define FLAG_W 1 << 1
#define FLAG_D 1 << 2

struct file_node {
unsigned long id;
unsigned int flag;
char *file;
};

#define MOD_NAME "radix_tree"
#define DEFAULT_FLAG (FLAG_R | FLAG_W)

static char *_files[] = {
"/opt/dlp/data/wps/file1.doc",
"/opt/dlp/data/wpa/config.ini",
NULL,
};

static unsigned long id_list[2] = {0};

RADIX_TREE(_root, 0);

static struct file_node *make_file_node(const char *file, const int flag)
{
static size_t node_len = sizeof(struct file_node);
int len = strlen(file);
struct file_node *node = kzalloc(node_len, GFP_KERNEL);

if (unlikely(node == NULL))
return NULL;

node->file = kzalloc(len+1, GFP_KERNEL);
if (unlikely(node->file == NULL))
goto free;

node->id = (unsigned long)node;
node->flag = flag;
memcpy(node->file, file, len);

return node;
free:
kfree(node);
return NULL;
}

static void free_file_node(struct file_node *node)
{
kfree(node->file);
kfree(node);
}

static void lookup_file_node(unsigned long id)
{
struct file_node *node = NULL;

node = (struct file_node *)radix_tree_lookup(&_root, id);
if (unlikely(node == NULL)) {
printk("[%s] failed to lookup node: 0x%lx", MOD_NAME, id);
return;
}

printk("[%s] node value: id(0x%lx), flag(%u), file(%s)", MOD_NAME, node->id,
node->flag, node->file);
}

int __init mod_init(void) {
int i = 0;

printk("[%s] init", MOD_NAME);
while (_files[i] != NULL) {
struct file_node *node = make_file_node(_files[i], DEFAULT_FLAG);
if (unlikely(node == NULL)) {
printk("[%s] failed to make file_node for '%s'", MOD_NAME, _files[i]);
i++;
continue;
}

printk("[%s] insert node: 0x%lx", MOD_NAME, node->id);
radix_tree_insert(&_root, node->id, (void *)node);
id_list[i] = node->id;
i++;
}

lookup_file_node(id_list[1]);
lookup_file_node(12334);
return 0;
}

void __exit mod_exit(void)
{
void **node_ptr = NULL;
struct radix_tree_iter iter;

printk("[%s] exit", MOD_NAME);
radix_tree_for_each_slot(node_ptr, &_root, &iter, 0) {
struct file_node *node = (struct file_node*)(*node_ptr);
printk("[%s] iter node value: id(0x%lx), flag(%u), file(%s)", MOD_NAME, node->id,
node->flag, node->file);
radix_tree_delete(&_root, node->id);
free_file_node(node);
node = NULL;
}

printk("[%s] empty: %d", MOD_NAME, radix_tree_empty(&_root));
}

module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jouyouyun");
MODULE_DESCRIPTION("a kernel radix-tree example");
11 changes: 11 additions & 0 deletions kernel/modules/template/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
obj-m := template.o
ccflags-y := -std=gnu99 -Wno-declaration-after-statement -O3
cwd := $(shell pwd)

kdir := /lib/modules/$(shell uname -r)/build

all:
make -C ${kdir} M=${cwd} modules

clean:
make -C ${kdir} M=${cwd} clean
36 changes: 36 additions & 0 deletions kernel/modules/template/template.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (C) 2021 jouyouyun <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* template.c -- template
*
* Written on 星期一, 4 一月 2021.
*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>

#define MOD_NAME "template"

int __init mod_init(void)
{
printk("[%s] init", MOD_NAME);
return 0;
}

void __exit mod_exit(void)
{
printk("[%s] exit", MOD_NAME);
}

module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jouyouyun");
MODULE_DESCRIPTION("template");
73 changes: 73 additions & 0 deletions misc/struct_pointer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FLAG_R 1 << 0
#define FLAG_W 1 << 1
#define FLAG_D 1 << 2

struct foo1 {
unsigned long id;
unsigned int flag;
char *value;
};

static char *files[] = {
"/opt/dlp/data/app1/file1",
"/opt/dlp/data/app2/file1",
NULL,
};

#define DEFAULT_FLAG (FLAG_R|FLAG_W|FLAG_D)

static struct foo1 *make_foo1(const char *filename, unsigned int flag)
{
struct foo1 *ret = NULL;
int len = strlen(filename);

ret = calloc(1, sizeof(struct foo1));
if (!ret)
return NULL;

ret->value = calloc(len+1, sizeof(char));
if (!ret->value)
goto free;

ret->id = (unsigned long)ret;
memcpy(ret->value, filename, len);
ret->flag = flag;

return ret;
free:
free(ret);
return NULL;
}

static void free_foo1(struct foo1 *node)
{
free(node->value);
free(node);
node = NULL;
}

int main()
{
int i = 0;

while (files[i] != NULL) {
struct foo1 *node = make_foo1(files[i], DEFAULT_FLAG);
if (!node) {
printf("failed to make node for '%s'\n", files[i]);
i++;
continue;
}

printf("node addr: %p\n", node);
printf("node value: 0x%lx, %u, %s\n", node->id, node->flag, node->value);
free_foo1(node);
printf("node free success\n");
i++;
}

return 0;
}

0 comments on commit c91dde4

Please sign in to comment.