I am writing a custom block driver in the Linux kernel and in my make_request routine, on writes I need to read the data of the bio's specified sector (from the physical drive) prior to writing the new data. My excerpt below showcases most of what I am trying to accomplish but for whatever reason, I never get a return from the wait_for_completion. Once I/O is executed to the block device. It hangs after the submit_bio and never continues. Every 120 seconds I get a stack dump and message saying how the task is blocked. Any ideas? Thoughts?
... in make_request ....
if(rw != READ){
struct completion event;
struct bio *biow = bio_alloc(GFP_NOIO, bio_segments(bio));
biow->bi_bdev = bio->bi_bdev;
biow->bi_sector = bio->sector;
biow->bi_rw = READ_SYNC;
biow->bi_vcnt = bio_segments(bio);
biow->bi_size = bio->bi_size;
init_completion(&event);
biow->bi_private = &event;
biow->bi_end_io = bi_complete;
submit_bio(READ_SYNC, biow);
wait_for_completion(&event);
.... some more magic occurs here ....
}
generic_make_request(bio);
Maybe you can create a kernel thread, and do reading/writing ops in the thread. Really, I don't know why it works, I refer to relevant examples and try to do it, and find that it works.
To explain more clearly, I write the example as below:
static void trigger_some_event()
{
struct task_struct *task;
task = kthread_create(<your_func>, <arg>, "<desc>");
if(task){
wake_up_process(task);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With