struct request_queue
--298-->请求队列的链表头
--300-->请求队列使用的IO调度算法, 通过内核启动参数来选择: kernel elevator=deadline
request_queue_t和gendisk一样需要使用内核API来分配并初始化,里面大量的成员不要直接操作, 此外, 请求队列如果要正常工作还需要绑定到一个处理函数中, 当请求队列不为空时, 处理函数会被回调, 这就是块设备驱动中处理请求的核心部分!
从驱动模型的角度来说, 块设备主要分为两类需要IO调度的和不需要IO调度的, 前者包括磁盘, 光盘等, 后者包括Flash, SD卡等, 为了保证模型的统一性 , Linux中对这两种使用同样的模型但是通过不同的API来完成上述的初始化和绑定
有IO调度类设备API //初始化+绑定 struct request_queue *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) 无IO调度类设备API //初始化 struct request_queue *blk_alloc_queue(gfp_t gfp_mask) //绑定 void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) 共用API针对请求队列的操作是块设备的一个核心任务, 其实质就是对请求队列操作函数的编写, 这个函数的主要功能就是从请求队列中获取请求并根据请求进行相应的操作 内核中已经提供了大量的API供该函数使用
//清除请求队列, 通常在卸载函数中使用 void blk_cleanup_queue(struct request_queue *q) //从队列中去除请求 blkdev_dequeue_request() //提取请求 struct request *blk_fetch_request(struct request_queue *q) //从队列中去除请求 struct request *blk_peek_request(struct request_queue *q) //启停请求队列, 当设备进入到不能处理请求队列的状态时,应通知通用块层 void blk_stop_queue(struct request_queue *q) void blk_start_queue(struct request_queue *q) request 97 struct request { 98 struct list_head queuelist; 104 struct request_queue *q; 117 struct bio *bio; 118 struct bio *biotail; 119 120 struct hlist_node hash; /* merge hash */ 126 union { 127 struct rb_node rb_node; /* sort/lookup */ 128 void *completion_data; 129 }; 137 union { 138 struct { 139 struct io_cq *icq; 140 void *priv[2]; 141 } elv; 142 143 struct { 144 unsigned int seq; 145 struct list_head list; 146 rq_end_io_fn *saved_end_io; 147 } flush; 148 }; 149 150 struct gendisk *rq_disk; 151 struct hd_struct *part; 199 };struct request
--98-->将这个request挂接到链表的节点
--104-->这个request从属的request_queue
--117-->组成这个request的bio链表的头指针
--118-->组成这个request的bio链表的尾指针
--120-->内核hash表头指针
bio用来描述单一的I/O请求,它记录了一次I/O操作所必需的相关信息,如用于I/O操作的数据缓存位置,,I/O操作的块设备起始扇区,是读操作还是写操作等等
46 struct bio { 47 struct bio *bi_next; /* request queue link */ 48 struct block_device *bi_bdev; 49 unsigned long bi_flags; /* status, command, etc */ 50 unsigned long bi_rw; /* bottom bits READ/WRITE, 51 * top bits priority 52 */ 54 struct bvec_iter bi_iter; 59 unsigned int bi_phys_segments; 65 unsigned int bi_seg_front_size; 66 unsigned int bi_seg_back_size; 68 atomic_t bi_remaining; 70 bio_end_io_t *bi_end_io; 72 void *bi_private; 85 unsigned short bi_vcnt; /* how many bio_vec's */ 91 unsigned short bi_max_vecs; /* max bvl_vecs we can hold */ 104 struct bio_vec bi_inline_vecs[0]; 105 };