Linux Kernel - The Block I/O Layer

北慕城南 提交于 2020-03-11 17:56:49

固定大小的数据块称为块,常见块设备磁盘有硬盘,闪存等,随机访问,字符设备以序列数据流的方式访问,如键盘输入是一字节接一字节访问。由于块设备的复杂度,访问性能等原因,内核提供了一个子系统进行管理,即 Block I/O Layer。块设备最小可寻址单元称为扇区,扇区大小是一个设备的物理属性,大部分块设备为 512 B,CD-ROM 磁盘为 2KB。软件层面上的块是文件系统中的一个抽象概念,也是文件系统最小可逻辑寻址单元。尽管物理设备是以扇区来寻址,内核以块来执行磁盘操作。

 且


Buffers and Buffer Heads

struct buffer_head {
    unsigned long b_state; /* buffer state flags */
    struct buffer_head *b_this_page; /* list of page’s buffers */
    struct page *b_page; /* associated page */
    sector_t b_blocknr; /* starting block number */
    size_t b_size; /* size of mapping */
    char *b_data; /* pointer to data within the page */
    struct block_device *b_bdev; /* associated block device */
    bh_end_io_t *b_end_io; /* I/O completion */
    void *b_private; /* reserved for b_end_io */
    struct list_head b_assoc_buffers; /* associated mappings */
    struct address_space *b_assoc_map; /* associated address space */
    atomic_t b_count; /* use count */
};

buffer_head 的目的是用来描述 buffer-to-block (physical in-memory buffer and on-disk block)映射,由于 buffer_head 较大且数据操作不便(如一个 buffer_head 只能描述一个 buffer)的诸多缺点,2.6 kernel 以页和地址空间替换 buffer 来运作,2.5 kernel 引入 更轻量级的block I/O Operations(large block I/O operations (say, a write) → multiple buffer_head structures → space consumption).

struct bio {
	sector_t        bi_sector; /* associated sector on disk */
	struct bio  	*bi_next; /* list of requests */
	struct block_device *bi_bdev; /* associated block device */
	unsigned long 	bi_flags; /* status and command flags */
	unsigned long 	bi_rw; /* read or write? */
	unsigned short 	bi_vcnt; /* number of bio_vecs off */
	unsigned short 	bi_idx; /* current index in bi_io_vec */
	unsigned short 	bi_phys_segments; /* number of segments */
	unsigned int 	bi_size; /* I/O count */
	unsigned int 	bi_seg_front_size; /* size of first segment */
	unsigned int 	bi_seg_back_size; /* size of last segment */
	unsigned int 	bi_max_vecs; /* maximum bio_vecs possible */
	unsigned int 	bi_comp_cpu; /* completion CPU */
	atomic_t        bi_cnt; /* usage counter */
	struct bio_vec 	*bi_io_vec; /* bio_vec list */
	bio_end_io_t 	*bi_end_io; /* I/O completion method */
	void        	*bi_private; /* owner-private method */
	bio_destructor_t *bi_destructor; /* destructor method */
	struct bio_vec bi_inline_vecs[0]; /* inline bio vectors */
};

This structure represents block I/O operations that are in flight (active) as a list of segments.A segment is a chunk of a buffer that is contiguous in memory.Thus, individual buffers need not be contiguous in memory. By allowing the buffers to be described in chunks, the bio structure provides the capability for the kernel to perform block I/O operations of even a single buffer from multiple locations in memory.

The bi_io_vec field points to an array of bio_vec structures.These structures are used as lists of individual segments in this specific block I/O operation. Each bio_vec is treated as a vector of the form <page, offset, len>, which describes a specific segment: the physical page on which it lies, the location of the block as an offset into the page, and the length of the block starting from the given offset.The full array of these vectors describes the entire buffer.
 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!