从内核列表中删除元素

时间:2014-01-28 18:32:29

标签: c list linux-kernel free

我正在从内核列表中删除每个元素并将其内容复制到用户缓冲区中(如果适合,则删除每个元素)。我正在做同步,所以我包括信号量,我做删除过程的方式是通过从同步模式列表中删除并将其插入另一个列表,然后我解锁代码并从新列表中删除。复制到字符串aux中的元素数量是正确的,但是当执行时(接近结束):

    printk(KERN_INFO "item->data: %d",item->data);

结果是:item-> data:111

这不应该发生,因为item->数据是一个随机数,因此删除会导致内存失败,但我不知道如何修复它,甚至不知道问题来自哪里。

list_item_t结构是这样的:

   typedef struct {
        int data;
        struct list_head links;
   }list_item_t;

我的清单声明是:

   struct list_head mylist = LIST_HEAD_INIT(mylist);

以下是产生问题的代码。

static ssize_t modtimer_read (struct file *file, char *user, size_t nbits, loff_t * offset){
    struct list_head* pos = mylist.next; // The position of the list
    struct list_head* auxpos; 
    struct list_head listaux = LIST_HEAD_INIT(listaux);
    list_item_t* item;
    char aux[MAX_BUFFER];
    char aux2[10];
    int total =0;
    int subt =0;
    int done = 0;


    printk(KERN_INFO "modtimer_read open"); 

    if (down_interruptible(&mtx)) /*Lock*/
        return -EINTR;

    while (done == 0){
        if(pos == pos->next || list_num_items == 0){
            done++;
        printk(KERN_INFO "Empty list");
        // Esperar
        }else{
            item = list_entry(pos, list_item_t, links); //gets the item in the 'pos' position
            subt=sprintf(aux2, "%d\n",item->data);
            auxpos = pos->next;
            if(subt + total > MAX_BUFFER )  {           
                done++;
                printk(KERN_INFO "string has maximum size");
            }else {
                total+= sprintf(&aux[total],"%i\n",item->data); //reads the data (integer)

                list_add_tail(&listaux,pos); //Added into the aux list                  
                list_del(pos);  //deleted from the list
                list_num_items--;   
            }
            subt = 0;
            pos = auxpos;
        }
    }
    aux[total] = '\0';
    up(&mtx);
    pos = listaux.next; 
    while(&listaux != listaux.next){
        item = list_entry(pos, list_item_t, links); //gets the item in the 'pos' position
        auxpos = pos->next;
        list_del(pos);

        printk(KERN_INFO "item->data: %d",item->data);

        vfree(item);
        pos = auxpos;
    }
    copy_to_user(user,aux,total);

    printk(KERN_INFO "modtimer_read cerrado");
    return total;
}

1 个答案:

答案 0 :(得分:0)

list_add_tail(&listaux,pos);

参数顺序错误:此行将列表项listaux添加到从标题pos开始的列表中。

请阅读documentation