本篇的(上)基本搞清楚了我们已经实现的内存块设备驱动和通用块层之间的丝丝联系。现在我们该做点自己想做的事情了: 踢开IO调度器,自己来处理bio。
踢开IO调度器很容易,即不使用__make_request 这个系统指定的强力函数,如何不使用?其实我们从(上)的blk_init_queue()函数中也能看出来,系统使用了blk_queue_make_request(q, __make_request)这个函数,那么我们也可以使用这个函数来指定我们自己的策略函数,从而替换掉__make_request函数。那初始化request_queue的blk_init_queue函数也不需要了。
直接看更改过后的源码:
simp_blkdev.c:
#include<linux/init.h>
#include<linux/module.h>
#include<linux/genhd.h>
#include<linux/fs.h>
#include<linux/blkdev.h>
#include<linux/bio.h>
#define SIMP_BLKDEV_DISKNAME "simp_blkdev"
#define SIMP_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR
#define SIMP_BLKDEV_BYTES (8*1024*1024)
static DEFINE_SPINLOCK(rq_lock);
unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];
static struct gendisk *simp_blkdev_disk;
static struct request_queue *simp_blkdev_queue;//device's request queue
struct block_device_operations simp_blkdev_fops = {
.owner = THIS_MODULE,
};
//handle bio
static int simp_blkdev_make_request(s

本文介绍了如何在Linux内核中编写块设备驱动,不使用默认的IO调度器,而是自定义`make_request_fn`函数处理`bio`。通过`blk_alloc_queue`初始化队列,`blk_queue_make_request`指定处理函数,实现对`bio`的遍历和内存操作。在`bio_for_each_segment`循环中,根据读写操作处理`bio_vec`,并利用`kmap`和`kunmap`进行内存映射。最终实现了一个无需IO调度器的内存块设备驱动。
最低0.47元/天 解锁文章
238

被折叠的 条评论
为什么被折叠?



