通用块层相关数据结构
2011-01-31 23:47
218 查看
1.4.2 通用块层相关数据结构
好了,通用块层的一些比较重要的基础知识大家都知道了,下面我们着重来看bio这个东西。大家在前面“创建一个bio请求”一节中已经见过这个结构了,但是,由于它太重要了,所以我们这里有必要对它进行进一步的介绍。每个bio结构都包含一个磁盘存储区标识符(存储区中的起始扇区号和扇区数目)和一个或多个描述与I/O操作相关的内存区的段。bio由bio数据结构描述:
struct bio { sector_t bi_sector; //块I/O操作的第一个磁盘扇区 struct bio *bi_next; //链接到请求队列中的下一个bio struct block_device *bi_bdev;//指向块设备描述符的指针 unsigned long bi_flags; //bio的状态标志 unsigned long bi_rw; //IO操作标志,即这次I.O是读或写 unsigned short bi_vcnt; /* bio的bio_vec数组中段的数目 */ unsigned short bi_idx; /* bio的bio_vec数组中段的当前索引值 */ unsigned short bi_phys_segments; //合并之后bio中物理段的数目 unsigned short bi_hw_segments; //合并之后硬件段的数目 unsigned int bi_size; /* 需要传送的字节数 */ unsigned int bi_hw_front_size;// 硬件段合并算法使用 unsigned int bi_hw_back_size;// 硬件段合并算法使用 unsigned int bi_max_vecs; /* bio的bio vec数组中允许的最大段数 */ struct bio_vec *bi_io_vec; /*指向bio的bio_vec数组中的段的指针 */ bio_end_io_t *bi_end_io; /* bio的I/O操作结束时调用的方法 */ atomic_t bi_cnt; /* bio的引用计数器 */ void *bi_private; //通用块层和块设备驱动程序的I/O完成方法使用的指针 bio_destructor_t *bi_destructor;//释放bio时调用的析构方法(通常是bio_destructor()方法)r }; |
另外,回忆一下,在do_mpage_readpage中bio的bdev来自buffer_head的b_bdev字段;bi_destructor被设置为bio_fs_destructor函数,作为当bio上的I/O操作完成时所执行的完成程序的地址;bi_io_vec通过bvec_alloc_bs函数初始化成数组,表示若干个bio待传输的段;同时bi_flags和bi_max_vecs字段也被设置了。另外min_t(int, nr_pages, bio_get_nr_vecs(bdev))表示这个bio中的iovec个数。所以,这里我们就来好好说道说道这个bio_vec数组。
bio中的每个段是由一个bio_vec数据结构描述的,bio中的bi_io_vec字段指向bio_vec数据结构的第一个元素,bi_vcnt字段则存放了bio_vec数组中当前的元素个数。
struct bio_vec { struct page *bv_page; //指向段的页框对应页描述符的指针 unsigned int bv_len; //段的字节长度 unsigned int bv_offset; //页框中段数据的偏移量 }; |
而这个min_t(int, nr_pages, bio_get_nr_vecs(bdev))这么一长串是什么呢?大家可以回过头去看看do_mpage_readpage函数:nr_pages是mpage_readpage传递给他的,其值是1;所以我们不用去管bio_get_nr_vecs的值了,min_t(int, nr_pages, bio_get_nr_vecs(bdev))这么一长串就是1,表示bio就只有一个iovec结构。什么意思?其实iovec结构是代表一个段,用于启动一次分散-聚集DMA传送,存放磁盘控制器所需的内存区的描述符链表的一项,包含一个地址和一个长度。
所以,对于普通文件,假设没有遇到文件的洞,那么一个页面所包含的4个块总是连续的,mpage_alloc调用的bio_alloc_bioset函数就只分配一个bio_vec结构。随后do_mpage_readpage通过调用bio_add_page将这个结构的bv_page指向对于的页描述符,bv_len设置为4个块的大小4096字节,bv_offset为0。bio_add_page还有一些合并段的工作,即不同的段在RAM中相应的页框正好是连续的并且在磁盘上相应的数据块也是相邻的,那么就合并它们。这些内容都比较绕脑子,有兴趣的同学可以去尝试深入分析一下。我们这里就假设一个页中4个块都是连续的,所以在bio_add_page函数的最后一行,把4个块的大小4096赋值给bio的bi_size字段。
相关文章推荐
- 通用块层相关数据结构
- 链表相关的算法题大汇总 — 数据结构之链表奇思妙想
- Linux0.11内核--进程相关数据结构
- 文件相关内核数据结构
- 数据结构——顺序表的相关操作
- 【数据结构与算法】深入浅出递归和迭代的通用转换思想
- SEH相关数据结构
- linux路由内核实现分析(二)---FIB相关数据结构
- Decal SDL-Delphi的范型类库-通用数据结构与算法类库(一)
- 扁平状数据链接成树状结构的通用方法
- 【数据结构与算法】B tree 即相关操作 深入解读
- Linux0.11内核--进程相关数据结构
- libevent2.0源码学习二:通用数据结构
- linux uart驱动——相关数据结构以及API(二)
- 数据结构课程设计,五种结构的相关操作和应用
- SQL Server2000 索引结构及其使用 (实现小数据量和海量数据的通用分页显示存储过程)
- 10. 数据结构进阶十排序相关概念
- 链表相关的算法题大汇总 — 数据结构之链表奇思妙想
- 文件系统-- 虚拟文件系统相关数据结构
- 数据结构实验2-2:单链表及其相关操作