[linux驱动]linux块设备学习笔记(四)——请求处理

一,请求处理

块设备的处理函数里没有read write等函数,所有对块设备的请求如读取 写入等都是通过request函数处理的。request函数的原型是void request(request_queue_t *queue);
request函数的处理是异步的。每一个设备都有一个请求队列,当请求队列生成的时候,request函数就与该请求队列绑定在一起了,request函数总是与一个自旋锁一起使用,当request函数拥有自旋锁的时候,该锁防止内核为设备安排其它请求。构request代表了挂起的I/O请求,每个请求用一个结构request实例描述,存放在请求队列链表中

<pre name="code" class="cpp">struct request {  
02.    //用于挂在请求队列链表的节点,使用函数blkdev_dequeue_request访问它,而不能直接访问  
04.    struct list_head queuelist;   
05.    struct list_head donelist;  /*用于挂在已完成请求链表的节点*/  
06.    struct request_queue *q;   /*指向请求队列*/  
07.    unsigned int cmd_flags;    /*命令标识*/  
08.    enum rq_cmd_type_bits cmd_type;  /*命令类型*/  
09.    /*各种各样的扇区计数,为提交i/o维护bio横断面的状态信息,hard_*成员是块层内部使用的,驱动程序不应该改变它们*/  
12.    sector_t sector;     /*将提交的下一个扇区*/  
13.    sector_t hard_sector;        /* 将完成的下一个扇区*/  
14.    unsigned long nr_sectors;  /* 整个请求还需要传送的扇区数*/  
15.    unsigned long hard_nr_sectors; /* 将完成的扇区数*/  
16. /*在当前bio中还需要传送的扇区数 */  
17.    unsigned int current_nr_sectors;  
18.    /*在当前段中将完成的扇区数*/  
19.    unsigned int hard_cur_sectors;  
20.    struct bio *bio;     /*请求中第一个未完成操作的bio*、 
21.    struct bio *biotail; /*请求链表中末尾的bio*、 
22.    struct hlist_node hash;  /*融合 hash */  
23.    /* rb_node仅用在I/O调度器中,当请求被移到分发队列中时,请求将被删除。因此,让completion_data与rb_node分享空间*/      
25.    union {  
26.        struct rb_node rb_node;   /* 排序/查找*/  
27.        void *completion_data;  
28.    };  


 
二,请求队列 

每个块设备都有一个请求队列,每个请求队列单独执行I/O调度,请求队列是由请求结构实例链接成的双向链表,链表以及整个队列的信息用结构request_queue描述,称为请求队列对象结构或请求队列结构。它存放了关于挂起请求的信息以及管理请求队列(如:电梯算法)所需要的信息。结构成员request_fn是来自设备驱动程序的请求处理函数。

三,Bio结构

通常1个bio对应1个I/O请求,IO调度算法可将连续的bio合并成1个请求。所以,1个请求可以包含多个bio。bio为通用层的主要数据结构,既描述了磁盘的位置,又描述了内存的位置,是上层内核vfs与下层驱动的连接纽带

struct bio {  
02.sector_t        bi_sector;//该bio结构所要传输的第一个(512字节)扇区:磁盘的位置  
03.struct bio        *bi_next;    //请求链表  
04.struct block_device    *bi_bdev;//相关的块设备  
05.unsigned long        bi_flags//状态和命令标志  
06.unsigned long        bi_rw; //读写  
07.unsigned short        bi_vcnt;//bio_vesc偏移的个数  
08.unsigned short        bi_idx;    //bi_io_vec的当前索引  
09.unsigned short        bi_phys_segments;//当DMA完成时候,它表示BIO中包含的物理段的数目
10.unsigned short        bi_hw_segments;//当DMA完成时候,它表示BIO中包含的硬件所能操作的段数 
11.unsigned int        bi_size;    //以字节为单位所需要传输数据的大小  
12.unsigned int        bi_hw_front_size;//第一个可合并的段大小;  
13.unsigned int        bi_hw_back_size;//最后一个可合并的段大小  
14.unsigned int        bi_max_vecs;    //bio_vecs数目上限  
15.struct bio_vec        *bi_io_vec;    //bio_vec链表:内存的位置  
16.bio_end_io_t        *bi_end_io;//I/O完成方法  
17.atomic_t        bi_cnt; //使用计数  
18.void            *bi_private; //拥有者的私有方法  
19.bio_destructor_t    *bi_destructor;    //销毁方法  
20.};  
内存数据段结构bio_vec
struct bio_vec {
        struct page     *bv_page;   /*数据段所在的页*/
        unsigned short  bv_len;     /*数据段的长度*/
        unsigned short  bv_offset;  /*数据段页内偏移*/
 };


四:

Linux中的队列请求处理函数为kernel/drivers/mmc/card/Block.c文件的mmc_blk_issue_rq()函数


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值