Hi!
I'm having some fun creating a linux block device driver. This device driver will have to read from files and so I've been trying to solve all the problems involved. While doing my research I've hit a very weird behavior in a function defined in
fs/read_write.c. It's
do_sync_read. I have added some debug messages to it on my UML kernel (the one I'm developing my device driver on) to check all vaules involved while running the function cause I was getting a -EFAULT when I ran vfs_read. Following the functions involved I arrived at do_sync_read.
If you take a look at the function, you will see that there is one _seemingly_ endless for, then a check, then change of the ppos variable and finally a return of ret.
I have found that there is only one cycle of the for run, because there is a break that is hit if everything is OK inside the for.
First, ret is assigned like this:
Code:
ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
After this point, the value of the variable ret is set to 0 meaning the operation ran normally (or so I like to think).
Then there is a check that is evaluated to true which means that
ret != -EIOCBRETRY, great... but before I call
break I print again the value of ret and now the value has been changed to -14 (-EFAULT). Why is that happening? Cause I dont see anything that could be going on that could be changing the value of ret from 0 to -14 between those two points.
Code:
for (;;) {
ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
if (filp == debugFile) printk (KERN_NOTICE "Con la posicion %d resultado fue %d\n", kiocb.ki_pos, ret);
if (ret != -EIOCBRETRY) {
if (filp == debugFile) printk (KERN_NOTICE "Saliendo del ciclo con ret valiendo %d\n", ret);
break;
}
wait_on_retry_sync_kiocb(&kiocb);
}
Output:
Code:
Con la posicion 2000 resultado fue 0
Saliendo del ciclo con ret valiendo -14