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

一,请求处理

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

[cpp] view plaincopy

  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

  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()函数

时间: 2024-08-24 05:41:44

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

linux驱动开发之块设备学习笔记

学习参考:http://www.cnblogs.com/yuanfang/archive/2010/12/24/1916231.html 1.块设备 块设备将数据按照固定块大小的块中,每个块的大小通常在512字节到32768字节之间,磁盘.SD卡都是常见的块设备. 2.字符设备和块设备的区别: 字符设备 块设备 ---------------------------------------------- 按字节访问 按块进行访问 只能按照数据流访问 随机访问 直接访问设备 挂在文件系统的方式访问

[linux驱动]linux块设备学习笔记(一)

1,区别块设备和字符设备:块设备是系统中能随机访问固定大小的数据片的硬件.,扇区是所有块设备物理上的最小可寻址单位,通常大小为512Byte,块是文件系统的最小寻址单位,大小是扇区的整数倍,同时不能超过一个页的大小~ 操作块设备的时候需要在内存中有一个对应的缓冲区,用struct buffer_head结构体表示. [cpp] view plaincopy struct buffer_head { unsigned long b_state;        /* buffer state bit

[linux驱动]linux块设备学习笔记(二)

1,gendisk结构体在linux内核中,使用gendisk结构体来表示一个实际的磁盘设备的抽象,结构体定义如下所示: [cpp] view plaincopy struct gendisk { int major; //主设备号 int first_minor;//次设备号 int minors;        //最大次设备数,如果不能分区则为1 char disk_name[DISK_NAME_LEN]; //设备名称,显示在/proc/partitions和sysfs中 struct 

Linux 驱动之块设备 (一)

1.引言 块设备的驱动比字符设备的难,这是因为块设备的驱动和内核的联系进一步增大,但是同时块设备的访问的几个基本结构和字符还是有相似之处的. 有一句话必须记住:对于存储设备(硬盘~~带有机械的操作)而言,调整读写的顺序作用巨大,因为读写连续的扇区比分离的扇区快. 但是同时:SD卡和U盘这类设备没有机械上的限制,所以像上面说的进行连续扇区的调整显得就没有必要了 2.块设备概念 块设备(blockdevice) --- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存

Linux学习笔记四:Linux的文件搜索命令

1.文件搜索命令  which 语法:which [命令名称] 范例:$which ls  列出ls命令所在目录 [[email protected] ~]$ which ls alias ls='ls --color=auto' /bin/ls 另外一个命令:whereis [名称名称],也可以列出命令所在目录. [[email protected] ~]$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/ma

Linux System Programming 学习笔记(四) 高级I/O

1. Scatter/Gather I/O a single system call  to  read or write data between single data stream and multiple buffers This type of I/O is so named because the data is scattered into or gathered from the given vector of buffers Scatter/Gather I/O 相比于 C标准

代码管理工具 --- git的学习笔记四《重新整理git(1)》

1.创建版本库 mkdir  创建目录 cd  地址,到该地址下 pwd 显示当前目录 1.创建目录 $ mkdir startGit $ cd startGit $ pwd 显示当前目录 或者cd到桌面,然后再创建目录 2.初始化版本库 $ git init 初始化仓库 提示信息:Initialized empty Git repository in /Users/xingzai/Desktop/startGit/.git/ 建立一个空的git仓库在/Users/xingzai/Desktop

CCNA学习笔记四——Telnet CDP

CDP协议:Cisco发现协议 show cdp show cpd neighbors:查看当前设备连接了哪些Cisco设备 cdp timer:修改发送间隔时间 cdp holdtime:修改保留时间 cdp advertise-2:修改版本号 debug cdp packets show cdp traffic:查看有关cdp包的统计信息 show cdp interface:查看端口cdp信息 show cdp entry:查看所有邻居的详细信息 cdp run:全局开启所有接口cdp协议

laravel3学习笔记(四)

原作者博客:ieqi.net ==================================================================================================== 视图 Laravel3遵循MVC模式,视图层负责将控制器处理好的数据展示出来,view层相关代码文件保存在application/views目录下,并且以php结尾. 因为PHP本身就可以和HTML混写的特性,一般而言,PHP框架的View层某种程度上也可以作为模板使