Linux nbd 网络块设备(2)-内核实现

Linux nbd网络块设备(2)-内核实现

关注我,一起学习吧,后续持续更新内核相关

1. 概述:

  • 内核linux/drivers/block/nbd.c 是nbd 网络设备的底层驱动实现逻辑。
  • 本文主要介绍nbd 设备注册及I/O请求的处理逻辑。

2. nbd 设备的初始化:

在这里插入图片描述

  • disk 注册到内核后会产生/dev/nbdx 节点,后续nbd_client 可以通过该节点开始nbd 块设备传输;

  • 设置tag_set.ops操作函数:

    nbd->tag_set.ops = &nbd_mq_ops;
    static const struct blk_mq_ops nbd_mq_ops = {
    	.queue_rq	= nbd_queue_rq,
    	.complete	= nbd_complete_rq,
    	.init_request	= nbd_init_request,
    	.timeout	= nbd_xmit_timeout,
    };
    
  • 设置disk 的操作函数:

    • 该函数集主要用于nbd_client 打开nbd 设备,执行ioctl 指令,开始块传输等操作;
    disk->fops = &nbd_fops;
    static const struct block_device_operations nbd_fops =
    {
    	.owner =	THIS_MODULE,
    	.open =		nbd_open,
    	.release =	nbd_release,
    	.ioctl =	nbd_ioctl,
    	.compat_ioctl =	nbd_ioctl,
    	.free_disk =	nbd_free_disk,
    };
    
  • nbd 与tag_set 的关联:

    • tag_set 是nbd的成员

    • tag_set的driver_data 指向该nbd

      nbd->tag_set
      nbd->tag_set.driver_data=nbd
      
  • nbd 与disk的关联:

    • disk 基于tag_set 分配并初始化
    • disk 是nbd 的成员
    • disk的private_data 指向该nbd
    disk = blk_mq_alloc_disk(&nbd->tag_set, NULL);
    nbd->disk = disk;
    disk->private_data = nbd;
    

3. nbd 设备实例创建流程:

在这里插入图片描述

  • nbd_fops 是操作disk 时的相关处理函数,执行nbd_open时会实例化config
  • 所有的ioctl cmd 均通过nbd_ioctl 进行处理,主要设置config 相关属性
  • 执行完NBD_DO_IT 后,nbd 会更新硬件队列并将recv_work 提交工作队列
  • sock 存储关系:
    • 可以通config→socks[connection_number]→sock 访问到链接nbd_client 建立的sock,基于该sock 读取nbd_client 的数据或发送相关cmd

      //nbd.c nbd_add_socket()
      sock = nbd_get_socket(nbd, arg, &err);
      nsock->sock = sock;
      socks[config->num_connections++] = nsock;
      config->socks = socks;
      

3. nbd I/O 传输流程:

  • 通过sock 将块层请求发送给服务端
    • 以virtual-media 为例,将读取镜像的请求通过sock 发送给远程服务端
  • 通过sock 读取来着服务端的响应及响应数据,然后存储到bio_vec 指定内存。供更底层设备获取。

3.1 nbd 块层请求及数据发送:

  • 以virtual-meida 举例,USB层会将USB的请求转换为块请求,并通过nbd_queue_rq 将请求数据通过sock 发给服务端。
    在这里插入图片描述

3.2 nbd 接收处理:

  • recv_work 触发:
    • nbd 模组初始化执行nbd_dev_add 的时候,会创建recv_workq接收工作队列;
    • nbd 响应NBD_DO_IT ioctl cmd 执行nbd_start_device(nbd);时,将recv_work 提交到recv_workq,内核调度会执行recv_workq的工作线程,并执行recv_work.
    • 在recv_work 中主要通过socket读取服务端replay 并读取对应数据到bio_vec
      在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值