<1>填充块设备数据结构
static void mtd_blktrans_request(struct request_queue *rq)
{
struct mtd_blktrans_ops *tr = rq->queuedata;
wake_up_process(tr->blkcore_priv->thread);
}
tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
<2>请求的具体实现
static int mtd_blktrans_thread(void *arg)
{
struct mtd_blktrans_ops *tr = arg;
struct request_queue *rq = tr->blkcore_priv->rq;
/* we might get involved when memory gets low, so use PF_MEMALLOC */
current->flags |= PF_MEMALLOC;
spin_lock_irq(rq->queue_lock);
while (!kthread_should_stop()) { //当kthread_stop被调用时,循环推出
struct request *req;
struct mtd_blktrans_dev *dev;
int res = 0;
req = elv_next_request(rq);
if (!req) {
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irq(rq->queue_lock);
schedule(); //调度
spin_lock_irq(rq->queue_lock);
continue;
}
dev = req->rq_disk->private_data;
tr = dev->tr;
spin_unlock_irq(rq->queue_lock);
mutex_lock(&dev->lock);
res = do_blktrans_request(tr, dev, req);
mutex_unlock(&dev->lock);
spin_lock_irq(rq->queue_lock);
end_request(req, res);
}
spin_unlock_irq(rq->queue_lock);
return 0;
}
<3>注册内核线程
tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
"%sd", tr->name);
<4>停止kthread
/* Clean up the kernel thread */
kthread_stop(tr->blkcore_priv->thread);
---------------------------------------------------
FAT
static const struct address_space_operations fat_aops = {
.readpage = fat_readpage,
.readpages = fat_readpages,
.writepage = fat_writepage,
.writepages = fat_writepages,
.sync_page = block_sync_page,
.write_begin = fat_write_begin,
.write_end = fat_write_end,
.direct_IO = fat_direct_IO,
.bmap = _fat_bmap
};
fat_readpage->mpage_bio_submit->submit_bio->generic_make_request
->__generic_make_request->q->make_request_fn(q, bio)->__generic_unplug_device->q->request_fn(q)->mtd_blktrans_request
注:
blk_queue_make_request(q, __make_request);设置函数__make_request为make_request_fn