深入浅出块I/O子系统(二)块I/O子系统对象

目录

块I/O子系统对象

1 gendisk:通用磁盘

2 hd_struct:分区

3 block_device:块设备

4 request_queue:请求队列

5 request:块设备驱动层请求

6 bio:通用块层请求


块I/O子系统对象

1 gendisk:通用磁盘

2 hd_struct:分区

3 block_device:块设备

4 request_queue:请求队列

在块I/O子系统,request_queue的直观理解是请求队列,但实际上它的精确含义要稍微解释一下。首先它可能包括派发队列或和I/O调度队列,也就是来自上层的请求,在队列中经过I/O调度器的合并、排序,最终被提交到块设备驱动。

请求队列可能包含派发队列和I/O调度队列。

派发队列被组织成链表的形式,这是需要向块设备驱动提交的待处理请求链表,链表表头为queue_head域。

I/O调度队列则蕴涵在I/O调度器描述符(即elevator域)中,具体组织形式和调度方式取决于I/O调度算法的实现。

 struct request_queue {
    struct list_head    queue_head;
    struct elevator_queue   *elevator;
}

将请求提交到低层。

struct request_queue {
    request_fn_proc     *request_fn;
}

//申请请求队列
struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
{
     struct request_queue *q;
    //scsi_request_fn这个函数回调最后会赋值给q->request_fn
     q = __scsi_alloc_queue(sdev->host, scsi_request_fn);
}

static void scsi_request_fn(struct request_queue *q)
{
    //向低层提交命令
    scsi_dispatch_cmd(cmd);
}

• int (prep_rq_fn) (struct request_queue *, struct request *)

在处理请求前,构建要发送到驱动器设备的命令的方法。以SCSI为例,我们可以为队列注册一个prep_rq_fn回调,在请求被传给request_fn之前被调用。这个函数的目的是准备一个用于I/O的请求,例如它可以被用来从请求数据构建一个CDB。对于SCSI磁盘,其实现为sd模块的sd_prep_fn函数,负责将块层的读/写请求(即排入该队列的request)翻译为对应的SCSICDB,翻译好的SCSI命令字符串由request描述符的special指针(将块设备驱动层的request转化成scsi命令)

void (softirq_done_fn)(struct request *)

回调函数,在BLOCK_SOFTIRQ软中断下半部调用,以继续处理低层已完成的请求。对于SCSI子系统,其实现为scsi_softirq_done方法,它查看SCSI响应结果,以及感测数据以便确定如何处理这条SCSI命令,或完成,或重试,或进入错误处理。

static void scsi_softirq_done(struct request *rq) 
{
    disposition = scsi_decide_disposition(cmd);
    switch (disposition) {
        case SUCCESS:
            scsi_finish_command(cmd);
            break;
        case NEEDS_RETRY:
            scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY);
            break;
        case ADD_TO_MLQUEUE:
            scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
            break;
        default:
            if (!scsi_eh_scmd_add(cmd, 0))
                scsi_finish_command(cmd);
    }
}

5 request:块设备驱动层请求

6 bio:通用块层请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux技术芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值