如何将节点添加到内核链表

时间:2013-07-29 21:59:01

标签: struct linked-list kernel

我有一个结构:

struct test
{
   int a;
   struct* page p;
   struct list_head l;
};

我已查看include/linux/list.h,但我不确定应该如何添加到我的列表中。我所做的是:

test* node_1 = (struct test*)malloc(sizeof(test));
node_1->a = 10;
node_1->p = alloc_page();
LIST_HEAD(node_1->l);
// for the rest nodes
test* node_2 = (struct test*)malloc(sizeof(test));
node_2->a = 20;
node_2->p = alloc_page();
//can I use list_add or should I write a custom add? 
list_add(node_2,node_1); //???

为了添加每个节点,list_add的第二个参数应该是node_1

1 个答案:

答案 0 :(得分:1)

@Sweet,我使用内核暴露列表开发了一个小内核模块如下所示,如果您有任何疑问或反馈,请通过并回复我。

void todo_add_entry(struct todo_struct *new)
{
#ifdef QUEUE
    list_add_tail(&new->list, &first.list);
#else
    list_add(&new->list, &first.list);
#endif    
}

void todo_del_entry(struct todo_struct *new)
{
    struct todo_struct *str, *temp;

    list_for_each_entry_safe(str, temp, &first.list, list)
    {
        if((str->priority == new->priority) && (str->name == new->name))
        {
            list_del(&str->list);
#ifdef DEBUG            
            dmsg("Same:%d \t %d\n", str->priority, new->priority);          
#endif          

            kfree(str);
        }
    }       
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
static long 
list_minor_ioctl(struct file *filp, U32 cmd, unsigned long arg)
#else
static int 
list_minor_ioctl(struct inode *inode, struct file *filp, U32 cmd, 
                 unsigned long arg)
#endif
{
    S32 res = 0;
    S32 err = 0;
    struct todo_struct *new;
    struct test *a;

    if(_IOC_TYPE(cmd) != IOCTL_LIST_MAGIC)
        return -ENOTTY;

    if(_IOC_NR(cmd) > IOCTL_MAX_CMDS)
        return -ENOTTY;

    if(_IOC_DIR(cmd) & _IOC_READ)
        err = !access_ok(VERIFY_WRITE, (void __user*) arg, _IOC_SIZE(cmd));             

    if(_IOC_DIR(cmd) & _IOC_WRITE)
        err = !access_ok(VERIFY_READ, (void __user*) arg, _IOC_SIZE(cmd));              

    if(err)
        return -EFAULT;

    new = kmalloc(sizeof(*new), GFP_KERNEL);    

    a = (struct test *) arg;

    switch(cmd)
    {
    case IOCTL_LIST_ADD:

        new->priority = a->priority;
        new->name     = a->name;

        INIT_LIST_HEAD(&new->list);

        todo_add_entry(new);

        break;

    case IOCTL_LIST_DEL:
        new->priority = a->priority;
        new->name     = a->name;

#ifdef DEBUG        
        dmsg("prio:%d \t name:%s \n", new->priority, new->name);
#endif      

        todo_del_entry(new);    
        break;  

    default: /* Default case --> Ignore, will never get executed */
        break;  
    }

    return res; 
}