Eliminando elementos de la lista del kernel

I'm removing every element from a kernel list and copying it's content into the user buffer (removing every element if they fit). I am doing it synchrone, so i included semaphores, the way i do the removal process is by removing from the list in synchrone mode and inserting it into another list, then i unlock the code and delete from the new list. The quantity of elements copied into the string aux is right, but when is executed (is near of the end):

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

the result is ever: item->data: 111

That should not happen because the item->data is a random number, so the removal causes a memory fail, but i do not know how to fix it or even what the problem comes from.

The list_item_t structure is this:

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

My list declaration is:

   struct list_head mylist = LIST_HEAD_INIT(mylist);

Here is the code that generates problems.

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;
}

preguntado el 28 de enero de 14 a las 18:01

1 Respuestas

list_add_tail(&listaux,pos);

The parameter order is wrong: this line adds the list item listaux to the list that starts at the header pos.

Por favor lea el documentación.

Respondido el 30 de enero de 14 a las 08:01

So, what's your point? i add into an auxiliar list in order to remove later. The doc just says: "Insert a new entry before the specified head. This is useful for implementing queues." - Kaostias

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.