Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


*(current->bio_tail) = bio;
bio->bi_next = NULL;
current->bio_tail = &bio->bi_next;
return;
}

do {
current->bio_list = bio->bi_next;
if (bio->bi_next == NULL)
current->bio_tail = ¤t->bio_list;
else
bio->bi_next = NULL;
__generic_make_request(bio);
bio = current->bio_list;
} while (bio);
current->bio_tail = NULL; /* deactivate */
}

The method is simple, yet creative. Figure 6-17 shows how the data structures evolve over time.

bio_list
bio_tail
current

bio_list
bio_tail

Bio 1

(a) (b)

(c) (d)

Bio 1
bio_list
bio_tail
current

bio

bi_next

bi_next bi_next bi_next
Bio 2

bi_next
Bio 3

bi_next
Bio 4

bi_next
Bio 1 Bio 2

bio bio

bio

bi_next

bio_list
bio_tail

Bio 2

bi_next
Bio 1

current

Figure 6-17: BIO lists evolving under recursive calls togeneric_make_request.

current->bio_tailis initialized toNULL, so we can skip the first conditional block. Onebioinstance
is submitted, and the data structures look as in Figure 6-17(a).biopoints to the submitted BIO, while
current->bio_listisNULLandcurrent_bio_tailpoint to the address ofcurrent_bio_tail.Notethat
the following pictures in the figure will always consider the localbiovariable of the first function call to
generic_make_request— not any variables in later stack frames.

Now suppose that__generic_make_requestdoes recursively callgeneric_make_requestto submit
aBIOinstance, which we call BIO 2. How do the data structures look when__generic_make_request
returns? Consider the action of the recursive call: Sincecurrent->bio_tailis not aNULLpointer any-
more, the initialif-block ingeneric_make_requestis processed.current->bio_listthen points to
the second BIO, andcurrent->bio_tailpoints at the address of thebi_nextofBIO2.Thusthedata
structure looks as in Figure 6-17(b) when__generic_make_requestreturns.
Free download pdf