Sync_request is not necessarily the case. You can call other functions.
Submit_bio
// Bio and bio_vec are local variables.
Static intSync_request
(Struct page * page, struct block_device * bdev, int rw)
{
Struct bio;
Struct bio_vec;
Struct completion complete;
Bio_init (& bio );
Bio. bi_io_vec = & bio_vec;
Bio_vec.bv_page = page; // transmits the entire page
Bio_vec.bv_len = PAGE_SIZE;
Bio_vec.bv_offset = 0;
Bio. bi_vcnt = 1; // A bio_vec
Bio. bi_idx = 0; // The current value is 0.
Bio. bi_size = PAGE_SIZE;
Bio. bi_bdev = bdev;
Bio. bi_sector = page-> index * (PAGE_SIZE> 9); // how is this calculated?
Init_completion (& complete );
Bio. bi_private = & complete;
Bio. bi_end_io = request_complete;
Submit_bio (rw, & bio); // submit
Generic_unplug_device (bdev_get_queue (bdev ));
Wait_for_completion (& complete); // wait for completion
Return test_bit (BIO_UPTODATE, & bio. bi_flags )? 0:-EIO;
}
VoidSubmit_bio
(Int rw, struct bio * bio)
{
Int count = bio_sectors (bio); // converts it to the number of sector, in the unit of 512B
...
...
Generic_make_request (bio );
}
/*
* We only want one-> make_request_fn to be active at a time,
* Else stack usage with stacked devices cocould be a problem.
* So use current-> bio_list to keep a list of requests
* Submited by a make_request_fn function.
* Current-> bio_list is also used as a flag to say if
* Generic_make_request is currently active in this task or not.
* If it is NULL, then no make_request is active. If it is non-NULL,
* Then a make_request is active, and new requests shocould be added
* At the tail
*/
VoidGeneric_make_request
(Struct bio * bio)
{
Struct bio_list bio_list_on_stack;
If (current-> bio_list ){
/* Make_request is active */
Bio_list_add (current-> bio_list, bio );
Return;
}
/* Following loop may be a bit non-obvious, and so deserves some
* Explanation.
* Before entering the loop, bio-> bi_next is null (as all callers
* Ensure that) So we have a list with a single bio.
* We pretend that we have just taken it off a longer list, so
* We assign bio_list to a pointer to the bio_list_on_stack,
* Thus initialising the bio_list of New BIOS to be
* Added. _ generic_make_request may indeed add some more BIOS
* Through a recursive call to generic_make_request. If it
* Did, we find a non-null value in bio_list and re-enter the loop
* From the top. In this case we really did just take the bio
* Of the top of the list (No pretending) And so remove it from
* Bio_list, and call into _ generic_make_request again.
*
* The loop was structured like this to make only one call
* _ Generic_make_request (which is important as it is large and
* Inlined) and to keep the structure simple.
*/
BUG_ON (bio-> bi_next );
Bio_list_init (& bio_list_on_stack );
Current-> bio_list = & bio_list_on_stack;
Do {
_ Generic_make_request (bio );
Bio = bio_list_pop (current-> bio_list );
} While (bio );
Current-> bio_list = NULL;/* deactivate */
}
Static inline void_ Generic_make_request (
Struct bio * bio)
{
Struct request_queue * q;
Sector_t old_sector;
Int ret, nr_sectors = bio_sectors (bio );
Dev_t old_dev;
Int err =-EIO;
Might_sleep ();
If (bio_check_eod (bio, nr_sectors ))
Goto end_io;
/*
* Resolve the mapping until finished. (drivers are
* Still free to implement/resolve their own stacking
* By explicitly returning 0)
*
* NOTE: we don't repeat the blk_size check for each new device.
* Stacking drivers are expected to know what they are doing.
*/
Old_sector =-1;
Old_dev = 0;
Do {
Char B [BDEVNAME_SIZE];
Q = bdev_get_queue (bio-> bi_bdev );
If (unlikely (! Q )){
Printk (KERN_ERR
"Generic_make_request: Trying to access"
"Nonexistent block-device % s (% Lu)/n ",
Bdevname (bio-> bi_bdev, B ),
(Long) bio-> bi_sector );
Goto end_io;
}
If (unlikely (! (Bio-> bi_rw & REQ_DISCARD )&&
Nr_sectors> queue_max_hw_sectors (q ))){
Printk (KERN_ERR "bio too big device % s (% u> % u)/n ",
Bdevname (bio-> bi_bdev, B ),
Bio_sectors (bio ),
Queue_max_hw_sectors (q ));
Goto end_io;
}
If (unlikely (test_bit (QUEUE_FLAG_DEAD, & q-> queue_flags )))
Goto end_io;
If (should_fail_request (bio ))
Goto end_io;
/*
* If this device has partitions, remap block n
* Of partition p to block n + start (p) of the disk.
*/
Blk_partition_remap (bio );
If (bio_integrity_enabled (bio) & bio_integrity_prep (bio ))
Goto end_io;
If (old_sector! =-1)
Trace_block_remap (q, bio, old_dev, old_sector );
Old_sector = bio-> bi_sector;
Old_dev = bio-> bi_bdev-> bd_dev;
If (bio_check_eod (bio, nr_sectors ))
Goto end_io;
If (bio-> bi_rw & REQ_DISCARD )&&
(! Blk_queue_discard (q) |
(Bio-> bi_rw & req_secure )&&
! Blk_queue_secdiscard (q )))){
Err =-eopnotsupp;
Goto end_io;
}
Trace_block_bio_queue (Q, bio );
Ret = Q->Make_request_fn
(Q, bio); // this should be the registered request function.
} While (RET );
Return;
End_io:
Bio_endio (Bio, err );
}