struct buffer_head {

unsigned long b_state; /*

struct buffer_head *b_this_page;/* struct page *b_page; /*

sector_t b_blocknr; /*

struct block_device *b_bdev; bh_end_io_t *b_end_io; /*

Buffers, like pages, can have many states. The current state of a buffer head is held in the b_state element that accepts the following selection of values (the full list of values is available as an enum called bh_state_bits in include/linux/buffer_heads.h):

□ The state is BH_Uptodate if the current data in the buffer match the data in the backing store.

□ Buffers are labeled as BH_Dirty if their data have been modified and no longer match the data in the backing store.

□ BH_Lock indicates that the buffer is locked for further access. Buffers are explicitly locked during I/O operations to prevent several threads from handling the buffers concurrently and thus interfering with each other.

□ BH_Mapped means that there is a mapping of the buffer contents on a secondary storage device, as is the case with all buffers that originate from filesystems or from direct accesses to block devices.

□ BH_New marks newly created buffers as new.

buffer state bitmap (see above) */ circular list of page's buffers */ the page this bh is mapped to */

start block number */

size of mapping */

pointer to data within the page */

users using this buffer_head */

b_state is interpreted as a bitmap. Every possible constant stands for a position in the bitmap. As a result, several values (BK_Lock and BH_Mapped, e.g.) can be active at the same time — as also at many other points in the kernel.

BH_uptodate and BH_Dirty can also be active at the same time, and this is often the case. Whereas BH_uptodate is set after a buffer has been filled with data from the block device, the kernel uses BH_Dirty to indicate that the data in memory have been modified but not yet been written back. This may appear to be confusing but must be remembered when considering the information below.

Besides the above constants, a few additional values are defined in enum bh_state_bits. They are ignored because they are either of little importance or are simply no longer used. They are retained in the kernel sources for historical reasons and will disappear sooner or later.

The kernel defines the set_buffer_foo and get_buffer_foo functions to set and read the buffer state bits for BH_Foo.

The buffer_head structure also includes further elements whose meanings are given below:

□ b_count implements the usual access counter to prevent the kernel from freeing buffer heads that are still in active use.

□ b_page holds a pointer to a page instance with which the buffer head is associated when used in conjunction with the page cache. If the buffer is independent, b_page contains a null pointer.

□ As discussed above, several buffers are used to split the contents of a page into smaller units. All buffer heads belonging to these units are kept on a singly linked, circular list using b_this_page (the entry for the last buffer points to the entry for the first buffer to create a circular structure).

□ b_blocknr holds the number of the block on the underlying block device, and b_size specifies the size of the block. b_bdev is a pointer to the block_device instance of the block device. This information uniquely identifies the source of the data.

□ The pointer to the data in memory is held in b_data (the end position can be calculated from b_size; there is therefore no need for an explicit pointer to this position, although a pointer was used above for the sake of simplicity).

□ b_end_io points to a routine that is automatically invoked by the kernel when an I/O operation involving the buffer is completed (it is required by the BIO routines described in Chapter 6). This enables the kernel to postpone further buffer handling until a desired input or output operation has, in fact, been completed.

□ b_private is a pointer reserved for private use by b_end_io. It is used primarily by journaling filesystems. It is usually set to null if it is not needed.

Continue reading here: Operations

Was this article helpful?

0 0