块I/O层基本原理

本文深入探讨了Linux内核中块I/O层的基本原理,包括块设备、缓冲区管理、bio结构体及其作用。文章阐述了块设备的特性,如最小寻址单位为扇区,以及如何通过buffer_head结构体管理和映射磁盘块。同时,介绍了bio结构体用于表示块I/O请求,其中包含了多个内存片段。文章还讨论了I/O调度程序的重要性,如请求队列、request结构体和不同的I/O调度算法,如 Deadline 和 CFQ,旨在优化系统全局吞吐量并防止请求饥饿现象。
摘要由CSDN通过智能技术生成

作者:YouChuang

本文主要介绍学习块IO层的基本原理



    整体结构

    I/O设备

    * 基本概念
    

    “an input/output device is a hardware device that accepts inputted information and also has the capability of outputting that information.”
    常见的就是打印机、硬盘、软盘、光盘、键盘和鼠标
    分类字符设备和块设备
    区分方法:是不是能够随机的访问数据,字符设备是顺序访问,而块设备可以任意访问指定位置

    块设备
    块设备的最小可寻址单元是扇区,一般是512字节,大小是设备的物理属性,对于小于扇区的单元设备无法寻址
    块设备需要文件系统和块驱动来管理
    而为了上层的统一访问,文件系统把设备空间的最小逻辑可寻址单元设定为块,块肯定要大于扇区,不然物理上寻址不到,内核要求块的大小是扇区的2的整数倍,并且不能超过页的大小。

    * 缓冲区
    

    块由块设备调入内存时存储在缓冲区中,每个缓冲区和一个块对应
    缓冲区的描述符称为缓冲区头,由buffer_head结构体来描述,主要用来描述磁盘块和物理内存缓冲区之间的映射关系
    后来又引入了新的描述方式

    struct buffer_head {
    62 unsigned long b_state; /* buffer state bitmap (see above) */
    63 struct buffer_head b_this_page;/ circular list of page’s buffers */
    64 struct page b_page; / the page this bh is mapped to */
    65
    66 sector_t b_blocknr; /* start block number 起始块号 */
    67 size_t b_size; /* size of mapping */
    68 char b_data; / pointer to data within the page */
    69
    struct block_device *b_bdev;
    71 bh_end_io_t b_end_io; / I/O completion */
    72 void b_private; / reserved for b_end_io */
    73 struct list_head b_assoc_buffers; /* associated with another mapping */
    struct address_space b_assoc_map; / mapping this buffer is associated with */
    atomic_t b_count; /* users using this buffer_head */
    };

    b_count为缓冲区的使用计数,由get_bh和put_bh两个方法来增减
    /* 用在操作缓冲区之前 */
    252 static inline void get_bh(struct buffer_head *bh)
    253 {
    254 atomic_inc(&bh->b_count);
    255 }
    /* 用在操作缓冲区之后 */
    257 static inline void put_bh(struct buffer_head *bh)
    258 {
    259 smp_mb__before_atomic_dec();
    260 atomic_dec(&bh->b_count);
    261 }

    * bio结构体
    

    bio结构体代表了正在活动的以片段链表形式组织的块I/O操作,表示一个块I/O请求,每个请求包含一个或者多个块,一个片段是一小块连续的内存缓冲区,这样就不需要保证单个缓冲区一定要连续,可以分散在内存的多个位置上

    struct bio {
    sector_t bi_sector; /* device address in 512 byte sectors / / 磁盘上相关的扇区 */
    struct bio bi_next; / request queue link */
    struct block_device bi_bdev; / 指向块设备描述符 */
    67 unsigned long bi_flags; /* status, command, etc */
    68 unsigned long bi_rw; /* bottom bits READ/WRITE, top bits priority*/
    unsigned short bi_vcnt; /* how many bio_vec’s */
    unsigned short bi_idx; /* 分割bio结构体,current index into bvl_vec */
    78 unsigned int bi_phys_segments;
    80 unsigned int bi_size; /* residual I/O count */
    86 unsigned int bi_seg_front_size;
    87 unsigned int bi_seg_back_size;
    88
    89 unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
    90
    91 unsigned int bi_comp_cpu; /* completion CPU */
    92
    93 atomic_t bi_cnt; /* pin count */
    94
    struct bio_vec bi_io_vec; / 描述IO操作的一个片段(Page,offset,Len),the actual vec list 指向bio_vec结构体的第一个元素 */
    96
    97 bio_end_io_t *bi_end_io;
    98
    99 void *bi_private;

    104 bio_destructor_t bi_destructor; / destructor */
    struct bio_vec bi_inline_vecs[0];
    };

    bio_vec结构体
    struct bio_vec {
    47 struct page *bv_page;
    48 unsigned int bv

    • 1
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值