一、块设备的I/O请求过程
在gendisk结构体中的fops操作集合没有read和write的读写函数来从物理块设备中读写数据,而是通过request_queue、request 、bio和请求处理函数来实现的。
二、请求队列申请与释放API
1、申请并初始化请求队列
需要申请并初始化一个request_queue,并将这个request_queue地址赋值给gendisk的queue成员变量
a) 使用I/O调度器申请并初始化请求队列(如机械硬盘)
struct request_queue *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
- 参数
rfn:请求处理函数指针,每个 request_queue 都要有一个请求处理函数。请求处理函数原型如下
void (request_fn_proc) (struct request_queue *q)
lock:自旋锁指针,需要驱动编写人员定义并初始化一个自旋锁,然后传递进来,请求队列会使用这个自旋锁。
- 返回值
成功:申请到的request_queue地址;失败:NULL
b) 不使用I/O调度器申请并初始化请求队列(如EMMC、SD卡)
1.申请请求队列
struct request_queue *blk_alloc_queue(gfp_t gfp_mask)
参数
gfp_mask:内存分配掩码,具体可选择的掩码值请参考 include/linux/gfp.h 中的相关宏定义,一般为 GFP_KERNEL。
返回值
成功:申请到的request_queue地址
2.初始化请求队列(绑定一个“制造请求“函数)
void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
参数
q:需要绑定的请求队列,也就是 blk_alloc_queue 申请到的请求队列。
mfn:需要绑定的“制造”请求函数,函数原型如下,该函数由驱动编写人员实现
blk_qc_t (make_request_fn)