栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

【操作系统】LinuxKernel-块(磁盘硬盘)I/O 认知框架构建(bio,bio

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【操作系统】LinuxKernel-块(磁盘硬盘)I/O 认知框架构建(bio,bio

0x06 块I/O 概念

首先清楚一些概念在磁盘上,最小可寻址单元是扇区,文件系统的最小寻址单元是 块,且块不能比扇区小,得是它的2的n次方倍

而且访问device的块开销相当大

总而言之

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。

块IO的基本组织 struct bio (块I/O的基本容器)

bio 结构体包含了大量的基础信息,这些都是一个基本单元的属性,他们代表着当前这个 bio 的状态,比如是读还是写或者是一些特殊的操作命令等。以链表形式组织,因为其分散不连续性,又叫向量I/O

**是块I/O的基本容器,**这个结构体描述的都只是元数据部分,实际数据都包含在紧跟其后的 bio_vec

struct bio {
        struct bio          *bi_next;   
        struct block_device *bi_bdev;
        unsigned int        bi_flags;   
        int                 bi_error;
        unsigned long       bi_rw;      
        struct bvec_iter    bi_iter;

        
        unsigned int        bi_phys_segments;

        
        unsigned int        bi_seg_front_size;
        unsigned int        bi_seg_back_size;

        
        atomic_t            __bi_remaining;
        bio_end_io_t        *bi_end_io;
        void                *bi_private;
        unsigned short      bi_vcnt;    

        
        unsigned short      bi_max_vecs;    
        
        atomic_t            __bi_cnt;       
        struct bio_vec      *bi_io_vec;     
        struct bio_set      *bi_pool;

        
        struct bio_vec      bi_inline_vecs[0];
};
struct bio_vec (bio 数据的最小单位)
struct bio_vec {
        struct page     *bv_page;
        unsigned int    bv_len;
        unsigned int    bv_offset;
};

bio_vec 则是组成 bio 数据的最小单位,他包含了一块数据所在的页,这块数据所在的页内偏移以及长度,通过这些信息就可以很清晰的描述数据具体位于什么位置

通过对这些数据的整合,可以将他们添加到 SGL(散列表) 中直接发送给后端硬件设备

struct bvec_iter (bio的file定位)
struct bvec_iter {
        sector_t        bi_sector;      
        unsigned int    bi_size;        
        unsigned int    bi_idx;         
        unsigned int    bi_bvec_done;   
};

除了存储数据,作为一个I/O抽象,不光得定位数据在文件的哪页,还得定位文件在哪吧,把bio比做货车,bvec_iter就是货车上的分拣员,负责定位文件的位置

bio bio_vec page关系图

个人总结:

1.bio自身是链表组织的块I/O操作这个抽象

2.每一个bio维护了一个bio_vec结构的数组,保存bio_vec数据,bio.bi_vcnt是这个数组的内容个数,bio.bi_idx指向当前bio_vec数组的索引

3.每一个bio_vec相当于一个唯一的三元组确定数据具体位置

bio bio_vec page 逻辑架构图 块I/O 的 scheduler(驱动)

块设备挂起的IO请求保存在请求队列中,由reques_queue表示

struct reques_queue (双向链表请求队列)
struct request_queue {
    struct list_head    queue_head; //待处理请求的链表,请求队列中的请求用链表组织在一起
    struct request      *last_merge; //指向队列中首先可能合并的请求描述符
    struct elevator_queue   *elevator;//指向elevator对象的指针(电梯算法)
    struct request_list root_rl;///为分配请求描述符所使用的数据结构

    request_fn_proc     *request_fn;//实现驱动程序的策略例程入口点的方法,由他处理队列中请求
    make_request_fn     *make_request_fn;//将一个新请求插入请求队列时调用的方法
    prep_rq_fn      *prep_rq_fn; //该方法把这个处理请求的命令发送给硬件设备

    softirq_done_fn     *softirq_done_fn;
    rq_timed_out_fn     *rq_timed_out_fn;

    sector_t        end_sector;
    struct request      *boundary_rq;
    struct delayed_work delay_work;

    struct backing_dev_info backing_dev_info;

    
    void            *queuedata;
    spinlock_t      __queue_lock; //请求队列锁
    spinlock_t      *queue_lock; //指向请求队列锁的指针


    unsigned long       nr_requests;

    struct queue_limits limits;//队列的其他限制
};
struct request (请求队列中的具体请求)
struct request{
        struct list_head queuelist;
        unsigned long flags;

        sector_t sector;
        unsigned long nr_sectors;
        unsigned int current_nr_sector;

        sector_t hard_sector;
        unsigned long hard_nr_sectors;
        unsigned int hard_cur_sectors;

        struct bio* bio;
        struct bio* biotail;

        
        unsigned short nr_phys_segments;
        unsigned short nr_hw_segments;

        int tag;
        char* buffer;
        int ref_count;
        ...
    };

主要成员:

sector_t hard_sector;/要完成的下一个扇区/

unsigned long hard_nr_sectors;/要被完成的扇区数目/

unsigned int hard_cur_sectors;/当前要被完成的扇区数目/

分别对应的第一个尚未传输的扇区 尚待完成的扇区数 当前IO待完成的扇区数

在驱动中经常用的成员是:

sector_t sector;/要传输的下一个扇区/

unsigned long nr_sectors;/要传送的扇区数目/

unsigned int current_nr_sector;/当前要传送的扇区/

关于块设备IO更多内容诸如初始化 ddl调度 预测io调度 完全公正调度 空操作调度等 我没有了解需求,暂时打住。

有需要请回来看这个

Linux内核IO调度-http://www.ilinuxkernel.com/

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/851085.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号