LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (http://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Why does the value of ret change out of nowhere in do_sync_read? (http://www.linuxquestions.org/questions/linux-kernel-70/why-does-the-value-of-ret-change-out-of-nowhere-in-do_sync_read-878849/)

eantoranz 05-04-2011 04:18 PM

Why does the value of ret change out of nowhere in do_sync_read?
 
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



All times are GMT -5. The time now is 12:14 AM.