zoukankan      html  css  js  c++  java
  • [linux驱动]linux块设备学习笔记(四)——请求处理

    一,请求处理

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

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



    
    

    二,请求队列

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

    三,Bio结构

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

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



    四:

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

  • 相关阅读:
    ORA-01940: cannot drop a user that is currently connected解决方法
    Git基本用法简介
    C 入门 第十节 存储区
    C 入门 第九节 结构体指针
    C 入门 第八节 指针
    C 入门 第七节 结构体
    C 入门 第六节 自定义函数
    C 入门 第五节 多维数组 字符串数组
    C 入门 第四节
    C 入门 第三节
  • 原文地址:https://www.cnblogs.com/zhiliao112/p/4237241.html
Copyright © 2011-2022 走看看