Eliminando elementos de la lista del kernel
Frecuentes
Visto 1,318 veces
0
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;
}
1 Respuestas
0
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
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c list linux-kernel free or haz tu propia pregunta.
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