Figure 168 Code flow diagram for the bufferrelated operations of blockwritefullpage

The writeback process is split into several parts, each of which repeatedly iterates over the singly linked list of buffers attached to a page.

As usual, it is first necessary to check that buffers are actually attached to the page — this cannot be taken for granted. As when a page is read, page_has_buffers is invoked to check whether buffers are present. If not, they are created using create_empty_buffers.

The kernel then iterates a total of three times over the list of buffers, as shown in the code flow diagram:

1. The purpose of the first iteration is to create a mapping between the buffer and the block device for all unmapped but dirty buffers. The function held in the get_block function pointer is invoked to find the matching block of the block device for the buffer.

2. In the second iteration, all dirty buffers are filtered out; this can be checked by test_clear_buffer_dirty — if the flag was set, it is deleted when the function is invoked because the buffer contents are due to be written back immedi-ately.13 mark_buffer_async_write sets the BH_Async_Write state bit and assigns end_buffer_async_write as the BIO completion handler to b_end_io.

At the end of this iteration, set_page_writeback sets the PG_writeback flag for the full page.

3. In the third and final iteration, all buffers marked with BH_Async_Write in the previous pass are forwarded to the block layer that performs the actual write operation by invoking submit_bh, which submits a corresponding request to the block layer (by means of BIOs; see Chapter 6).

When the write operation for a buffer terminates, end_buffer_async_write is invoked automatically to check whether this also applies for all other buffers of the page. If so, all processes that are sleeping on the queue associated with the page and that are waiting for this event are woken.

Continue reading here: Independent Buffers

Was this article helpful?

0 0